import asyncio
import sys
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch

from fastapi import HTTPException

AI_ENGINE_ROOT = Path(__file__).resolve().parents[1]
if str(AI_ENGINE_ROOT) not in sys.path:
    sys.path.insert(0, str(AI_ENGINE_ROOT))

import main as ai_main


def _run(coro):
    return asyncio.run(coro)


class MainApiFunctionTests(unittest.TestCase):
    def test_analyze_match_v20plus_returns_payload(self):
        orchestrator = MagicMock()
        orchestrator.analyze_match.return_value = {"match_info": {"match_id": "m1"}}

        with patch("main.get_single_match_orchestrator", return_value=orchestrator):
            result = _run(ai_main.analyze_match_v20plus("m1"))

        self.assertEqual(result["match_info"]["match_id"], "m1")

    def test_analyze_match_v20plus_raises_404(self):
        orchestrator = MagicMock()
        orchestrator.analyze_match.return_value = None

        with patch("main.get_single_match_orchestrator", return_value=orchestrator):
            with self.assertRaises(HTTPException) as ctx:
                _run(ai_main.analyze_match_v20plus("missing"))

        self.assertEqual(ctx.exception.status_code, 404)

    def test_analyze_match_htms_v20plus_returns_payload(self):
        orchestrator = MagicMock()
        orchestrator.analyze_match_htms.return_value = {
            "status": "ok",
            "engine_used": "v20plus_top_htms",
        }

        with patch("main.get_single_match_orchestrator", return_value=orchestrator):
            result = _run(ai_main.analyze_match_htms_v20plus("m1"))

        self.assertEqual(result["status"], "ok")
        self.assertEqual(result["engine_used"], "v20plus_top_htms")

    def test_analyze_match_htft_timeout_validation(self):
        with self.assertRaises(HTTPException) as ctx:
            _run(ai_main.analyze_match_htft_v20plus("m1", timeout_sec=2))

        self.assertEqual(ctx.exception.status_code, 400)

    def test_generate_coupon_v20plus_forwards_payload(self):
        orchestrator = MagicMock()
        orchestrator.build_coupon.return_value = {"bets": []}

        request = ai_main.CouponRequest(
            match_ids=["m1", "m2"],
            strategy="SAFE",
            max_matches=3,
            min_confidence=70,
        )

        with patch("main.get_single_match_orchestrator", return_value=orchestrator):
            result = _run(ai_main.generate_coupon_v20plus(request))

        self.assertEqual(result, {"bets": []})
        orchestrator.build_coupon.assert_called_once_with(
            match_ids=["m1", "m2"],
            strategy="SAFE",
            max_matches=3,
            min_confidence=70.0,
        )

    def test_reversal_watchlist_validation(self):
        with self.assertRaises(HTTPException) as ctx:
            _run(ai_main.get_reversal_watchlist_v20plus(count=0))
        self.assertEqual(ctx.exception.status_code, 400)

    def test_reversal_watchlist_forwards_payload(self):
        orchestrator = MagicMock()
        orchestrator.get_reversal_watchlist.return_value = {"watchlist": []}

        with patch("main.get_single_match_orchestrator", return_value=orchestrator):
            result = _run(
                ai_main.get_reversal_watchlist_v20plus(
                    count=12,
                    horizon_hours=48,
                    min_score=50.5,
                    top_leagues_only=True,
                ),
            )

        self.assertEqual(result, {"watchlist": []})
        orchestrator.get_reversal_watchlist.assert_called_once_with(
            count=12,
            horizon_hours=48,
            min_score=50.5,
            top_leagues_only=True,
        )


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