<?php

namespace App\Modules\HR\Recruitment\Services;

use App\Modules\Admin\ActivityLog\Models\ActivityLog;
use App\Modules\HR\Recruitment\Models\RecruitmentHiring;
use App\Modules\HR\Recruitment\Models\RecruitmentInterview;
use App\Modules\HR\Recruitment\Models\RecruitmentVacancy;
use App\Modules\HR\Recruitment\Repositories\RecruitmentApplicationRepository;
use App\Modules\HR\Recruitment\Repositories\RecruitmentOfferLetterRepository;
use App\Modules\HR\Recruitment\Repositories\RecruitmentVacancyRepository;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class VacancyDetailPageService
{
    public function __construct(
        private readonly RecruitmentVacancyRepository $vacancies,
        private readonly RecruitmentApplicationRepository $applications,
        private readonly RecruitmentOfferLetterRepository $offers,
    ) {}

    /** @return array<string, mixed> */
    public function build(int $tenantId, RecruitmentVacancy $vacancy, string $tab): array
    {
        $row = $this->vacancies->findForShow($tenantId, (int) $vacancy->id);
        $tab = in_array($tab, $this->tabs(), true) ? $tab : 'overview';

        return [
            'vacancy' => $row,
            'tab' => $tab,
            'tabs' => $this->tabs(),
            'tabData' => $this->tabData($tenantId, $row, $tab),
        ];
    }

    /** @return list<string> */
    public function tabs(): array
    {
        return ['overview', 'applications', 'interviews', 'offers', 'hiring', 'activity'];
    }

    private function tabData(int $tenantId, RecruitmentVacancy $row, string $tab): mixed
    {
        return match ($tab) {
            'applications' => $this->applications->paginateForTenant($tenantId, ['vacancy_id' => $row->id], 15),
            'interviews' => $this->interviewsForVacancy($tenantId, (int) $row->id),
            'offers' => $this->offers->paginateForTenant($tenantId, ['vacancy_id' => $row->id], 15),
            'hiring' => $this->hiringsForVacancy($tenantId, (int) $row->id),
            'activity' => $this->activityForVacancy($tenantId, $row),
            default => null,
        };
    }

    private function interviewsForVacancy(int $tenantId, int $vacancyId): LengthAwarePaginator
    {
        return RecruitmentInterview::query()
            ->where('tenant_id', $tenantId)
            ->whereHas('application', fn ($a) => $a->where('vacancy_id', $vacancyId))
            ->with(['application.candidate', 'interviewer'])
            ->orderByDesc('scheduled_at')
            ->paginate(15)
            ->withQueryString();
    }

    private function hiringsForVacancy(int $tenantId, int $vacancyId): Collection
    {
        return RecruitmentHiring::query()
            ->where('tenant_id', $tenantId)
            ->where('vacancy_id', $vacancyId)
            ->with(['employee', 'candidate', 'offerLetter'])
            ->orderByDesc('hired_at')
            ->limit(100)
            ->get();
    }

    private function activityForVacancy(int $tenantId, RecruitmentVacancy $vacancy): Collection
    {
        return ActivityLog::query()
            ->where('tenant_id', $tenantId)
            ->where('entity_type', $vacancy::class)
            ->where('entity_id', $vacancy->id)
            ->with('user:id,name')
            ->orderByDesc('created_at')
            ->limit(50)
            ->get();
    }
}
