"""HR endpoints for employee advances (primary module for advance lifecycle)."""
from rest_framework.authentication import TokenAuthentication
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from system_administration.models import CompanyProfile
from system_administration.utils import check_if_system_administrator

from human_resource.models import StaffProfile

from finance_and_accounting.employee_advance import (
    create_hr_employee_advance,
    list_company_advances,
    update_advance_recovery_terms,
)
from finance_and_accounting.models import EmployeeAdvance


def _hr_can_manage(staff_profile, company_profile) -> bool:
    return (
        staff_profile.company_department
        and staff_profile.company_department.department_name == "human_resource_management"
        and staff_profile.is_head_of_department is True
        and staff_profile.has_read_write_priviledges is True
        and company_profile
    ) or check_if_system_administrator(staff_profile)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def employee_advances_list(request):
    company_serial_number = request.data.get("serial_number")
    branch_id = request.data.get("company_branch_id") or ""
    include_closed = str(request.data.get("include_closed", "false")).lower() == "true"
    try:
        company_profile = CompanyProfile.objects.get(company_serial_number=company_serial_number)
        staff_profile = StaffProfile.objects.get(user=request.user)
        if not _hr_can_manage(staff_profile, company_profile):
            return Response({"message": "You are unauthorised to perform this action"}, status=401)

        rows = list_company_advances(
            company_profile=company_profile,
            branch_id=branch_id or None,
            include_closed=include_closed,
        )
        return Response({"message": "true", "payload": {"advances_list": rows}}, status=200)
    except CompanyProfile.DoesNotExist:
        return Response({"message": "Company not found"}, status=404)
    except Exception as exc:
        return Response({"message": str(exc)}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def create_employee_advance(request):
    company_serial_number = request.data.get("serial_number")
    staff_id = request.data.get("staff_id")
    amount = request.data.get("amount")
    description = request.data.get("description", "")
    recovery_module = request.data.get("recovery_module", "percentage")
    recovery_value = request.data.get("recovery_value")
    try:
        company_profile = CompanyProfile.objects.get(company_serial_number=company_serial_number)
        staff_profile = StaffProfile.objects.get(user=request.user)
        if not _hr_can_manage(staff_profile, company_profile):
            return Response({"message": "You are unauthorised to perform this action"}, status=401)

        staff_on_advance = StaffProfile.objects.get(id=int(staff_id))
        advance = create_hr_employee_advance(
            staff=staff_on_advance,
            amount=amount,
            description=description,
            recorded_by=staff_profile,
            recovery_module=recovery_module,
            recovery_value=recovery_value,
        )
        return Response({
            "message": "Employee advance recorded successfully",
            "payload": {"advance_id": str(advance.id), "reference_number": advance.reference_number},
        }, status=200)
    except StaffProfile.DoesNotExist:
        return Response({"message": "Staff not found"}, status=404)
    except ValueError as exc:
        return Response({"message": str(exc)}, status=406)
    except Exception as exc:
        return Response({"message": str(exc)}, status=500)


@api_view(["POST"])
@authentication_classes([TokenAuthentication])
@permission_classes([IsAuthenticated])
def update_employee_advance_recovery(request):
    company_serial_number = request.data.get("serial_number")
    advance_id = request.data.get("advance_id")
    recovery_module = request.data.get("recovery_module")
    recovery_value = request.data.get("recovery_value")
    try:
        company_profile = CompanyProfile.objects.get(company_serial_number=company_serial_number)
        staff_profile = StaffProfile.objects.get(user=request.user)
        if not _hr_can_manage(staff_profile, company_profile):
            return Response({"message": "You are unauthorised to perform this action"}, status=401)

        advance = EmployeeAdvance.objects.select_related("company_branch__company_profile").get(
            id=int(advance_id),
            company_branch__company_profile=company_profile,
        )
        update_advance_recovery_terms(
            advance=advance,
            recovery_module=recovery_module,
            recovery_value=recovery_value,
        )
        return Response({"message": "Advance recovery terms updated"}, status=200)
    except EmployeeAdvance.DoesNotExist:
        return Response({"message": "Advance not found"}, status=404)
    except ValueError as exc:
        return Response({"message": str(exc)}, status=406)
    except Exception as exc:
        return Response({"message": str(exc)}, status=500)
