<?php

namespace App\Modules\HR\Employees\Services;

use App\Modules\Admin\ActivityLog\Models\ActivityLog;
use App\Modules\HR\Contracts\Models\EmploymentContract;
use App\Modules\HR\Employees\Models\Employee;
use App\Modules\HR\Employees\Repositories\EmployeeAssetAssignmentRepository;
use App\Modules\HR\Employees\Repositories\EmployeeEmergencyContactRepository;
use App\Modules\HR\Employees\Repositories\EmployeeEmploymentHistoryRepository;
use App\Modules\HR\Employees\Repositories\EmployeeRepository;
use App\Modules\HR\Employees\Repositories\EmployeeSkillRepository;
use App\Modules\Payroll\Models\PayrollEmployeeSnapshot;
use Illuminate\Support\Collection;

class EmployeeProfilePageService
{
    public function __construct(
        private readonly EmployeeRepository $employees,
        private readonly EmployeeEmergencyContactRepository $contacts,
        private readonly EmployeeSkillRepository $skills,
        private readonly EmployeeAssetAssignmentRepository $assets,
        private readonly EmployeeEmploymentHistoryRepository $employmentHistories,
    ) {}

    /** @return array<string, mixed> */
    public function build(Employee $employee, string $tab): array
    {
        $row = $this->employees->findOrFailForShow((int) $employee->id);
        $tab = in_array($tab, $this->tabs(), true) ? $tab : 'overview';
        $tenantId = (int) $row->tenant_id;

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

    /** @return list<string> */
    public function tabs(): array
    {
        return [
            'overview',
            'government',
            'bank',
            'payroll',
            'documents',
            'emergency_contacts',
            'skills',
            'assets',
            'employment_history',
            'activity',
        ];
    }

    private function tabData(int $tenantId, Employee $row, string $tab): mixed
    {
        return match ($tab) {
            'overview' => $this->contractsForEmployee($tenantId, (int) $row->id),
            'emergency_contacts' => $this->contacts->listForEmployee($tenantId, (int) $row->id),
            'skills' => $this->skills->listForEmployee($tenantId, (int) $row->id),
            'assets' => $this->assets->listForEmployee($tenantId, (int) $row->id),
            'employment_history' => $this->employmentHistories->listForEmployee($tenantId, (int) $row->id),
            'payroll' => $this->payrollForEmployee($tenantId, (int) $row->id),
            'activity' => $this->activityForEmployee($tenantId, $row),
            'documents' => $row->documents,
            default => null,
        };
    }

    private function payrollForEmployee(int $tenantId, int $employeeId): Collection
    {
        return PayrollEmployeeSnapshot::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->with('period:id,name,start_date,end_date,status')
            ->orderByDesc('generated_at')
            ->limit(24)
            ->get();
    }

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

    private function contractsForEmployee(int $tenantId, int $employeeId): Collection
    {
        return EmploymentContract::query()
            ->where('tenant_id', $tenantId)
            ->where('employee_id', $employeeId)
            ->orderByDesc('start_date')
            ->limit(20)
            ->get();
    }
}
