from __future__ import annotations

from app.excel_import.reader import ExcelSource, LotDraft
from app.excel_import.report import ImportReport
from app.models import Lot, db


def _designation_for_lot(draft: LotDraft) -> str:
    if draft.split_total > 1:
        return f"Lot {draft.lot_copro} (éclaté {draft.split_index}/{draft.split_total})"
    if draft.etage_porte:
        return f"Appart {draft.etage_porte}"
    return ""


def run(
    source: ExcelSource,
    copro_id: int,
    *,
    dry_run: bool,
) -> tuple[dict[str, Lot], ImportReport]:
    report = ImportReport("lots", dry_run=dry_run)
    surfaces = source.read_surfaces()
    caves = source.read_caves()
    lot_map: dict[str, Lot] = {}
    copro_numbers: dict[str, str] = {}

    drafts = source.expand_all_lots()
    for draft in drafts:
        if draft.lot_syndic in surfaces:
            draft.surface = surfaces[draft.lot_syndic]
        elif f"copro:{draft.lot_copro}" in surfaces:
            draft.surface = surfaces[f"copro:{draft.lot_copro}"]
        if draft.lot_syndic in caves and not draft.cave:
            draft.cave = caves[draft.lot_syndic]

        if draft.lot_copro in copro_numbers and copro_numbers[draft.lot_copro] != draft.import_key:
            report.add_warning(
                f"N° copro « {draft.lot_copro} » en doublon "
                f"({copro_numbers[draft.lot_copro]} vs {draft.import_key}, "
                f"ligne {draft.source_row})"
            )
        copro_numbers[draft.lot_copro] = draft.import_key

        label = (
            f"lot copro {draft.lot_copro} "
            f"(syndic {draft.lot_syndic or '—'}, étage {draft.etage_porte or '—'})"
        )

        if dry_run:
            report.add_created(label)
            continue

        lot = Lot(
            copropriete_id=copro_id,
            lot_syndic=draft.lot_syndic,
            lot_copro=draft.lot_copro,
            designation=_designation_for_lot(draft),
            etage=draft.etage,
            porte=draft.porte,
            bal=draft.bal,
            cave=draft.cave,
            surface=draft.surface,
            notes=draft.notes,
        )
        db.session.add(lot)
        db.session.flush()
        lot_map[draft.import_key] = lot
        report.add_created(label)

    if not dry_run:
        db.session.commit()
    return lot_map, report
