from __future__ import annotations

from fastapi.testclient import TestClient


class TestScenarioLifecycle:
    def test_scenario_lifecycle_flow(self, client: TestClient) -> None:
        # Create a project to attach scenarios to
        project_response = client.post(
            "/projects",
            json={
                "name": "Scenario Host Project",
                "location": "Ontario",
                "operation_type": "open_pit",
                "description": "Project for scenario lifecycle testing",
            },
        )
        assert project_response.status_code == 201
        project_id = project_response.json()["id"]

        # Create a scenario via the API for the project
        scenario_response = client.post(
            f"/projects/{project_id}/scenarios",
            json={
                "name": "Lifecycle Scenario",
                "description": "Initial scenario description",
                "status": "draft",
                "currency": "usd",
                "primary_resource": "diesel",
            },
        )
        assert scenario_response.status_code == 201
        scenario_id = scenario_response.json()["id"]

        # Project detail page should list the new scenario in draft state
        project_detail = client.get(f"/projects/{project_id}/view")
        assert project_detail.status_code == 200
        assert "Lifecycle Scenario" in project_detail.text
        assert "<td>Draft</td>" in project_detail.text

        # Update the scenario through the HTML form
        form_response = client.post(
            f"/scenarios/{scenario_id}/edit",
            data={
                "name": "Lifecycle Scenario Revised",
                "description": "Revised scenario assumptions",
                "status_value": "active",
                "start_date": "2025-01-01",
                "end_date": "2025-12-31",
                "discount_rate": "5.5",
                "currency": "cad",
                "primary_resource": "electricity",
            },
            follow_redirects=False,
        )
        assert form_response.status_code == 303
        assert form_response.headers["Location"].endswith(
            f"/scenarios/{scenario_id}/view")

        # Scenario detail page should reflect the updated information
        scenario_detail = client.get(f"/scenarios/{scenario_id}/view")
        assert scenario_detail.status_code == 200
        assert "Lifecycle Scenario Revised" in scenario_detail.text
        assert "Status: Active" in scenario_detail.text
        assert "CAD" in scenario_detail.text
        assert "Electricity" in scenario_detail.text
        assert "Revised scenario assumptions" in scenario_detail.text

        # Project detail page should show the scenario as active with updated currency/resource
        project_detail = client.get(f"/projects/{project_id}/view")
        assert "<td>Active</td>" in project_detail.text
        assert "<td>CAD</td>" in project_detail.text
        assert "<td>Electricity</td>" in project_detail.text

        # Attempt to update the scenario with invalid currency to trigger validation error
        invalid_update = client.put(
            f"/scenarios/{scenario_id}",
            json={"currency": "ca"},
        )
        assert invalid_update.status_code == 422
        assert "Invalid currency code" in invalid_update.json()[
            "detail"][0]["msg"]

        # Scenario detail should still show the previous (valid) currency
        scenario_detail = client.get(f"/scenarios/{scenario_id}/view")
        assert "CAD" in scenario_detail.text

        # Archive the scenario through the API
        archive_response = client.put(
            f"/scenarios/{scenario_id}",
            json={"status": "archived"},
        )
        assert archive_response.status_code == 200
        assert archive_response.json()["status"] == "archived"

        # Scenario detail reflects archived status
        scenario_detail = client.get(f"/scenarios/{scenario_id}/view")
        assert "Status: Archived" in scenario_detail.text

        # Project detail metrics and table entries reflect the archived state
        project_detail = client.get(f"/projects/{project_id}/view")
        assert "<h2>Archived</h2>" in project_detail.text
        assert '<p class="metric-value">1</p>' in project_detail.text
        assert "<td>Archived</td>" in project_detail.text
