from dataclasses import dataclass
from datetime import datetime
from typing import Any


@dataclass(frozen=True, slots=True)
class Plan:
    id: str
    code: str
    name: str
    summary: str = ""
    status: str = "ACTIVE"
    premium_cents: int = 0
    coverage_amount_cents: int = 0
    min_age: int = 0
    max_age: int = 100


@dataclass(frozen=True, slots=True)
class Product:
    id: str
    product_code: str
    name: str
    category: str
    summary: str
    status: str


@dataclass(frozen=True, slots=True)
class ProductVersion:
    id: str
    product_id: str
    version_no: str
    status: str
    effective_from: datetime
    effective_to: datetime | None
    plans: tuple[Plan, ...]
    rule_version: str = "eligibility-v1"
    rate_version: str = "rate-v1"
    terms_summary: str = ""

    def is_available_at(self, when: datetime) -> bool:
        return (
            self.status == "PUBLISHED"
            and self.effective_from <= when
            and (self.effective_to is None or when <= self.effective_to)
        )


@dataclass(frozen=True, slots=True)
class ProductChangeLog:
    id: str
    product_id: str
    version_id: str | None
    action: str
    actor_id: str
    actor_name: str
    detail: dict[str, Any]
    created_at: datetime
