"""
Unit and Integration tests for Feedback HTTP API and Isolated Storage.
Tests POST /api/feedback, GET /api/feedback, validation rules, and database isolation.
"""

import json
import socketserver
import threading
import unittest
import urllib.request
import urllib.error
import tempfile
import os

from tools.serve_webapp import FreeExileHTTPRequestHandler
from server.feedback.feedback_service import FeedbackService, SystemDiagnosticsDTO


class TestFeedbackAPIIntegration(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # Create dedicated temp db for testing to isolate from production
        cls.temp_dir = tempfile.TemporaryDirectory()
        cls.test_db_path = os.path.join(cls.temp_dir.name, "test_api_feedback.db")
        cls.orig_env_db = os.environ.get("FEEDBACK_DB_PATH")
        os.environ["FEEDBACK_DB_PATH"] = cls.test_db_path

        # Start HTTP server on ephemeral port (port 0)
        cls.httpd = socketserver.TCPServer(("127.0.0.1", 0), FreeExileHTTPRequestHandler)
        cls.port = cls.httpd.server_address[1]
        cls.server_thread = threading.Thread(target=cls.httpd.serve_forever, daemon=True)
        cls.server_thread.start()

    @classmethod
    def tearDownClass(cls):
        cls.httpd.shutdown()
        cls.httpd.server_close()
        if cls.orig_env_db is not None:
            os.environ["FEEDBACK_DB_PATH"] = cls.orig_env_db
        else:
            os.environ.pop("FEEDBACK_DB_PATH", None)
        cls.temp_dir.cleanup()

    def test_post_feedback_success(self):
        url = f"http://127.0.0.1:{self.port}/api/feedback"
        payload = {
            "player_id": 99999,
            "player_name": "DaoSiLangThang",
            "category": "GAMEPLAY_SUGGESTION",
            "title": "Đề xuất thêm tính năng khinh công vượt tường",
            "content": "Kính gửi Ban Quản Trị, hy vọng game có thêm thân pháp đạp tường để leo nóc nhà tại thành chính.",
            "diagnostics": {
                "client_platform": "iOS",
                "device_model": "iPhone 16 Pro",
                "current_fps": 120.0,
                "current_ping_ms": 15,
                "current_zone_name": "Cổ Trấn Huyết Lân"
            }
        }
        data = json.dumps(payload).encode("utf-8")
        req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"}, method="POST")

        with urllib.request.urlopen(req) as resp:
            self.assertEqual(resp.status, 200)
            res_body = json.loads(resp.read().decode("utf-8"))
            self.assertTrue(res_body["success"])
            self.assertTrue(res_body["feedback_id"].startswith("fb_"))
            self.assertIn("đã ghi nhận", res_body["message"])

    def test_post_feedback_validation_error(self):
        url = f"http://127.0.0.1:{self.port}/api/feedback"
        # Content too short (< 10 chars)
        payload = {
            "player_id": 99998,
            "player_name": "Tester",
            "category": "BUG_REPORT",
            "title": "Lỗi game",
            "content": "Lag"
        }
        data = json.dumps(payload).encode("utf-8")
        req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"}, method="POST")

        with self.assertRaises(urllib.error.HTTPError) as ctx:
            urllib.request.urlopen(req)
        self.assertEqual(ctx.exception.code, 400)

    def test_get_feedback_list(self):
        url = f"http://127.0.0.1:{self.port}/api/feedback"
        req = urllib.request.Request(url, method="GET")

        with urllib.request.urlopen(req) as resp:
            self.assertEqual(resp.status, 200)
            res_body = json.loads(resp.read().decode("utf-8"))
            self.assertIn("feedbacks", res_body)
            self.assertIsInstance(res_body["feedbacks"], list)


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