from __future__ import annotations

from dataclasses import dataclass
from datetime import date, datetime
from decimal import Decimal
from pathlib import Path


@dataclass(frozen=True)
class NormalizedTransaction:
    source_file: Path
    sheet_name: str
    source_row: int
    transaction_at: datetime
    income: Decimal
    expense: Decimal
    balance: Decimal | None
    own_account: str | None
    own_name: str | None
    counterparty_account: str | None
    counterparty_name: str | None
    counterparty_bank: str | None
    summary: str | None
    purpose: str | None
    reference: str | None
    currency: str | None


@dataclass(frozen=True)
class StatementBatch:
    source_file: Path
    sheet_name: str
    bank_name: str
    template_id: str
    header_row: int
    own_account: str | None
    own_name: str | None
    period_start: date | None
    period_end: date | None
    transactions: tuple[NormalizedTransaction, ...]
    warnings: tuple[str, ...]
    template_version: int = 1


@dataclass(frozen=True)
class SheetResult:
    """Per-worksheet parse outcome with the four diagnostic evidence items.

    ``outcome`` is the deterministic parse verdict: ``parsed`` (transactions
    normalized), ``exception`` (template/header/balance problems) or
    ``ignored`` (empty or single-cell sheets with no bank content). The human
    decision about whether a parsed sheet may participate in calculations is
    a separate lifecycle stage (``review_status``), persisted in
    ``sheet_reviews``; it is never decided here.
    """

    sheet_name: str
    outcome: str  # parsed | exception | ignored
    message: str | None = None
    scanned_rows: int | None = None
    candidate_headers: tuple[str, ...] = ()
    batch: StatementBatch | None = None
