from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime


@dataclass(frozen=True, slots=True)
class UserRecord:
    id: int
    username: str
    username_key: str
    password_hash: str
    is_admin: bool
    status: str
    created_at: datetime
    updated_at: datetime


@dataclass(frozen=True, slots=True)
class MembershipRecord:
    user_id: int
    state: str
    expires_at: datetime | None
    is_permanent: bool
    daily_llm_limit: int
    updated_at: datetime
    updated_by: int | None


@dataclass(frozen=True, slots=True)
class SessionRecord:
    token_hash: str
    csrf_hash: str
    user: UserRecord
    membership: MembershipRecord
    expires_at: datetime


@dataclass(frozen=True, slots=True)
class Principal:
    token_hash: str
    csrf_hash: str
    user: UserRecord
    membership: MembershipRecord


@dataclass(frozen=True, slots=True)
class SessionIssue:
    token: str
    csrf_token: str
    principal: Principal


@dataclass(frozen=True, slots=True)
class MembershipView:
    status: str
    active: bool
    is_permanent: bool
    expires_at: datetime | None
    remaining_days: int | None
    daily_limit: int
    used_today: int
    remaining_today: int | None
    quota_exempt: bool


@dataclass(frozen=True, slots=True)
class BirthProfile:
    birth_date: str
    birth_time: str
    gender: str
    updated_at: datetime


@dataclass(frozen=True, slots=True)
class MembershipAccount:
    user: UserRecord
    membership: MembershipRecord


@dataclass(frozen=True, slots=True)
class MembershipAccountView:
    user: UserRecord
    membership: MembershipView


@dataclass(frozen=True, slots=True)
class ModelPoolRecord:
    id: int
    display_name: str
    display_name_key: str
    base_url: str
    model_identifier: str
    encrypted_api_key: str
    created_at: datetime
    updated_at: datetime
    updated_by: int


@dataclass(frozen=True, slots=True)
class ModelPoolItem:
    id: int
    display_name: str
    base_url: str
    model_identifier: str
    has_api_key: bool
    is_primary: bool
    is_fallback: bool
    updated_at: datetime


@dataclass(frozen=True, slots=True)
class ModelRuntimeConfig:
    primary: ModelPoolRecord
    fallback: ModelPoolRecord | None
