"""Automated tests for fuel efficiency tracking, dossier generation, and IPC features."""

import unittest

from fastapi.testclient import TestClient

from app.modules.auth.presentation.auth import get_current_user
from app.core.postgres.project_crud_repository import ProjectCrudRepository
from app.main import create_app
from app.modules.dossier.application.dossier_generator_service import DossierGeneratorService
from app.modules.operations.application.equipment_efficiency_service import EquipmentEfficiencyService


class TestAdvancedOperationalFeatures(unittest.TestCase):
    def setUp(self):
        self.app = create_app()
        self.client = TestClient(self.app)
        self.repo = ProjectCrudRepository()
        self.efficiency_service = EquipmentEfficiencyService(self.repo)
        self.dossier_service = DossierGeneratorService(self.repo)

        # Mock current user authentication
        def mock_user():
            return {"id": "admin-id", "email": "admin@dscons.vn", "role": "superadmin"}

        self.app.dependency_overrides[get_current_user] = mock_user

    def tearDown(self):
        self.app.dependency_overrides = {}

    def test_record_fuel_log_and_metrics(self):
        """Kiểm thử ghi nhận nhiên liệu và tính toán hiệu suất ca máy."""
        # 1. Fetch active equipment to test
        sql = (
            "SELECT id, equipment_code, fuel_norm_per_hour FROM erp_equipment LIMIT 1;"
        )
        with self.repo.get_connection() as conn, conn.cursor() as cur:
            cur.execute(sql)
            equip = cur.fetchone()

        if not equip:
            self.skipTest("No equipment found in database to run fuel test")

        equip_id = str(equip["id"])

        # 2. Record fuel log
        res = self.efficiency_service.record_fuel_log(
            equipment_id=equip_id,
            fill_date="2026-08-21",
            fuel_quantity_liters=120.0,
            unit_price_vnd=21000.0,
            total_cost_vnd=2520000.0,
            odometer_hours=150.0,
            source_invoice_id=None,
        )
        self.assertEqual(res["status"], "success")

        # 3. Fetch efficiency metrics
        metrics = self.efficiency_service.get_equipment_efficiency(equip_id)
        self.assertIn("equipment_code", metrics)
        self.assertIn("fuel_norm_per_hour", metrics)
        self.assertIn("average_consumption_liters_per_hour", metrics)
        self.assertIn("efficiency_percentage", metrics)
        self.assertIn("warning_level", metrics)
        self.assertIn("fuel_logs", metrics)

    def test_dossier_template_generation(self):
        """Kiểm thử sinh biểu mẫu KCS điền sẵn thông tin hợp đồng."""
        # 1. Fetch active finding to test
        sql = "SELECT id FROM dossier_review_findings LIMIT 1;"
        with self.repo.get_connection() as conn, conn.cursor() as cur:
            cur.execute(sql)
            finding = cur.fetchone()

        if not finding:
            self.skipTest(
                "No dossier review findings found in database to run template generation test"
            )

        finding_id = str(finding["id"])

        # 2. Generate dossier template
        res = self.dossier_service.generate_dossier_template(finding_id)
        self.assertEqual(res["status"], "success")
        self.assertIn("filename", res)
        self.assertIn("download_url", res)
        self.assertIn("content_type", res)

    def test_api_routes_fuel_and_ipcs(self):
        """Kiểm thử REST API endpoints mới cho ca máy và IPC."""
        # 1. Fetch active project
        projects = self.repo.list_projects()
        if not projects:
            self.skipTest("No projects found in database to run API routes test")
        project_id = str(projects[0]["id"])

        # 2. Test project IPCs retrieval (GET)
        res = self.client.get(f"/v1/erp/advanced/projects/{project_id}/ipcs")
        self.assertEqual(res.status_code, 200)
        self.assertIsInstance(res.json(), list)

        # 3. Test creating project IPC (POST) with guaranteed cleanup
        ipc_id = None
        try:
            payload = {
                "ipc_number": 9999,
                "billing_period_start": "2026-08-01",
                "billing_period_end": "2026-08-20",
                "gross_claimed_amount_vnd": 1000000.0,
                "advance_recovery_amount_vnd": 100000.0,
                "retention_withheld_amount_vnd": 50000.0,
                "net_certified_amount_vnd": 850000.0,
                "status": "draft",
            }
            res_create = self.client.post(
                f"/v1/erp/advanced/projects/{project_id}/ipcs", json=payload
            )
            self.assertEqual(res_create.status_code, 201)
            self.assertEqual(res_create.json()["status"], "success")
            ipc_id = res_create.json().get("ipc_id")
        finally:
            with self.repo.get_connection() as conn, conn.cursor() as cur:
                if ipc_id:
                    cur.execute("DELETE FROM erp_project_ipcs WHERE id = %s", (ipc_id,))
                cur.execute("DELETE FROM erp_project_ipcs WHERE ipc_number = 9999")
                conn.commit()


if __name__ == "__main__":
    unittest.main()
