"""POS Pro aggregates — Phase 12.5.

Full-featured POS additions: payments, discounts, tax lines, floor plans,
and stations. No accounting posting — payment records are local only.
"""
from __future__ import annotations

import uuid

from sqlalchemy import Index, Integer, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column

from app.core.database import Base
from app.models.base import (
    ActorAuditMixin,
    SoftDeleteMixin,
    TenantMixin,
    TimestampMixin,
    UUIDPrimaryKeyMixin,
)
from app.models.types import GUID, LifecycleStatus, PosDiscountKind, PosPaymentMethod


class PosPayment(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """A payment recorded against a POS ticket (local record only, no accounting posting)."""

    __tablename__ = "pos_payments"

    venue_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    ticket_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    method: Mapped[PosPaymentMethod] = mapped_column(
        default=PosPaymentMethod.CASH, nullable=False
    )
    amount: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
    currency_code: Mapped[str] = mapped_column(String(3), default="IRR", nullable=False)
    external_payment_ref: Mapped[str | None] = mapped_column(String(255), nullable=True)
    status: Mapped[LifecycleStatus] = mapped_column(
        default=LifecycleStatus.ACTIVE, nullable=False
    )

    __table_args__ = (
        Index("ix_pos_payments_venue", "tenant_id", "venue_id"),
        Index("ix_pos_payments_ticket", "tenant_id", "ticket_id"),
        Index("ix_pos_payments_tenant_deleted", "tenant_id", "is_deleted"),
    )


class PosDiscount(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """A discount applied to a POS ticket."""

    __tablename__ = "pos_discounts"

    venue_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    ticket_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    kind: Mapped[PosDiscountKind] = mapped_column(
        default=PosDiscountKind.PERCENT, nullable=False
    )
    value: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
    name: Mapped[str | None] = mapped_column(String(255), nullable=True)

    __table_args__ = (
        Index("ix_pos_discounts_venue", "tenant_id", "venue_id"),
        Index("ix_pos_discounts_ticket", "tenant_id", "ticket_id"),
        Index("ix_pos_discounts_tenant_deleted", "tenant_id", "is_deleted"),
    )


class PosTaxLine(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """A tax line applied to a POS ticket."""

    __tablename__ = "pos_tax_lines"

    venue_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    ticket_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    rate_bps: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
    amount: Mapped[int] = mapped_column(Integer, default=0, nullable=False)

    __table_args__ = (
        Index("ix_pos_tax_lines_venue", "tenant_id", "venue_id"),
        Index("ix_pos_tax_lines_ticket", "tenant_id", "ticket_id"),
        Index("ix_pos_tax_lines_tenant_deleted", "tenant_id", "is_deleted"),
    )


class PosFloorPlan(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """A floor plan grouping tables within a venue / dining area."""

    __tablename__ = "pos_floor_plans"

    venue_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    dining_area_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    status: Mapped[LifecycleStatus] = mapped_column(
        default=LifecycleStatus.ACTIVE, nullable=False
    )

    __table_args__ = (
        UniqueConstraint(
            "tenant_id", "venue_id", "code", name="uq_pos_floor_plans_tenant_venue_code"
        ),
        Index("ix_pos_floor_plans_venue", "tenant_id", "venue_id"),
        Index("ix_pos_floor_plans_tenant_deleted", "tenant_id", "is_deleted"),
    )


class PosStation(
    Base,
    UUIDPrimaryKeyMixin,
    TenantMixin,
    TimestampMixin,
    SoftDeleteMixin,
    ActorAuditMixin,
):
    """A service station (bar / counter / terminal) optionally tied to a floor plan."""

    __tablename__ = "pos_stations"

    venue_id: Mapped[uuid.UUID] = mapped_column(GUID(), nullable=False)
    floor_plan_id: Mapped[uuid.UUID | None] = mapped_column(GUID(), nullable=True)
    code: Mapped[str] = mapped_column(String(50), nullable=False)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    status: Mapped[LifecycleStatus] = mapped_column(
        default=LifecycleStatus.ACTIVE, nullable=False
    )

    __table_args__ = (
        UniqueConstraint(
            "tenant_id", "venue_id", "code", name="uq_pos_stations_tenant_venue_code"
        ),
        Index("ix_pos_stations_venue", "tenant_id", "venue_id"),
        Index("ix_pos_stations_floor_plan", "tenant_id", "floor_plan_id"),
        Index("ix_pos_stations_tenant_deleted", "tenant_id", "is_deleted"),
    )
