"""Typed payload models for Ross1000 daily movement XML generation.

All payloads are frozen dataclasses — immutable, hashable, and safe to
pass across service boundaries without defensive copying.
"""

from __future__ import annotations

from dataclasses import dataclass, field
from datetime import date


@dataclass(frozen=True)
class Ross1000StrutturaPayload:
    """Structure capacity block required on every movement day.

    Attributes:
        codice:              ISTAT structure code (e.g. "058091-CAV-00001")
        apertura:            1 = open, 0 = closed
        camere_occupate:     Number of occupied rooms on this day
        camere_disponibili:  Total available rooms
        letti_disponibili:   Total available beds
    """

    codice: str
    apertura: int
    camere_occupate: int
    camere_disponibili: int
    letti_disponibili: int


@dataclass(frozen=True)
class Ross1000GuestPayload:
    """Single guest record for a Ross1000 arrival or departure block.

    Mandatory fields (always present in XML output):
        idswh:           Permanent regulatory identity token (from GuestStay)
        cognome:         Surname (uppercase)
        nome:            Given name (uppercase)
        sesso:           Gender code — "M" (male) or "F" (female)
        datanascita:     Date of birth in AAAAMMGG format (e.g. "19830209")
        cittadinanza:    9-digit ISTAT country code for citizenship/nationality
        statoresidenza:  9-digit ISTAT country code for country of residence
        statonascita:    9-digit ISTAT country code for country of birth

    Optional fields (omitted from XML when empty/None):
        comune_residenza:   ISTAT municipality code for residence (Italian guests)
        provincia_residenza: Italian province code for residence (2 chars)
        comune_nascita:     ISTAT municipality code for place of birth
    """

    # ── Mandatory ─────────────────────────────────────────────────────────
    idswh: str
    cognome: str
    nome: str
    sesso: str                # "M" or "F"
    datanascita: str          # AAAAMMGG
    cittadinanza: str         # 9-digit ISTAT code
    statoresidenza: str       # 9-digit ISTAT code
    statonascita: str         # 9-digit ISTAT code

    # ── Optional ──────────────────────────────────────────────────────────
    comune_residenza: str | None = None
    provincia_residenza: str | None = None
    comune_nascita: str | None = None


@dataclass(frozen=True)
class Ross1000MovementDayPayload:
    """All movement data for a single calendar day.

    One of these is generated for every day in the export range,
    including days with no guest activity (empty arrivals/departures).

    Attributes:
        date:       The calendar day this block represents
        struttura:  Structure capacity block (always present)
        arrivi:     Guests arriving on this day (may be empty)
        partenze:   Guests departing on this day (may be empty)
    """

    date: date
    struttura: Ross1000StrutturaPayload
    arrivi: tuple[Ross1000GuestPayload, ...] = field(default_factory=tuple)
    partenze: tuple[Ross1000GuestPayload, ...] = field(default_factory=tuple)


@dataclass(frozen=True)
class Ross1000ExportResult:
    """Complete export result for a date range.

    Attributes:
        filename:    Suggested download filename
        content:     UTF-8 XML string (plain XML or SOAP envelope)
        content_type: MIME type
        day_count:   Number of movement day blocks generated
        mode:        "xml" or "soap"
    """

    filename: str
    content: str
    content_type: str
    day_count: int
    mode: str  # "xml" | "soap"
