"""
MerchantWidgetKey ORM model.

Represents an API key issued to a merchant for embedding the Shopping Cart
Plugin on their storefront. Each key has an optional per-origin allowlist,
an encrypted webhook secret, and lifecycle timestamps.
"""
from __future__ import annotations

from datetime import datetime
from typing import Optional, List, TYPE_CHECKING

from sqlalchemy import Boolean, DateTime, ForeignKey, Integer, JSON, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func

from src.apps.base.models.base import Base

if TYPE_CHECKING:
    from src.apps.cart_plugin.models.cart_session import CartSession


class MerchantWidgetKey(Base):
    """API widget key issued to a merchant for the Shopping Cart Plugin."""

    __tablename__ = "merchant_widget_keys"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True, autoincrement=True)

    merchant_id: Mapped[int] = mapped_column(Integer, ForeignKey("merchants.id"), nullable=False, index=True)

    display_name: Mapped[str] = mapped_column(String(100), nullable=False)

    # Public key — safe to embed in client-side JavaScript.
    public_key: Mapped[str] = mapped_column(String(64), unique=True, index=True, nullable=False)

    # Fernet-encrypted webhook signing secret.  None if no webhook is configured.
    webhook_secret_encrypted: Mapped[Optional[str]] = mapped_column(Text, nullable=True)

    # JSON array of allowed origins, e.g. ["https://shop.example.com"].
    # Empty/null list means all origins are blocked.
    allowed_origins: Mapped[Optional[list]] = mapped_column(JSON, nullable=True)

    webhook_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True)

    # "auto" | "hosted" | "embedded"
    checkout_mode: Mapped[str] = mapped_column(String(20), nullable=False, default="auto")

    is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)

    created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), nullable=False)
    updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, onupdate=func.now())
    revoked_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)
    deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True)

    # ── Relationships ──────────────────────────────────────────────────────────

    sessions: Mapped[List["CartSession"]] = relationship(
        "CartSession", back_populates="widget_key", lazy="dynamic"
    )
