"""HR global search integration."""

from __future__ import annotations

from typing import TYPE_CHECKING

from simorgh.core.search import SearchHit, SearchableSpec, register_searchable

if TYPE_CHECKING:
    from simorgh.core.context import RequestContext


def _search_employees(ctx: "RequestContext", query: str, limit: int) -> list[SearchHit]:
    from django.db.models import Q

    from simorgh.apps.hr_core.models import Employee

    if not ctx.tenant:
        return []

    qs = (
        Employee.objects.filter(tenant_id=ctx.tenant.pk)
        .filter(
            Q(first_name__icontains=query)
            | Q(last_name__icontains=query)
            | Q(display_name__icontains=query)
            | Q(employee_no__icontains=query)
            | Q(work_email__icontains=query)
        )
        .select_related("job_title", "department")
        .distinct()
        .order_by("last_name", "first_name")[:limit]
    )

    return [
        SearchHit(
            entity="hr.employee",
            id=str(e.public_id),
            title=str(e),
            subtitle=(
                f"{e.job_title.title if e.job_title else ''}"
                f" · {e.department.name if e.department else ''}"
            ).strip(" ·"),
            url=f"/hr/employees/{e.public_id}/",
            score=2.0 if query.lower() in (e.display_name or "").lower() else 1.0,
        )
        for e in qs
    ]


register_searchable(
    SearchableSpec(
        entity="hr.employee",
        label_key="hr.employee",
        search=_search_employees,
    )
)


def _search_leave_requests(ctx: "RequestContext", query: str, limit: int) -> list[SearchHit]:
    from django.db.models import Q

    from simorgh.apps.hr_core.models import LeaveRequest

    if not ctx.tenant:
        return []

    qs = (
        LeaveRequest.objects.filter(tenant_id=ctx.tenant.pk)
        .filter(
            Q(employee__first_name__icontains=query)
            | Q(employee__last_name__icontains=query)
            | Q(employee__display_name__icontains=query)
            | Q(leave_type__name__icontains=query)
            | Q(reason__icontains=query)
        )
        .select_related("employee", "leave_type")
        .distinct()
        .order_by("-from_date")[:limit]
    )

    return [
        SearchHit(
            entity="hr.leave_request",
            id=str(lr.pk),
            title=(
                f"{lr.employee.display_name or str(lr.employee)} — "
                f"{lr.leave_type.name}"
            ),
            subtitle=f"{lr.from_date} → {lr.to_date} ({lr.status})",
            url=f"/hr/leaves/{lr.pk}/",
            score=1.0,
        )
        for lr in qs
    ]


register_searchable(
    SearchableSpec(
        entity="hr.leave_request",
        label_key="hr.leave_request",
        search=_search_leave_requests,
    )
)


def _search_positions(ctx: "RequestContext", query: str, limit: int) -> list[SearchHit]:
    from django.db.models import Q

    from simorgh.apps.hr_core.models import Position

    if not ctx.tenant:
        return []

    qs = (
        Position.objects.filter(tenant_id=ctx.tenant.pk)
        .filter(
            Q(position_code__icontains=query)
            | Q(title__icontains=query)
            | Q(description__icontains=query)
        )
        .select_related("department", "job_title")
        .order_by("title")[:limit]
    )

    return [
        SearchHit(
            entity="hr.position",
            id=str(p.public_id),
            title=p.title,
            subtitle=(
                f"{p.position_code}"
                f"{' · ' + p.department.name if p.department else ''}"
            ),
            url=f"/hr/positions/{p.public_id}/",
            score=1.0,
        )
        for p in qs
    ]


register_searchable(
    SearchableSpec(
        entity="hr.position",
        label_key="hr.position",
        search=_search_positions,
    )
)


def _search_employments(ctx: "RequestContext", query: str, limit: int) -> list[SearchHit]:
    from django.db.models import Q

    from simorgh.apps.hr_core.models import Employment

    if not ctx.tenant:
        return []

    qs = (
        Employment.objects.filter(tenant_id=ctx.tenant.pk)
        .filter(
            Q(employee__first_name__icontains=query)
            | Q(employee__last_name__icontains=query)
            | Q(employee__display_name__icontains=query)
            | Q(employee__employee_no__icontains=query)
        )
        .select_related("employee", "job_title", "department")
        .order_by("employee__last_name")[:limit]
    )

    return [
        SearchHit(
            entity="hr.employment",
            id=str(e.public_id),
            title=f"{e.employee.display_name or str(e.employee)} — {e.get_status_display()}",
            subtitle=(
                f"{e.job_title.title if e.job_title else ''}"
                f"{' · ' + e.department.name if e.department else ''}"
            ).strip(" ·"),
            url=f"/hr/employments/{e.public_id}/",
            score=1.0,
        )
        for e in qs
    ]


register_searchable(
    SearchableSpec(
        entity="hr.employment",
        label_key="hr.employment",
        search=_search_employments,
    )
)
