from __future__ import annotations

import argparse
import csv
from pathlib import Path

from flatten_invoices import build_plan, extract_date, flatten_invoices, label_from_row


def test_extract_date_prefers_source_month() -> None:
    row = {
        "path": "2026.03/_by_supplier/saas/me/Invoice.pdf",
        "preview": "Data wystawienia: 17 marca 2026 Termin płatności 2026-04-01",
    }
    assert extract_date(row) == "2026.03.17"


def test_extract_date_handles_english_month() -> None:
    row = {
        "path": "2026.03/_by_supplier/ai/me/Invoice-WLDFXE.pdf",
        "preview": "Invoice date Mar 24, 2026 Due date Apr 1, 2026",
    }
    assert extract_date(row) == "2026.03.24"


def test_extract_date_handles_underscore_before_iso_date() -> None:
    row = {
        "path": "2026.04/_by_supplier/ai/me/Historia_Operacji_2026-04-30_12-51-14.pdf",
        "preview": "",
    }
    assert extract_date(row) == "2026.04.30"


def test_label_uses_category_then_folder() -> None:
    assert label_from_row({"category": "windsurf", "path": "2026.03/_by_supplier/ai-tools/me/a.pdf"}) == "windsurf"
    assert label_from_row({"category": "unknown", "path": "2026.03/_by_supplier/ai-tools/me/a.pdf"}) == "ai-tools"


def test_build_plan_skips_no_invoice_and_adds_collision_suffix() -> None:
    rows = [
        {
            "path": "2026.03/_by_supplier/saas/me/a.pdf",
            "category": "saas",
            "reason": "",
            "ok": "True",
            "preview": "Faktura VAT Data wystawienia 2026-03-05",
        },
        {
            "path": "2026.03/_by_supplier/saas/other/a.pdf",
            "category": "saas",
            "reason": "",
            "ok": "True",
            "preview": "Faktura VAT Data wystawienia 2026-03-05",
        },
        {
            "path": "2026.03/_by_supplier/saas/me/regulamin.pdf",
            "category": "unknown",
            "reason": "",
            "ok": "True",
            "preview": "Regulamin usług",
        },
    ]

    plan, skipped = build_plan(rows)

    assert skipped == 1
    assert [row["target"] for row in plan] == [
        "2026.03/2026.03.05-saas-a.pdf",
        "2026.03/2026.03.05-saas-a-2.pdf",
    ]


class FakeClient:
    def __init__(self):
        self.calls = []

    def run(self, uri, payload):
        self.calls.append((uri, payload))
        return {"result": {"value": {
            "ok": True,
            "dryRun": payload["dry_run"],
            "moved": not payload["dry_run"],
            "target": payload["target_path"],
        }}}


def write_input(path: Path) -> None:
    with path.open("w", encoding="utf-8", newline="") as handle:
        writer = csv.DictWriter(handle, fieldnames=["path", "category", "reason", "ok", "preview"])
        writer.writeheader()
        writer.writerow({
            "path": "2026.03/_by_supplier/saas/me/a.pdf",
            "category": "saas",
            "reason": "",
            "ok": "True",
            "preview": "Faktura VAT Data wystawienia 2026-03-05",
        })


def test_flatten_invoices_dry_run_and_execute(tmp_path: Path) -> None:
    input_csv = tmp_path / "files.csv"
    write_input(input_csv)
    args = argparse.Namespace(
        node_url="http://node",
        input_csv=str(input_csv),
        output_dir=str(tmp_path),
        move_uri="fs://host/file/command/move",
        date_separator=".",
        max_files=0,
        timeout=10,
        overwrite=False,
        execute=False,
    )
    dry = flatten_invoices(args, client=FakeClient())
    assert dry["candidate_count"] == 1
    assert dry["moved_count"] == 0

    args.execute = True
    moved = flatten_invoices(args, client=FakeClient())
    assert moved["candidate_count"] == 1
    assert moved["moved_count"] == 1
