from datetime import datetime
from typing import Optional
from sqlalchemy import DateTime, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped, mapped_column, relationship
from src.database.base import BaseModel
from src.core.constants import AccountStatus, SubscriptionPlan


class Account(BaseModel):
    __tablename__ = "accounts"

    organization_name: Mapped[str] = mapped_column(String(255), nullable=False)
    subdomain: Mapped[str] = mapped_column(String(100), nullable=False, unique=True, index=True)
    cemetery_type: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    contact_email: Mapped[str] = mapped_column(String(255), nullable=False)
    contact_phone: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
    address: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    status: Mapped[str] = mapped_column(
        String(50), nullable=False, default=AccountStatus.PENDING.value, index=True
    )
    plan: Mapped[str] = mapped_column(
        String(50), nullable=False, default=SubscriptionPlan.STARTER.value
    )
    config_json: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True, default=dict)

    # Signup management fields (migration 0005)
    credentials_sent_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True
    )
    account_manager: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    size: Mapped[Optional[str]] = mapped_column(String(50), nullable=True)
    signup_source: Mapped[str] = mapped_column(
        String(20), nullable=False, default="marketing", index=True
    )
    activated_at: Mapped[Optional[datetime]] = mapped_column(
        DateTime(timezone=True), nullable=True
    )
    feature_flags: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True, default=dict)

    # Relationships
    users: Mapped[list] = relationship("User", back_populates="tenant", lazy="noload")
    branding: Mapped[Optional[object]] = relationship(
        "BrandingConfig", back_populates="account", uselist=False, lazy="noload"
    )
    subscriptions: Mapped[list] = relationship(
        "Subscription", back_populates="account", lazy="noload"
    )

    def __repr__(self) -> str:
        return f"<Account {self.subdomain}>"
