"""
Unit tests for Isolated Feedback & Suggestions Service in FreeExile.
Verifies submission, data isolation, status updates, and metrics reporting.
"""

import os
import tempfile
import unittest

from server.feedback.feedback_service import FeedbackService, SystemDiagnosticsDTO


class TestFeedbackService(unittest.TestCase):
    def setUp(self):
        # Create temporary database file for isolation
        self.temp_dir = tempfile.TemporaryDirectory()
        self.db_path = os.path.join(self.temp_dir.name, "test_feedback.db")
        self.service = FeedbackService(db_path=self.db_path)

    def tearDown(self):
        self.temp_dir.cleanup()

    def test_submit_valid_feedback(self):
        diag = SystemDiagnosticsDTO(
            client_platform="iOS",
            device_model="iPhone 16 Pro",
            current_fps=119.8,
            current_zone_name="Co Tran Huyet Lan"
        )
        success, fb_id, msg = self.service.submit_feedback(
            player_id=10001,
            player_name="TieuDaoKiem",
            category="GAMEPLAY_SUGGESTION",
            title="Đề xuất thêm tính năng kết hôn đạo lữ",
            content="Mong ban quản trị phát triển thêm hệ thống song tu đạo lữ để cùng vượt bí cảnh.",
            diagnostics=diag
        )
        self.assertTrue(success)
        self.assertTrue(fb_id.startswith("fb_"))
        self.assertIn("đã ghi nhận", msg)

        # Retrieve and verify
        record = self.service.get_feedback_by_id(fb_id)
        self.assertIsNotNone(record)
        self.assertEqual(record.player_id, 10001)
        self.assertEqual(record.category, "GAMEPLAY_SUGGESTION")
        self.assertEqual(record.status, "NEW")
        self.assertEqual(record.diagnostics["device_model"], "iPhone 16 Pro")

    def test_validation_errors(self):
        # Empty title
        ok1, _, err1 = self.service.submit_feedback(
            player_id=10002, player_name="BachY", category="BUG_REPORT",
            title="", content="Nội dung báo lỗi hợp lệ dài hơn mười ký tự"
        )
        self.assertFalse(ok1)
        self.assertIn("không được để trống", err1)

        # Content too short (< 10 chars)
        ok2, _, err2 = self.service.submit_feedback(
            player_id=10002, player_name="BachY", category="BUG_REPORT",
            title="Lỗi kẹt góc tường", content="Lag quá"
        )
        self.assertFalse(ok2)
        self.assertIn("tối thiểu 10 ký tự", err2)

    def test_status_update_and_admin_workflow(self):
        _, fb_id, _ = self.service.submit_feedback(
            player_id=10003, player_name="HacPhong", category="BALANCE_ADJUSTMENT",
            title="Giảm bớt sát thương Liệt Diễm Cuồng Đao",
            content="Kỹ năng Hỏa hệ đang quá mạnh so với Kim hệ trong phụ bản."
        )

        # Update to UNDER_REVIEW
        res1 = self.service.update_feedback_status(fb_id, "UNDER_REVIEW", "Đã chuyển cho Lead Systems Designer.")
        self.assertTrue(res1)
        rec1 = self.service.get_feedback_by_id(fb_id)
        self.assertEqual(rec1.status, "UNDER_REVIEW")
        self.assertEqual(rec1.admin_response, "Đã chuyển cho Lead Systems Designer.")

        # Update to PLANNED
        res2 = self.service.update_feedback_status(fb_id, "PLANNED", "Đã đưa vào lộ trình cân bằng bản cập nhật Mùa 1.")
        self.assertTrue(res2)
        rec2 = self.service.get_feedback_by_id(fb_id)
        self.assertEqual(rec2.status, "PLANNED")

    def test_listing_and_metrics(self):
        # Submit 3 feedbacks
        self.service.submit_feedback(1, "P1", "BUG_REPORT", "Bug 1", "Noi dung bao loi chi tiet so 1")
        self.service.submit_feedback(2, "P2", "GAMEPLAY_SUGGESTION", "Suggest 1", "Noi dung de xuat gameplay so 2")
        self.service.submit_feedback(3, "P3", "BUG_REPORT", "Bug 2", "Noi dung bao loi chi tiet so 3")

        # Query bug reports
        bugs = self.service.list_feedbacks(category="BUG_REPORT")
        self.assertEqual(len(bugs), 2)

        # Check metrics
        metrics = self.service.get_feedback_metrics()
        self.assertEqual(metrics["total"], 3)
        self.assertEqual(metrics["by_category"]["BUG_REPORT"], 2)
        self.assertEqual(metrics["by_category"]["GAMEPLAY_SUGGESTION"], 1)
        self.assertEqual(metrics["by_status"]["NEW"], 3)


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