from __future__ import annotations

import uuid
from datetime import datetime
from decimal import Decimal
from typing import Any

from sqlalchemy import (
    Boolean,
    CheckConstraint,
    DateTime,
    ForeignKeyConstraint,
    Index,
    Integer,
    Numeric,
    String,
    UniqueConstraint,
    func,
    text,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.types import JSON

from app.db.base_class import Base


def _new_id() -> str:
    return str(uuid.uuid4())


class TenantCommercialPlan(Base):
    """租户已协商的商业套餐版本，不与平台内部成本或客户节省事实混用。"""

    __tablename__ = "tenant_commercial_plans"
    __table_args__ = (
        UniqueConstraint("tenant_id", "id", name="uq_tenant_commercial_plans_tenant_id"),
        UniqueConstraint(
            "tenant_id",
            "plan_code",
            "version",
            name="uq_tenant_commercial_plans_tenant_code_version",
        ),
        CheckConstraint(
            "pricing_model IN ('subscription', 'usage', 'hybrid', 'pilot', 'custom')",
            name="ck_tenant_commercial_plans_pricing_model",
        ),
        CheckConstraint(
            "billing_interval IN ('monthly', 'quarterly', 'annual', 'contract')",
            name="ck_tenant_commercial_plans_billing_interval",
        ),
        CheckConstraint(
            "status IN ('draft', 'active', 'retired')",
            name="ck_tenant_commercial_plans_status",
        ),
        CheckConstraint(
            "base_fee >= 0 AND included_seats >= 0 AND version >= 1",
            name="ck_tenant_commercial_plans_values",
        ),
        CheckConstraint(
            "length(trim(plan_code)) > 0 AND length(trim(name)) > 0",
            name="ck_tenant_commercial_plans_keys",
        ),
        CheckConstraint(
            "length(trim(currency)) = 3",
            name="ck_tenant_commercial_plans_currency",
        ),
        CheckConstraint(
            "effective_to IS NULL OR effective_to > effective_from",
            name="ck_tenant_commercial_plans_effective_window",
        ),
        Index(
            "uq_tenant_commercial_plans_active_code",
            "tenant_id",
            "plan_code",
            unique=True,
            postgresql_where=text("status = 'active'"),
        ),
        Index(
            "ix_tenant_commercial_plans_tenant_status",
            "tenant_id",
            "status",
            "effective_from",
        ),
    )

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_new_id)
    tenant_id: Mapped[str] = mapped_column(String(64), nullable=False)
    plan_code: Mapped[str] = mapped_column(String(80), nullable=False)
    name: Mapped[str] = mapped_column(String(160), nullable=False)
    pricing_model: Mapped[str] = mapped_column(String(24), nullable=False)
    billing_interval: Mapped[str] = mapped_column(String(20), nullable=False)
    currency: Mapped[str] = mapped_column(String(3), nullable=False)
    base_fee: Mapped[Decimal] = mapped_column(Numeric(20, 4), nullable=False)
    included_seats: Mapped[int] = mapped_column(
        Integer, nullable=False, default=0, server_default="0"
    )
    overage_enabled: Mapped[bool] = mapped_column(
        Boolean, nullable=False, default=False, server_default="false"
    )
    status: Mapped[str] = mapped_column(
        String(16), nullable=False, default="draft", server_default="draft"
    )
    effective_from: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    effective_to: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    version: Mapped[int] = mapped_column(Integer, nullable=False, default=1, server_default="1")
    contract_terms_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
    created_by: Mapped[str] = mapped_column(String(120), nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
    )

    subscriptions = relationship("TenantSubscription", back_populates="plan", passive_deletes=True)


class TenantSubscription(Base):
    """租户订阅及当期计费快照，避免套餐后续变化污染历史账期。"""

    __tablename__ = "tenant_subscriptions"
    __table_args__ = (
        UniqueConstraint("tenant_id", "id", name="uq_tenant_subscriptions_tenant_id"),
        UniqueConstraint(
            "tenant_id", "subscription_key", name="uq_tenant_subscriptions_tenant_key"
        ),
        UniqueConstraint(
            "tenant_id",
            "external_provider",
            "external_subscription_id",
            name="uq_tenant_subscriptions_external_ref",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "plan_id"],
            ["tenant_commercial_plans.tenant_id", "tenant_commercial_plans.id"],
            name="fk_tenant_subscriptions_tenant_plan",
            ondelete="RESTRICT",
        ),
        CheckConstraint(
            "status IN ('trialing', 'active', 'past_due', 'suspended', 'canceled', 'expired')",
            name="ck_tenant_subscriptions_status",
        ),
        CheckConstraint(
            "billing_interval IN ('monthly', 'quarterly', 'annual', 'contract')",
            name="ck_tenant_subscriptions_billing_interval",
        ),
        CheckConstraint(
            "seats > 0 AND base_fee_snapshot >= 0 AND version >= 1",
            name="ck_tenant_subscriptions_values",
        ),
        CheckConstraint(
            "length(trim(subscription_key)) > 0 AND length(trim(currency)) = 3",
            name="ck_tenant_subscriptions_keys",
        ),
        CheckConstraint(
            "current_period_end > current_period_start",
            name="ck_tenant_subscriptions_period",
        ),
        CheckConstraint(
            "ends_at IS NULL OR ends_at > starts_at",
            name="ck_tenant_subscriptions_contract_window",
        ),
        CheckConstraint(
            "(external_provider IS NULL AND external_subscription_id IS NULL) OR "
            "(external_provider IS NOT NULL AND external_subscription_id IS NOT NULL)",
            name="ck_tenant_subscriptions_external_pair",
        ),
        CheckConstraint(
            "status != 'canceled' OR canceled_at IS NOT NULL",
            name="ck_tenant_subscriptions_cancellation",
        ),
        Index(
            "uq_tenant_subscriptions_current",
            "tenant_id",
            unique=True,
            postgresql_where=text("status IN ('trialing', 'active', 'past_due', 'suspended')"),
        ),
        Index(
            "ix_tenant_subscriptions_tenant_status_period",
            "tenant_id",
            "status",
            "current_period_end",
        ),
    )

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_new_id)
    tenant_id: Mapped[str] = mapped_column(String(64), nullable=False)
    subscription_key: Mapped[str] = mapped_column(String(120), nullable=False)
    plan_id: Mapped[str] = mapped_column(String(36), nullable=False)
    status: Mapped[str] = mapped_column(String(20), nullable=False)
    starts_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    ends_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    current_period_start: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    current_period_end: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    seats: Mapped[int] = mapped_column(Integer, nullable=False)
    base_fee_snapshot: Mapped[Decimal] = mapped_column(Numeric(20, 4), nullable=False)
    currency: Mapped[str] = mapped_column(String(3), nullable=False)
    billing_interval: Mapped[str] = mapped_column(String(20), nullable=False)
    auto_renew: Mapped[bool] = mapped_column(
        Boolean, nullable=False, default=False, server_default="false"
    )
    external_provider: Mapped[str | None] = mapped_column(String(60))
    external_subscription_id: Mapped[str | None] = mapped_column(String(160))
    canceled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    version: Mapped[int] = mapped_column(Integer, nullable=False, default=1, server_default="1")
    metadata_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
    created_by: Mapped[str] = mapped_column(String(120), nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
    )

    plan = relationship("TenantCommercialPlan", back_populates="subscriptions")
    entitlements = relationship(
        "CommercialEntitlement", back_populates="subscription", passive_deletes=True
    )


class CommercialEntitlement(Base):
    """订阅的功能权益与可计量配额定义。"""

    __tablename__ = "commercial_entitlements"
    __table_args__ = (
        UniqueConstraint("tenant_id", "id", name="uq_commercial_entitlements_tenant_id"),
        UniqueConstraint(
            "tenant_id",
            "subscription_id",
            "id",
            name="uq_commercial_entitlements_tenant_subscription_id",
        ),
        UniqueConstraint(
            "tenant_id",
            "subscription_id",
            "entitlement_key",
            name="uq_commercial_entitlements_subscription_key",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id"],
            ["tenant_subscriptions.tenant_id", "tenant_subscriptions.id"],
            name="fk_commercial_entitlements_tenant_subscription",
            ondelete="RESTRICT",
        ),
        CheckConstraint(
            "entitlement_type IN ('feature', 'metered', 'unlimited')",
            name="ck_commercial_entitlements_type",
        ),
        CheckConstraint(
            "reset_interval IN ('none', 'monthly', 'quarterly', 'annual', 'contract')",
            name="ck_commercial_entitlements_reset_interval",
        ),
        CheckConstraint(
            "overage_policy IN ('block', 'allow', 'alert')",
            name="ck_commercial_entitlements_overage_policy",
        ),
        CheckConstraint(
            "status IN ('active', 'suspended', 'expired')",
            name="ck_commercial_entitlements_status",
        ),
        CheckConstraint(
            "version >= 1 AND (included_quantity IS NULL OR included_quantity >= 0) "
            "AND (hard_limit_quantity IS NULL OR hard_limit_quantity >= 0)",
            name="ck_commercial_entitlements_values",
        ),
        CheckConstraint(
            "(entitlement_type = 'unlimited' AND included_quantity IS NULL "
            "AND hard_limit_quantity IS NULL) OR "
            "(entitlement_type = 'feature' AND included_quantity IN (0, 1) "
            "AND (hard_limit_quantity IS NULL OR hard_limit_quantity IN (0, 1))) OR "
            "(entitlement_type = 'metered' AND included_quantity IS NOT NULL "
            "AND (hard_limit_quantity IS NULL OR hard_limit_quantity >= included_quantity))",
            name="ck_commercial_entitlements_quota_shape",
        ),
        CheckConstraint(
            "length(trim(entitlement_key)) > 0 AND length(trim(metric_key)) > 0 "
            "AND length(trim(unit)) > 0",
            name="ck_commercial_entitlements_keys",
        ),
        CheckConstraint(
            "effective_to IS NULL OR effective_to > effective_from",
            name="ck_commercial_entitlements_effective_window",
        ),
        Index(
            "ix_commercial_entitlements_subscription_status",
            "tenant_id",
            "subscription_id",
            "status",
        ),
    )

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_new_id)
    tenant_id: Mapped[str] = mapped_column(String(64), nullable=False)
    subscription_id: Mapped[str] = mapped_column(String(36), nullable=False)
    entitlement_key: Mapped[str] = mapped_column(String(120), nullable=False)
    metric_key: Mapped[str] = mapped_column(String(120), nullable=False)
    entitlement_type: Mapped[str] = mapped_column(String(20), nullable=False)
    unit: Mapped[str] = mapped_column(String(40), nullable=False)
    included_quantity: Mapped[Decimal | None] = mapped_column(Numeric(20, 6))
    hard_limit_quantity: Mapped[Decimal | None] = mapped_column(Numeric(20, 6))
    reset_interval: Mapped[str] = mapped_column(String(20), nullable=False)
    overage_policy: Mapped[str] = mapped_column(String(16), nullable=False)
    status: Mapped[str] = mapped_column(String(16), nullable=False)
    effective_from: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    effective_to: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
    version: Mapped[int] = mapped_column(Integer, nullable=False, default=1, server_default="1")
    config_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()
    )

    subscription = relationship("TenantSubscription", back_populates="entitlements")


class UsageMeterEvent(Base):
    """追加只读的客户用量事实；同一来源幂等键只能产生一条事件。"""

    __tablename__ = "usage_meter_events"
    __table_args__ = (
        UniqueConstraint("tenant_id", "id", name="uq_usage_meter_events_tenant_id"),
        UniqueConstraint(
            "tenant_id",
            "subscription_id",
            "id",
            name="uq_usage_meter_events_tenant_subscription_id",
        ),
        UniqueConstraint(
            "tenant_id",
            "subscription_id",
            "entitlement_id",
            "id",
            name="uq_usage_meter_events_entitlement_id",
        ),
        UniqueConstraint(
            "tenant_id",
            "source_system",
            "idempotency_key",
            name="uq_usage_meter_events_source_request",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id"],
            ["tenant_subscriptions.tenant_id", "tenant_subscriptions.id"],
            name="fk_usage_meter_events_tenant_subscription",
            ondelete="RESTRICT",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id", "entitlement_id"],
            [
                "commercial_entitlements.tenant_id",
                "commercial_entitlements.subscription_id",
                "commercial_entitlements.id",
            ],
            name="fk_usage_meter_events_tenant_entitlement",
            ondelete="RESTRICT",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id", "billing_period_id"],
            [
                "commercial_billing_periods.tenant_id",
                "commercial_billing_periods.subscription_id",
                "commercial_billing_periods.id",
            ],
            name="fk_usage_meter_events_tenant_billing_period",
            ondelete="RESTRICT",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id", "entitlement_id", "reversal_of_event_id"],
            [
                "usage_meter_events.tenant_id",
                "usage_meter_events.subscription_id",
                "usage_meter_events.entitlement_id",
                "usage_meter_events.id",
            ],
            name="fk_usage_meter_events_tenant_reversal",
            ondelete="RESTRICT",
        ),
        CheckConstraint(
            "event_type IN ('usage', 'credit', 'adjustment', 'reversal')",
            name="ck_usage_meter_events_type",
        ),
        CheckConstraint(
            "(event_type = 'usage' AND quantity > 0) OR "
            "(event_type = 'credit' AND quantity < 0) OR "
            "(event_type IN ('adjustment', 'reversal') AND quantity <> 0)",
            name="ck_usage_meter_events_quantity",
        ),
        CheckConstraint(
            "(event_type = 'reversal' AND reversal_of_event_id IS NOT NULL) OR "
            "(event_type != 'reversal' AND reversal_of_event_id IS NULL)",
            name="ck_usage_meter_events_reversal",
        ),
        CheckConstraint(
            "(subject_type IS NULL AND subject_id IS NULL) OR "
            "(subject_type IS NOT NULL AND subject_id IS NOT NULL)",
            name="ck_usage_meter_events_subject_pair",
        ),
        CheckConstraint(
            "actor_type IN ('system', 'user', 'integration', 'admin')",
            name="ck_usage_meter_events_actor_type",
        ),
        CheckConstraint(
            "length(trim(metric_key)) > 0 AND length(trim(unit)) > 0 "
            "AND length(trim(period_key)) > 0 AND length(trim(source_system)) > 0 "
            "AND length(trim(quota_period_key)) > 0 "
            "AND length(trim(idempotency_key)) > 0 "
            "AND length(trim(request_fingerprint)) > 0",
            name="ck_usage_meter_events_keys",
        ),
        Index(
            "ix_usage_meter_events_quota_window",
            "tenant_id",
            "subscription_id",
            "metric_key",
            "quota_period_key",
            "occurred_at",
        ),
        Index(
            "ix_usage_meter_events_billing_period",
            "tenant_id",
            "billing_period_id",
            "occurred_at",
        ),
        Index(
            "ix_usage_meter_events_correlation",
            "tenant_id",
            "correlation_id",
            "occurred_at",
        ),
    )

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_new_id)
    tenant_id: Mapped[str] = mapped_column(String(64), nullable=False)
    subscription_id: Mapped[str] = mapped_column(String(36), nullable=False)
    entitlement_id: Mapped[str] = mapped_column(String(36), nullable=False)
    billing_period_id: Mapped[str] = mapped_column(String(36), nullable=False)
    event_type: Mapped[str] = mapped_column(String(16), nullable=False)
    metric_key: Mapped[str] = mapped_column(String(120), nullable=False)
    quantity: Mapped[Decimal] = mapped_column(Numeric(20, 6), nullable=False)
    unit: Mapped[str] = mapped_column(String(40), nullable=False)
    period_key: Mapped[str] = mapped_column(String(64), nullable=False)
    quota_period_key: Mapped[str] = mapped_column(String(64), nullable=False)
    occurred_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    source_system: Mapped[str] = mapped_column(String(80), nullable=False)
    idempotency_key: Mapped[str] = mapped_column(String(160), nullable=False)
    request_fingerprint: Mapped[str] = mapped_column(String(80), nullable=False)
    reversal_of_event_id: Mapped[str | None] = mapped_column(String(36))
    subject_type: Mapped[str | None] = mapped_column(String(60))
    subject_id: Mapped[str | None] = mapped_column(String(160))
    actor_type: Mapped[str] = mapped_column(String(20), nullable=False)
    actor_id: Mapped[str] = mapped_column(String(120), nullable=False)
    correlation_id: Mapped[str | None] = mapped_column(String(120))
    trace_id: Mapped[str | None] = mapped_column(String(120))
    metadata_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
    recorded_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )


class CommercialCostEvent(Base):
    """平台内部成本事实；物理上独立于客户节省、价值机会和价值实现。"""

    __tablename__ = "commercial_cost_events"
    __table_args__ = (
        UniqueConstraint("tenant_id", "id", name="uq_commercial_cost_events_tenant_id"),
        UniqueConstraint(
            "tenant_id",
            "source_system",
            "idempotency_key",
            name="uq_commercial_cost_events_source_request",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id"],
            ["tenant_subscriptions.tenant_id", "tenant_subscriptions.id"],
            name="fk_commercial_cost_events_tenant_subscription",
            ondelete="RESTRICT",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id", "usage_event_id"],
            [
                "usage_meter_events.tenant_id",
                "usage_meter_events.subscription_id",
                "usage_meter_events.id",
            ],
            name="fk_commercial_cost_events_tenant_usage",
            ondelete="RESTRICT",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "subscription_id", "billing_period_id"],
            [
                "commercial_billing_periods.tenant_id",
                "commercial_billing_periods.subscription_id",
                "commercial_billing_periods.id",
            ],
            name="fk_commercial_cost_events_tenant_billing_period",
            ondelete="RESTRICT",
        ),
        ForeignKeyConstraint(
            ["tenant_id", "reversal_of_cost_event_id"],
            ["commercial_cost_events.tenant_id", "commercial_cost_events.id"],
            name="fk_commercial_cost_events_tenant_reversal",
            ondelete="RESTRICT",
        ),
        CheckConstraint(
            "event_type IN ('incurred', 'credit', 'adjustment', 'reversal')",
            name="ck_commercial_cost_events_type",
        ),
        CheckConstraint(
            "cost_category IN ('ai_inference', 'ocr', 'storage', 'connector', "
            "'support', 'implementation', 'infrastructure', 'payment', 'other')",
            name="ck_commercial_cost_events_category",
        ),
        CheckConstraint(
            "quantity > 0 AND unit_cost >= 0 AND fx_rate > 0",
            name="ck_commercial_cost_events_values",
        ),
        CheckConstraint(
            "(event_type = 'incurred' AND cost_amount >= 0 AND reporting_amount >= 0) OR "
            "(event_type = 'credit' AND cost_amount <= 0 AND reporting_amount <= 0) OR "
            "(event_type IN ('adjustment', 'reversal') AND cost_amount <> 0 "
            "AND reporting_amount <> 0)",
            name="ck_commercial_cost_events_amount_direction",
        ),
        CheckConstraint(
            "(event_type = 'reversal' AND reversal_of_cost_event_id IS NOT NULL) OR "
            "(event_type != 'reversal' AND reversal_of_cost_event_id IS NULL)",
            name="ck_commercial_cost_events_reversal",
        ),
        CheckConstraint(
            "usage_event_id IS NULL OR subscription_id IS NOT NULL",
            name="ck_commercial_cost_events_usage_pair",
        ),
        CheckConstraint(
            "(subscription_id IS NULL AND billing_period_id IS NULL) OR "
            "(subscription_id IS NOT NULL AND billing_period_id IS NOT NULL)",
            name="ck_commercial_cost_events_billing_period_pair",
        ),
        CheckConstraint(
            "length(trim(unit)) > 0 AND length(trim(source_system)) > 0 "
            "AND length(trim(idempotency_key)) > 0 "
            "AND length(trim(request_fingerprint)) > 0 "
            "AND length(trim(original_currency)) = 3 "
            "AND length(trim(reporting_currency)) = 3",
            name="ck_commercial_cost_events_keys",
        ),
        Index(
            "ix_commercial_cost_events_tenant_period",
            "tenant_id",
            "occurred_at",
            "cost_category",
        ),
        Index(
            "ix_commercial_cost_events_subscription_period",
            "tenant_id",
            "subscription_id",
            "billing_period_id",
            "occurred_at",
        ),
        Index(
            "ix_commercial_cost_events_allocation",
            "tenant_id",
            "allocation_key",
            "occurred_at",
        ),
    )

    id: Mapped[str] = mapped_column(String(36), primary_key=True, default=_new_id)
    tenant_id: Mapped[str] = mapped_column(String(64), nullable=False)
    subscription_id: Mapped[str | None] = mapped_column(String(36))
    billing_period_id: Mapped[str | None] = mapped_column(String(36))
    usage_event_id: Mapped[str | None] = mapped_column(String(36))
    event_type: Mapped[str] = mapped_column(String(16), nullable=False)
    cost_category: Mapped[str] = mapped_column(String(32), nullable=False)
    quantity: Mapped[Decimal] = mapped_column(Numeric(20, 6), nullable=False)
    unit: Mapped[str] = mapped_column(String(40), nullable=False)
    unit_cost: Mapped[Decimal] = mapped_column(Numeric(20, 8), nullable=False)
    cost_amount: Mapped[Decimal] = mapped_column(Numeric(20, 4), nullable=False)
    original_currency: Mapped[str] = mapped_column(String(3), nullable=False)
    reporting_amount: Mapped[Decimal] = mapped_column(Numeric(20, 4), nullable=False)
    reporting_currency: Mapped[str] = mapped_column(String(3), nullable=False)
    fx_rate: Mapped[Decimal] = mapped_column(Numeric(20, 8), nullable=False)
    provider: Mapped[str | None] = mapped_column(String(120))
    sku: Mapped[str | None] = mapped_column(String(120))
    model_name: Mapped[str | None] = mapped_column(String(120))
    allocation_key: Mapped[str] = mapped_column(String(160), nullable=False)
    occurred_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)
    source_system: Mapped[str] = mapped_column(String(80), nullable=False)
    idempotency_key: Mapped[str] = mapped_column(String(160), nullable=False)
    request_fingerprint: Mapped[str] = mapped_column(String(80), nullable=False)
    reversal_of_cost_event_id: Mapped[str | None] = mapped_column(String(36))
    correlation_id: Mapped[str | None] = mapped_column(String(120))
    trace_id: Mapped[str | None] = mapped_column(String(120))
    metadata_json: Mapped[dict[str, Any]] = mapped_column(JSON, nullable=False, default=dict)
    recorded_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), nullable=False, server_default=func.now()
    )


__all__ = [
    "CommercialCostEvent",
    "CommercialEntitlement",
    "TenantCommercialPlan",
    "TenantSubscription",
    "UsageMeterEvent",
]
