"""Smoke tests for HR models — leave lifecycle and travel lifecycle."""
from __future__ import annotations

import pytest
from django.contrib.auth import get_user_model
from django.utils import timezone

from apps.core.permissions.roles import UserRole
from apps.rims.hr.models import (
    BackToOfficeReport,
    Department,
    LeaveRequest,
    LeaveType,
    StaffProfile,
    TravelRequest,
    TravelReport,
)

User = get_user_model()


@pytest.fixture
def admin_user(db):
    u = User.objects.create_user(email="hr.admin@example.com", password="pw")
    u.role = UserRole.ADMIN
    u.save()
    return u


@pytest.fixture
def department(db):
    return Department.objects.create(name="Research")


@pytest.fixture
def staff_profile(db, admin_user, department):
    return StaffProfile.objects.create(
        user=admin_user,
        employee_id="EMP001",
        department=department,
        job_title="Researcher",
    )


@pytest.fixture
def annual_leave(db):
    return LeaveType.objects.create(name="Annual Leave", paid=True, max_days_per_year=21)


@pytest.mark.django_db
def test_leave_request_defaults_to_pending(staff_profile, annual_leave):
    req = LeaveRequest.objects.create(
        staff=staff_profile,
        leave_type=annual_leave,
        start_date="2026-07-01",
        end_date="2026-07-05",
        days=5,
    )
    assert req.status == LeaveRequest.Status.PENDING


@pytest.mark.django_db
def test_leave_request_can_be_approved(staff_profile, annual_leave, admin_user):
    req = LeaveRequest.objects.create(
        staff=staff_profile,
        leave_type=annual_leave,
        start_date="2026-07-01",
        end_date="2026-07-03",
        days=3,
    )
    req.status = LeaveRequest.Status.APPROVED
    req.reviewed_by = admin_user
    req.reviewed_at = timezone.now()
    req.save()
    req.refresh_from_db()
    assert req.status == LeaveRequest.Status.APPROVED
    assert req.reviewed_by == admin_user


@pytest.mark.django_db
def test_back_to_office_links_to_leave(staff_profile, annual_leave):
    req = LeaveRequest.objects.create(
        staff=staff_profile,
        leave_type=annual_leave,
        start_date="2026-07-01",
        end_date="2026-07-03",
        days=3,
        status=LeaveRequest.Status.APPROVED,
    )
    bto = BackToOfficeReport.objects.create(
        staff=staff_profile,
        leave_request=req,
        return_date="2026-07-04",
        summary="Attended workshop.",
    )
    assert bto.leave_request == req


@pytest.mark.django_db
def test_travel_request_lifecycle(staff_profile, admin_user):
    tr = TravelRequest.objects.create(
        staff=staff_profile,
        purpose="Conference",
        destination="Nairobi",
        travel_type=TravelRequest.TravelType.REGIONAL,
        departure_date="2026-08-01",
        return_date="2026-08-04",
    )
    assert tr.status == TravelRequest.Status.DRAFT

    tr.status = TravelRequest.Status.APPROVED
    tr.approved_by = admin_user
    tr.approved_at = timezone.now()
    tr.save()

    report = TravelReport.objects.create(
        travel_request=tr,
        summary="Presented paper.",
        actual_cost=1200,
    )
    tr.status = TravelRequest.Status.COMPLETED
    tr.save()
    tr.refresh_from_db()
    assert tr.status == TravelRequest.Status.COMPLETED
    assert report.travel_request == tr


@pytest.mark.django_db
def test_permanent_staff_annual_entitlement(staff_profile):
    assert staff_profile.annual_leave_entitlement == 21


@pytest.mark.django_db
def test_contract_staff_annual_entitlement(db, admin_user, department):
    profile = StaffProfile.objects.create(
        user=admin_user,
        employee_id="EMP002",
        department=department,
        employment_type=StaffProfile.EmploymentType.CONTRACT,
    )
    assert profile.annual_leave_entitlement == 14
