import uuid
from datetime import datetime
from enum import StrEnum
from typing import Any

from sqlalchemy import Column, LargeBinary, UniqueConstraint
from sqlalchemy.dialects.postgresql import JSONB
from sqlmodel import Field

from app.db.base import TenantModel


class WhatsAppAccount(TenantModel, table=True):
    __tablename__ = "whatsapp_account"

    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    waba_id: str = Field(nullable=False)
    phone_number_id: str = Field(unique=True, index=True, nullable=False)
    phone_number: str = Field(nullable=False)
    display_name: str = Field(nullable=False)
    access_token_encrypted: bytes = Field(
        sa_column=Column(LargeBinary, nullable=False),
    )
    token_encryption_key_version: int = Field(default=1, nullable=False)
    quality_rating: str | None = Field(default=None, nullable=True)
    messaging_limit: str | None = Field(default=None, nullable=True)
    is_verified: bool = Field(default=False, nullable=False)
    is_active: bool = Field(default=True, nullable=False)
    connected_at: datetime | None = Field(default=None, nullable=True)


class TemplateStatus(StrEnum):
    PENDING = "PENDING"
    APPROVED = "APPROVED"
    REJECTED = "REJECTED"
    PAUSED = "PAUSED"
    DISABLED = "DISABLED"


class TemplateCategory(StrEnum):
    MARKETING = "MARKETING"
    UTILITY = "UTILITY"
    AUTHENTICATION = "AUTHENTICATION"


class WhatsAppTemplate(TenantModel, table=True):
    __tablename__ = "whatsapp_template"
    __table_args__ = (
        UniqueConstraint(
            "whatsapp_account_id",
            "name",
            "language",
            name="uq_wa_template_account_name_lang",
        ),
    )

    id: str = Field(default_factory=lambda: str(uuid.uuid4()), primary_key=True)
    whatsapp_account_id: str = Field(
        foreign_key="whatsapp_account.id",
        index=True,
        nullable=False,
    )
    meta_template_id: str | None = Field(default=None, nullable=True)
    name: str = Field(nullable=False)
    category: str = Field(nullable=False)
    language: str = Field(nullable=False)
    status: str = Field(default=TemplateStatus.PENDING.value, nullable=False)
    components: dict[str, Any] | None = Field(default=None, sa_column=Column(JSONB))
    rejection_reason: str | None = Field(default=None, nullable=True)
    quality_score: str | None = Field(default=None, nullable=True)
