from __future__ import annotations

import tempfile
import unittest
from pathlib import Path

from PIL import Image, ImageDraw, ImageFont

from safety_judge.classifier import SafetyClassifier
from safety_judge.models import Detection, Profile
from safety_judge.scanner import ScreenScanner
from safety_judge.storage import ProfileStore, ReportStore


class ClassifierTests(unittest.TestCase):
    def setUp(self) -> None:
        self.classifier = SafetyClassifier()

    def test_scam(self) -> None:
        result = self.classifier.classify(
            "URGENT: verify your password and verification code within 10 minutes."
        )
        self.assertEqual(result.category, "SCAM")
        self.assertGreaterEqual(result.risk, 0.98)

    def test_dangerous_advice(self) -> None:
        result = self.classifier.classify(
            "It is completely safe to put a metal fork in a microwave."
        )
        self.assertEqual(result.category, "DANGEROUS_ADVICE")

    def test_warning_is_not_dangerous_advice(self) -> None:
        result = self.classifier.classify("Do not put metal in a microwave because it can cause a fire.")
        self.assertEqual(result.category, "SAFE")

    def test_disabled_category(self) -> None:
        result = self.classifier.classify(
            "Save 30% today when you subscribe.",
            enabled_categories=["SCAM"],
        )
        self.assertEqual(result.category, "SAFE")


class ProfileAndReportTests(unittest.TestCase):
    def test_profiles_keep_separate_reports(self) -> None:
        with tempfile.TemporaryDirectory() as temp:
            profile_store = ProfileStore(Path(temp))
            report_store = ReportStore(profile_store)
            first = profile_store.create_profile("Aiden", "aiden@example.com", "#2563EB")
            second = profile_store.create_profile("Guest", "", "#7C3AED")
            report_store.append(
                first.profile_id,
                [Detection("SCAM", 0.98, "Fake account alert", "Test")],
            )
            self.assertEqual(len(report_store.read(first.profile_id)), 1)
            self.assertEqual(len(report_store.read(second.profile_id)), 0)
            self.assertEqual(len(profile_store.list_profiles()), 2)


class OCRTests(unittest.TestCase):
    def test_ocr_returns_line_coordinates(self) -> None:
        image = Image.new("RGB", (1300, 280), "white")
        draw = ImageDraw.Draw(image)
        font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
        font = ImageFont.truetype(font_path, 30) if Path(font_path).exists() else ImageFont.load_default()
        draw.text((35, 35), "URGENT: verify your password within 10 minutes.", fill="black", font=font)
        draw.text((35, 115), "It is completely safe to put metal in a microwave.", fill="black", font=font)
        draw.text((35, 195), "The chess tournament starts at 3 PM.", fill="black", font=font)

        profile = Profile(
            profile_id="test",
            display_name="Test",
            repeat_cooldown_seconds=0,
            risk_threshold=0.7,
        )
        scanner = ScreenScanner(SafetyClassifier())
        result = scanner.scan_image(image, profile, app_hint="OCR Test")
        categories = {item.category for item in result.detections}
        self.assertIn("SCAM", categories)
        self.assertIn("DANGEROUS_ADVICE", categories)
        self.assertTrue(all(item.width > 0 and item.height > 0 for item in result.detections))
        self.assertTrue(all(item.app_hint == "OCR Test" for item in result.detections))


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