"""End-to-end CC workflow on the REAL-data clone (09-build-plan M7 gate):
create a batch -> paste real statement lines -> auto-rules pre-fill the
recurring charges -> confirm/assign the rest -> the paste block exports
byte-clean. Runs inside the SAVEPOINT session ``s`` (all commits roll
back — the real migrated data is untouched).

This exercises the SERVICE end to end against production-shaped entities
(the migrated projects/clients), not just unit fixtures."""

import uuid

from sqlalchemy import text

from app.services.cc import service as cc


def _first_project(session):
    """A real migrated (project_id, "{client} : {project}") to assign to."""
    row = session.execute(
        text(
            "SELECT pr.id, cl.name || ' : ' || pr.name AS label"
            " FROM projects pr JOIN parties cl ON cl.id = pr.client_party_id"
            " ORDER BY label LIMIT 1"
        )
    ).first()
    return uuid.UUID(str(row.id)), row.label


def test_e2e_paste_rules_assign_export(cc_engine, s, cc_owner):
    project_id, label = _first_project(s)

    # 1. A rule so a recurring charge auto-fills on paste (newest wins).
    cc.create_auto_rule(
        s, cc_owner,
        {"keyword": "FACEBK", "project_id": str(project_id),
         "assignment_description": "Facebook", "category": "Client Advertising Spend"},
    )

    # 2. New batch + a real-shaped statement paste (3 lines, one matches).
    batch_id = uuid.UUID(cc.create_batch(s, cc_owner, "M7 e2e PlusROI")["id"])
    paste = "\n".join(
        [
            "Jun 8, 2026\tFACEBK *AUTOHIT\t$14.97\t\t$4,472.24\t",
            "Jun 7, 2026\tANTHROPIC* CLAUDE\t$246.11\t\t$4,457.27\t",
            "\t\t\t\t\t",  # a blank/garbage row is dropped by the parser
            "Jun 6, 2026\tUNKNOWN VENDOR\t$10.00\t\t$4,211.16\t",
        ]
    )
    res = cc.append_lines(s, cc_owner, batch_id, paste)
    assert res["added"] == 3  # blank row dropped
    assert res["message"] == "Added 3 lines (1 auto-assigned)."

    detail = cc.batch_detail(s, cc_owner, batch_id)
    assert detail["totals"]["lines"] == 3
    by_desc = {ln["description"]: ln for ln in detail["lines"]}
    # the auto-hit row is orange (auto_assigned, project set)
    assert by_desc["FACEBK *AUTOHIT"]["auto_assigned"] is True
    assert by_desc["FACEBK *AUTOHIT"]["project_id"] == str(project_id)

    # 3. Confirm the auto-hit (orange -> green) and assign one more by hand.
    cc.update_line(
        s, cc_owner, uuid.UUID(by_desc["FACEBK *AUTOHIT"]["id"]),
        {"project_id": str(project_id), "assignment_description": "Facebook",
         "category": "Client Advertising Spend"},
    )
    cc.update_line(
        s, cc_owner, uuid.UUID(by_desc["ANTHROPIC* CLAUDE"]["id"]),
        {"project_id": str(project_id), "assignment_description": "Anthropic",
         "category": "General Licenses"},
    )
    saved = {ln["description"]: ln for ln in cc.batch_detail(s, cc_owner, batch_id)["lines"]}
    assert saved["FACEBK *AUTOHIT"]["auto_assigned"] is False  # saved == green

    # 4. Export: exactly the two assigned lines; the UNKNOWN one is skipped.
    block = cc.paste_block(s, cc_owner, batch_id)
    assert block["line_count"] == 2
    lines = block["text"].split("\n")
    assert len(lines) == 2
    # 7 tab columns; column 6 is the tenant literal; line_index order.
    first = lines[0].split("\t")
    assert len(first) == 7
    assert first[0] == label
    assert first[1] == "Facebook"
    assert first[2] == "14.97"
    assert first[3] == "2026-06-08"
    assert first[4] == ""
    assert first[5] == "Bowden Works"
    assert first[6] == "Client Advertising Spend"
    assert not block["text"].endswith("\n")
