"""مدل‌های Plan، Feature و PlanFeature.

Plan: بسته اشتراک.
Feature: یک قابلیت قابل کنترل (مثلاً accounting.invoice.create).
PlanFeature: نگاشت قابلیت‌ها به هر پلن به همراه سقف مصرف.
"""
from __future__ import annotations

import uuid
from datetime import datetime

from sqlalchemy import Boolean, DateTime
from sqlalchemy import Enum as SAEnum
from sqlalchemy import ForeignKey, Index, Integer, String, Text, UniqueConstraint, func
from sqlalchemy.orm import Mapped, mapped_column

from app.core.database import Base
from app.models.base import UUIDPrimaryKeyMixin
from app.models.enums import LimitPeriod
from app.models.types import GUID


class Plan(UUIDPrimaryKeyMixin, Base):
    __tablename__ = "plans"

    code: Mapped[str] = mapped_column(String(100), nullable=False, unique=True)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    description: Mapped[str | None] = mapped_column(Text, nullable=True)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    __table_args__ = (Index("ix_plans_code", "code", unique=True),)


class Feature(UUIDPrimaryKeyMixin, Base):
    __tablename__ = "features"

    # کلید یکتای قابلیت، مثال: accounting.invoice.create
    feature_key: Mapped[str] = mapped_column(String(150), nullable=False, unique=True)
    name: Mapped[str] = mapped_column(String(255), nullable=False)
    description: Mapped[str | None] = mapped_column(Text, nullable=True)
    # سرویسی که این قابلیت به آن تعلق دارد، مثال: accounting، crm.
    service_key: Mapped[str] = mapped_column(String(100), nullable=False)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)

    __table_args__ = (
        Index("ix_features_feature_key", "feature_key", unique=True),
        Index("ix_features_service_key", "service_key"),
    )


class PlanFeature(UUIDPrimaryKeyMixin, Base):
    __tablename__ = "plan_features"

    plan_id: Mapped[uuid.UUID] = mapped_column(
        GUID(), ForeignKey("plans.id", ondelete="CASCADE"), nullable=False
    )
    feature_id: Mapped[uuid.UUID] = mapped_column(
        GUID(), ForeignKey("features.id", ondelete="CASCADE"), nullable=False
    )
    # سقف مصرف؛ None یعنی نامحدود.
    limit_value: Mapped[int | None] = mapped_column(Integer, nullable=True)
    limit_period: Mapped[LimitPeriod | None] = mapped_column(
        SAEnum(LimitPeriod, name="limit_period"), nullable=True
    )
    is_enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)

    __table_args__ = (
        UniqueConstraint("plan_id", "feature_id", name="uq_plan_feature"),
        Index("ix_plan_features_plan_id", "plan_id"),
        Index("ix_plan_features_feature_id", "feature_id"),
    )
