from __future__ import annotations


import pytest
from fastapi.testclient import TestClient

from models import (
    MiningOperationType,
    Project,
)
from models.import_export_log import ImportExportLog


@pytest.fixture()
def project_seed(unit_of_work_factory):
    with unit_of_work_factory() as uow:
        assert uow.projects is not None
        project = Project(name="Seed Project", operation_type=MiningOperationType.OPEN_PIT)
        uow.projects.create(project)
        yield project


def test_project_import_preview_and_commit(client: TestClient, unit_of_work_factory) -> None:
    csv_content = (
        "name,location,operation_type\n"
        "Project Import A,Chile,open pit\n"
        "Project Import B,Canada,underground\n"
    )
    files = {"file": ("projects.csv", csv_content, "text/csv")}

    preview_response = client.post("/imports/projects/preview", files=files)
    assert preview_response.status_code == 200
    preview_payload = preview_response.json()
    assert preview_payload["summary"]["accepted"] == 2
    assert preview_payload["stage_token"]

    token = preview_payload["stage_token"]

    commit_response = client.post("/imports/projects/commit", json={"token": token})
    assert commit_response.status_code == 200
    commit_payload = commit_response.json()
    assert commit_payload["summary"]["created"] == 2

    with unit_of_work_factory() as uow:
        assert uow.projects is not None
        names = {project.name for project in uow.projects.list()}
        assert {"Project Import A", "Project Import B"}.issubset(names)
        # ensure audit logs recorded preview and commit events
        assert uow.session is not None
        logs = (
            uow.session.query(ImportExportLog)
            .filter(ImportExportLog.dataset == "projects")
            .order_by(ImportExportLog.created_at)
            .all()
        )
        actions = [log.action for log in logs]
        assert "preview" in actions
        assert "commit" in actions


def test_scenario_import_preview_and_commit(client: TestClient, unit_of_work_factory, project_seed) -> None:
    csv_content = (
        "project_name,name,status\n"
        "Seed Project,Scenario Import A,Draft\n"
        "Seed Project,Scenario Import B,Active\n"
    )
    files = {"file": ("scenarios.csv", csv_content, "text/csv")}

    preview_response = client.post("/imports/scenarios/preview", files=files)
    assert preview_response.status_code == 200
    preview_payload = preview_response.json()
    assert preview_payload["summary"]["accepted"] == 2
    token = preview_payload["stage_token"]

    commit_response = client.post("/imports/scenarios/commit", json={"token": token})
    assert commit_response.status_code == 200
    commit_payload = commit_response.json()
    assert commit_payload["summary"]["created"] == 2

    with unit_of_work_factory() as uow:
        assert uow.projects is not None and uow.scenarios is not None
        project = uow.projects.list()[0]
        scenarios = uow.scenarios.list_for_project(project.id)
        names = {scenario.name for scenario in scenarios}
        assert {"Scenario Import A", "Scenario Import B"}.issubset(names)
        assert uow.session is not None
        logs = (
            uow.session.query(ImportExportLog)
            .filter(ImportExportLog.dataset == "scenarios")
            .order_by(ImportExportLog.created_at)
            .all()
        )
        actions = [log.action for log in logs]
        assert "preview" in actions
        assert "commit" in actions


def test_project_export_endpoint(client: TestClient, unit_of_work_factory) -> None:
    with unit_of_work_factory() as uow:
        assert uow.projects is not None
        uow.projects.create(Project(name="Export Project", operation_type=MiningOperationType.OPEN_PIT))

    response = client.post("/exports/projects", json={"format": "csv"})
    assert response.status_code == 200
    assert response.headers["Content-Type"].startswith("text/csv")
    assert "attachment; filename=" in response.headers["Content-Disposition"]
    body = response.content.decode("utf-8")
    assert "Export Project" in body

    with unit_of_work_factory() as uow:
        assert uow.session is not None
        logs = (
            uow.session.query(ImportExportLog)
            .filter(ImportExportLog.dataset == "projects", ImportExportLog.action == "export")
            .order_by(ImportExportLog.created_at.desc())
            .first()
        )
        assert logs is not None
        assert logs.status == "success"
        assert logs.row_count >= 1