"""Ziyaretçi hafızası ORM: FlovyVisitor (moat) + FlovyVisitorSession.

Sadece tablo şeması. Tenant izolasyonu: uq (tenant_id, visitor_uuid).
"""
from datetime import datetime

from sqlalchemy import (
    DECIMAL,
    JSON,
    Boolean,
    DateTime,
    Enum,
    ForeignKey,
    Index,
    Integer,
    String,
    UniqueConstraint,
)
from sqlalchemy.orm import Mapped, mapped_column

from app.database import Base, TimestampMixin, UUIDMixin

DEVICE_TYPE = ("mobile", "desktop", "tablet")
TIME_OF_DAY = ("morning", "afternoon", "evening", "night")


class FlovyVisitor(UUIDMixin, TimestampMixin, Base):
    __tablename__ = "flovy_visitors"
    __table_args__ = (
        UniqueConstraint("tenant_id", "visitor_uuid", name="uq_tenant_visitor"),
        Index("idx_visitor_fingerprint", "tenant_id", "fingerprint_hash"),
        Index("idx_visitor_email", "tenant_id", "email"),
        Index("idx_visitor_phone", "tenant_id", "phone"),
    )

    tenant_id: Mapped[str] = mapped_column(
        String(36), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False
    )
    visitor_uuid: Mapped[str] = mapped_column(String(64), nullable=False)
    fingerprint_hash: Mapped[str | None] = mapped_column(String(64), nullable=True)

    email: Mapped[str | None] = mapped_column(String(200), nullable=True)
    phone: Mapped[str | None] = mapped_column(String(30), nullable=True)
    name: Mapped[str | None] = mapped_column(String(200), nullable=True)

    ip_address: Mapped[str | None] = mapped_column(String(45), nullable=True)
    ip_history: Mapped[list | None] = mapped_column(JSON, nullable=True)
    device_type: Mapped[str | None] = mapped_column(
        Enum(*DEVICE_TYPE, name="visitor_device_type"), nullable=True
    )
    browser: Mapped[str | None] = mapped_column(String(50), nullable=True)
    language: Mapped[str | None] = mapped_column(String(10), nullable=True)

    total_sessions: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
    total_messages: Mapped[int] = mapped_column(Integer, default=0, server_default="0")
    last_session_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    last_intent: Mapped[str | None] = mapped_column(String(50), nullable=True)
    lifetime_value: Mapped[float] = mapped_column(DECIMAL(12, 2), default=0, server_default="0")

    products_viewed: Mapped[list | None] = mapped_column(JSON, nullable=True)
    products_purchased: Mapped[list | None] = mapped_column(JSON, nullable=True)
    cart_abandoned: Mapped[dict | None] = mapped_column(JSON, nullable=True)
    interests: Mapped[list | None] = mapped_column(JSON, nullable=True)
    preferred_time_of_day: Mapped[str | None] = mapped_column(
        Enum(*TIME_OF_DAY, name="visitor_time_of_day"), nullable=True
    )

    is_returning: Mapped[bool] = mapped_column(Boolean, default=False, server_default="0")
    kvkk_consent_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    anonymized_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)


class FlovyVisitorSession(UUIDMixin, Base):
    __tablename__ = "flovy_visitor_sessions"

    visitor_id: Mapped[str] = mapped_column(
        String(36), ForeignKey("flovy_visitors.id", ondelete="CASCADE"), nullable=False, index=True
    )
    tenant_id: Mapped[str] = mapped_column(String(36), nullable=False, index=True)
    chat_session_id: Mapped[str | None] = mapped_column(String(36), nullable=True)
    ip_address: Mapped[str | None] = mapped_column(String(45), nullable=True)
    page_url: Mapped[str | None] = mapped_column(String(1000), nullable=True)
    referrer: Mapped[str | None] = mapped_column(String(500), nullable=True)
    utm_source: Mapped[str | None] = mapped_column(String(100), nullable=True)
    utm_medium: Mapped[str | None] = mapped_column(String(100), nullable=True)
    utm_campaign: Mapped[str | None] = mapped_column(String(100), nullable=True)
    started_at: Mapped[datetime] = mapped_column(DateTime, nullable=True)
    ended_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
