from __future__ import annotations

import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from fastapi.testclient import TestClient

import api
from src import env_settings


class ApiTests(unittest.TestCase):
    def setUp(self) -> None:
        self.client = TestClient(api.app)

    def test_health(self) -> None:
        res = self.client.get("/health")
        self.assertEqual(res.status_code, 200)
        self.assertEqual(res.json(), {"ok": True})

    def test_home_page(self) -> None:
        res = self.client.get("/")
        self.assertEqual(res.status_code, 200)
        self.assertIn("Langfuse Lens", res.text)

    def test_chat_endpoint(self) -> None:
        with patch("api.run", return_value="## Metrics summary\n- error_rate: 1.00%\n- avg_latency_ms: 1234"):
            res = self.client.post("/api/chat", json={"message": "mode=overview"})
        self.assertEqual(res.status_code, 200)
        body = res.json()
        self.assertIn("output", body)
        self.assertIn("metrics", body)
        self.assertEqual(body["metrics"].get("error_rate"), "1.00%")

    def test_extract_metrics(self) -> None:
        output = """## Metrics summary\n- error_rate: 0.00%\n- avg_latency_ms: 55\n\n## Heuristic opinions\n- ok"""
        metrics = api._extract_metrics(output)
        self.assertEqual(metrics["error_rate"], "0.00%")
        self.assertEqual(metrics["avg_latency_ms"], "55")

    def test_get_llm_settings(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            project_env = Path(tmp) / "project.env"
            home_env = Path(tmp) / "home.env"
            project_env.write_text("OPENAI_API_KEY=sk-test\n", encoding="utf-8")
            with patch.object(env_settings, "PROJECT_ENV_PATH", project_env), patch.object(
                env_settings, "HOME_ENV_PATH", home_env
            ):
                env_settings._ENV_BOOTSTRAPPED = False
                with patch.dict(os.environ, {}, clear=True):
                    res = self.client.get("/api/settings/llm-keys")
                    self.assertEqual(res.status_code, 200)
                    body = res.json()
                    self.assertTrue(body["status"]["openai"])
                    self.assertTrue(body["present"]["OPENAI_API_KEY"])

    def test_save_llm_settings(self) -> None:
        with tempfile.TemporaryDirectory() as tmp:
            project_env = Path(tmp) / "project.env"
            home_env = Path(tmp) / "home.env"
            with patch.object(env_settings, "PROJECT_ENV_PATH", project_env), patch.object(
                env_settings, "HOME_ENV_PATH", home_env
            ):
                env_settings._ENV_BOOTSTRAPPED = False
                with patch.dict(os.environ, {}, clear=True):
                    res = self.client.post(
                        "/api/settings/llm-keys",
                        json={"target": "project", "openai_api_key": "sk-123"},
                    )
                    self.assertEqual(res.status_code, 200)
                    self.assertIn("OPENAI_API_KEY=sk-123", project_env.read_text(encoding="utf-8"))


if __name__ == "__main__":
    unittest.main()
