"""API-level smoke for /api/import — the T-IMP-001/012/024 mechanics
over real HTTP (multipart upload -> resolution payload -> commit ->
batch list), plus the structured-error shape (04-architecture)."""

import pytest
from fastapi.testclient import TestClient

from app.main import create_app
from app.services.auth import session as auth_session
from tests.imports.conftest import csv_of, csv_row


@pytest.fixture()
def client_factory(graph, monkeypatch):
    from app import db as app_db

    monkeypatch.setattr(app_db, "get_engine", lambda: graph.engine)
    clients: list[TestClient] = []

    def make(username: str, email: str = "", is_super_admin: bool = False) -> TestClient:
        test_client = TestClient(create_app(), base_url="https://testserver")
        test_client.__enter__()
        clients.append(test_client)
        token = auth_session.mint_session(
            username=username, email=email, is_super_admin=is_super_admin
        )
        test_client.cookies.set(auth_session.SESSION_COOKIE, token)
        return test_client

    yield make
    for test_client in clients:
        test_client.__exit__(None, None, None)


@pytest.fixture()
def as_adi(client_factory):
    return client_factory("adi", "info@adipramono.com")


def upload(client, csv_text: str, name: str | None = None):
    data = {}
    if name is not None:
        data["name"] = name
    return client.post(
        "/api/import",
        files={"file": ("weekly.csv", csv_text.encode(), "text/csv")},
        data=data,
    )


def test_upload_resolve_commit_roundtrip(as_adi, graph):
    response = upload(as_adi, csv_of(csv_row(), csv_row(Description="Other")))
    assert response.status_code == 200
    payload = response.json()
    pending_id = payload["pending_id"]
    assert payload["pending"]["batch_name"] == "Jun 2, 2026"
    assert payload["summary"]["all_known"] is True
    assert payload["can_commit"] is True

    # GET the resolution again (the resolver page's own load)
    again = as_adi.get(f"/api/import/pending/{pending_id}")
    assert again.status_code == 200
    assert again.json()["pending"]["entry_count"] == 2

    committed = as_adi.post(
        f"/api/import/pending/{pending_id}/commit",
        json={"operators": [], "clients": [], "projects": [], "buckets": []},
    )
    assert committed.status_code == 200
    body = committed.json()
    assert body["row_count"] == 2 and body["matched"] == 2

    batches = as_adi.get("/api/import/batches").json()
    assert any(row["id"] == body["batch_id"] for row in batches["rows"])
    assert batches["can_manage"] is True

    summary = as_adi.get(f"/api/import/batches/{body['batch_id']}/summary").json()
    assert summary["total"] == 2 and summary["unmatched"] == 0

    # the consumed pending id is now a structured 404
    gone = as_adi.get(f"/api/import/pending/{pending_id}")
    assert gone.status_code == 404
    assert gone.json()["error_code"] == "PENDING_NOT_FOUND"


def test_upload_without_file_is_structured_error(as_adi):
    response = as_adi.post("/api/import", data={"name": "x"})
    assert response.status_code == 400
    body = response.json()
    assert body["error_code"] == "NO_FILE"
    assert body["summary"] == "Please choose a CSV file to upload."


def test_worker_upload_refused(client_factory):
    gary = client_factory("gary", "gary@rian.ca")
    response = upload(gary, csv_of(csv_row()))
    assert response.status_code == 403
    assert response.json()["error_code"] == "NOT_ALLOWED"


def test_cancel_deletes_pending(as_adi):
    pending_id = upload(as_adi, csv_of(csv_row())).json()["pending_id"]
    assert as_adi.delete(f"/api/import/pending/{pending_id}").json() == {"ok": True}
    assert as_adi.get(f"/api/import/pending/{pending_id}").status_code == 404
