"""
Однократная/повторная генерация criteria_interface_layout.json из Excel
«Запрос для ИИ Общий(2).xlsx» (листы с «интерфейс» в названии).

Запуск (путь к xlsx можно передать аргументом):
  py extract_criteria_interface_layout.py "C:\\Users\\...\\Запрос для ИИ Общий(2).xlsx"
"""
from __future__ import annotations

import json
import os
import sys

import openpyxl

SHEET_TO_SHIPPING_TYPES: dict[str, list[str]] = {
    "Авто LTL интерфейс": ["Автомобильная перевозка (LTL)"],
    "Авто FTL интерфейс": ["Автомобильная перевозка (FTL)"],
    "Море, море+жд, жд LCL интерфейc": [
        "Морская перевозка (LCL)",
        "Железнодорожная перевозка (LCL)",
        "Мультимодальная перевозка море + ж/д (LCL)",
    ],
    "Море, море+жд, жд FCL интерфейc": [
        "Морская перевозка (FCL)",
        "Железнодорожная перевозка (FCL)",
        "Мультимодальная перевозка море + ж/д (FCL)",
    ],
    "Авиа Интерфейс": ["Авиаперевозка"],
}


def _row_cells(ws, r: int, max_c: int = 12) -> list[tuple[int, str]]:
    out: list[tuple[int, str]] = []
    for c in range(1, max_c + 1):
        v = ws.cell(r, c).value
        if v is not None and str(v).strip():
            out.append((c, str(v).strip()))
    return out


def _is_num_like(s: str) -> bool:
    if not isinstance(s, str):
        return False
    t = s.strip()
    if not t:
        return False
    # 1, 1., 1.0
    return t.isdigit() or t.replace(".", "", 1).isdigit()


def parse_interface_sheet(ws) -> list[dict]:
    """Разбор листа интерфейса в последовательность визуальных блоков."""
    blocks: list[dict] = []
    r = 1
    max_r = ws.max_row or 1
    while r <= max_r:
        cells = _row_cells(ws, r)
        if not cells:
            r += 1
            continue

        # Заголовок верхнего ряда:
        # в новых версиях файла набор колонок может отличаться, поэтому
        # распознаём динамически: строка с номерами + следующая строка с подписями
        # в тех же колонках.
        cols = [c[0] for c in cells]
        vals = [c[1] for c in cells]
        if len(cells) >= 4 and all(_is_num_like(v) for v in vals):
            r2 = r + 1
            cells2 = _row_cells(ws, r2)
            map2 = {c: v for c, v in cells2}
            if all(c in map2 and str(map2[c]).strip() for c in cols):
                labels = [str(map2[c]).strip() for c in cols]
                # Если в следующей строке снова только числа — это не шапка.
                if not all(_is_num_like(v) for v in labels):
                    nums = [str(v).strip() for v in vals]
                    blocks.append({"type": "header", "nums": nums, "labels": labels})
                    r += 2
                    continue

        # Только правая пара (6 = номер, 7 = текст) — например «20 Место таможни»
        if len(cells) == 2 and cells[0][0] == 6 and cells[1][0] == 7:
            blocks.append({"type": "right_67", "num": cells[0][1], "label": cells[1][1]})
            r += 1
            continue

        # Две пары: 1-2 и 6-7
        if len(cells) == 4 and {cells[i][0] for i in range(4)} == {1, 2, 6, 7}:
            blocks.append(
                {
                    "type": "pair",
                    "left": {"num": cells[0][1], "label": cells[1][1]},
                    "right": {"num": cells[2][1], "label": cells[3][1]},
                }
            )
            r += 1
            continue

        # Только левая пара 1-2 (один блок на строку)
        if len(cells) == 2 and cells[0][0] == 1 and cells[1][0] == 2:
            blocks.append({"type": "left_12", "num": cells[0][1], "label": cells[1][1]})
            r += 1
            continue

        r += 1
    return blocks


def main() -> None:
    xlsx = (
        sys.argv[1]
        if len(sys.argv) > 1
        else os.path.join(os.path.dirname(__file__), "Запрос для ИИ Общий(3).xlsx")
    )
    if not os.path.isfile(xlsx):
        print("Файл не найден:", xlsx)
        sys.exit(1)

    wb = openpyxl.load_workbook(xlsx, read_only=False, data_only=True)
    out: dict = {"version": 1, "source_xlsx": os.path.basename(xlsx), "by_shipping_type": {}}

    for sheet_name, type_names in SHEET_TO_SHIPPING_TYPES.items():
        if sheet_name not in wb.sheetnames:
            print("Пропуск: лист не найден:", sheet_name)
            continue
        blocks = parse_interface_sheet(wb[sheet_name])
        for tn in type_names:
            out["by_shipping_type"][tn] = {"sheet": sheet_name, "blocks": blocks}

    out_path = os.path.join(os.path.dirname(__file__), "criteria_interface_layout.json")
    with open(out_path, "w", encoding="utf-8") as f:
        json.dump(out, f, ensure_ascii=False, indent=2)
    print("Записано:", out_path, "типов:", len(out["by_shipping_type"]))


if __name__ == "__main__":
    main()
