from dataclasses import dataclass
from datetime import date, datetime
from typing import Any


@dataclass(frozen=True)
class Quote:
    id: str
    user_id: str
    product_id: str
    product_version_id: str
    plan_id: str
    insured_age: int
    insured_region_code: str
    occupation_code: str
    relationship: str
    premium_cents: int
    currency: str
    rule_version: str
    rate_version: str
    status: str
    expires_at: datetime
    created_at: datetime


@dataclass(frozen=True)
class EnrollmentDraft:
    id: str
    user_id: str
    quote_id: str
    applicant: dict[str, Any]
    insured: dict[str, Any]
    contact: dict[str, Any]
    status: str
    expires_at: datetime
    created_at: datetime


@dataclass(frozen=True)
class UserConfirmation:
    id: str
    user_id: str
    draft_id: str
    token_hash: str
    status: str
    expires_at: datetime
    created_at: datetime


@dataclass(frozen=True)
class EnrollmentOrder:
    id: str
    order_no: str
    user_id: str
    quote_id: str
    draft_id: str
    confirmation_id: str
    idempotency_key: str
    product_id: str
    product_version_id: str
    plan_id: str
    applicant_snapshot: dict[str, Any]
    insured_snapshot: dict[str, Any]
    amount_cents: int
    currency: str
    status: str
    created_at: datetime


@dataclass(frozen=True)
class PaymentTransaction:
    id: str
    payment_no: str
    order_id: str
    user_id: str
    transaction_type: str
    provider: str
    idempotency_key: str
    amount_cents: int
    currency: str
    status: str
    provider_transaction_no: str | None
    succeeded_at: datetime | None
    created_at: datetime


@dataclass(frozen=True)
class Policy:
    id: str
    policy_no: str
    order_id: str
    user_id: str
    product_id: str
    product_version_id: str
    plan_id: str
    premium_cents: int
    currency: str
    coverage_start: date
    coverage_end: date
    status: str
    issued_at: datetime


@dataclass(frozen=True)
class OutboxEvent:
    id: str
    aggregate_type: str
    aggregate_id: str
    event_type: str
    payload: dict[str, Any]
    status: str
    created_at: datetime


@dataclass(frozen=True)
class AsyncTask:
    id: str
    task_type: str
    business_key: str
    idempotency_key: str
    payload: dict[str, Any]
    status: str
    attempt_count: int
    created_at: datetime
