from sqlalchemy import Integer, String, DateTime, Boolean, Column, ForeignKey
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship, Mapped, mapped_column
from sqlalchemy.sql.schema import Table
from typing import Optional, List, TYPE_CHECKING
from datetime import datetime
from src.apps.base.models.base import Base
from src.core.utils.enums import ContactTypes

if TYPE_CHECKING:
    from typing import Any

merchant_contact_address_map = Table(
    "merchant_contact_addresses",
    Base.metadata,
    Column("contact_id", ForeignKey("merchant_contacts.id")),
    Column("address_id", ForeignKey("address.id")),
)


class MerchantContacts(Base):
    """
    Merchant Contacts Model: ORM class for Merchant Contacts Entity
    """

    __tablename__ = "merchant_contacts"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True, autoincrement=True)
    contact_id: Mapped[Optional[str]] = mapped_column(String(50), index=True, unique=True, nullable=True)
    name: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    email: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    phone: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    contact_type: Mapped[Optional[str]] = mapped_column(String(50), nullable=True, default=ContactTypes.USER)
    is_active: Mapped[Optional[bool]] = mapped_column(Boolean, nullable=True)

    created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
    updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, onupdate=func.now())
    deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    title: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    dob: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    timezone: Mapped[Optional[str]] = mapped_column(String(32), nullable=True)
    website: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)

    merchant_id: Mapped[int] = mapped_column(Integer, ForeignKey("merchants.id"))
    addresses: Mapped[List["Address"]] = relationship("Address", secondary=merchant_contact_address_map)
