"""Unit tests for staff_profile_domain (no database)."""

from __future__ import annotations

import unittest
import uuid

from src.initiative_db.models import User, UserStaffProfile
from src.staff_profile_domain import (
    apply_reverify_from_verified,
    assert_complete_for_submission,
    assert_employee_id_shape,
    assert_unit_exclusive,
    material_staff_fields_changed,
    normalize_employee_id,
    staff_row_for_audit,
)


class StaffProfileDomainTests(unittest.TestCase):
    def test_normalize_employee_id(self) -> None:
        self.assertIsNone(normalize_employee_id(None))
        self.assertEqual(normalize_employee_id("  ab-12 "), "AB-12")

    def test_employee_id_shape(self) -> None:
        assert_employee_id_shape(None)
        assert_employee_id_shape("ABC-123")
        with self.assertRaises(ValueError):
            assert_employee_id_shape("ab")

    def test_unit_exclusive(self) -> None:
        uid = uuid.uuid4()
        user = User(
            id=uid,
            email="t@ump.edu.vn",
            password_hash="x",
            full_name="T",
            unit_id=uuid.uuid4(),
        )
        sp = UserStaffProfile(user_id=uid, unit_name_freetext="  Khoa X  ")
        with self.assertRaises(ValueError):
            assert_unit_exclusive(user, sp)

    def test_material_staff_fields_changed(self) -> None:
        a = staff_row_for_audit(
            UserStaffProfile(user_id=uuid.uuid4(), job_title="A"),
            None,
        )
        b = staff_row_for_audit(
            UserStaffProfile(user_id=uuid.uuid4(), job_title="B"),
            None,
        )
        self.assertTrue(material_staff_fields_changed(a, b))
        self.assertFalse(material_staff_fields_changed(a, a))

    def test_apply_reverify_sets_pending(self) -> None:
        from datetime import datetime, timezone

        sp = UserStaffProfile(
            user_id=uuid.uuid4(),
            profile_verification_status="verified",
            verified_at=datetime.now(timezone.utc),
            verified_by_user_id=uuid.uuid4(),
            rejection_reason=None,
        )
        now = datetime.now(timezone.utc)
        apply_reverify_from_verified(sp, now)
        self.assertEqual(sp.profile_verification_status, "pending")
        self.assertIsNone(sp.verified_at)
        self.assertEqual(sp.verification_submitted_at, now)

    def test_assert_complete_for_submission(self) -> None:
        uid = uuid.uuid4()
        user = User(
            id=uid,
            email="t@ump.edu.vn",
            password_hash="x",
            full_name="T",
            unit_id=uuid.uuid4(),
        )
        sp = UserStaffProfile(
            user_id=uid,
            employee_id="CB-001",
            academic_title_code="master",
            job_title="GV",
        )
        assert_complete_for_submission(user, sp)

        sp2 = UserStaffProfile(user_id=uid, employee_id=None)
        with self.assertRaises(ValueError):
            assert_complete_for_submission(user, sp2)


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