<?php

namespace App\Modules\HR\Offboarding\Services;

use App\Modules\HR\Offboarding\DTOs\OffboardingData;
use App\Modules\HR\Offboarding\Events\OffboardingSubmitted;
use App\Modules\HR\Offboarding\Models\OffboardingCase;
use App\Modules\HR\Offboarding\Models\OffboardingChecklistItem;
use App\Modules\HR\Offboarding\Repositories\OffboardingRepository;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

class OffboardingService
{
    public function __construct(private readonly OffboardingRepository $repository) {}

    public function create(OffboardingData $dto, int $tenant, int $user): OffboardingCase
    {
        return $this->repository->create($dto->attributes + ['tenant_id' => $tenant, 'created_by' => $user, 'status' => 'draft']);
    }

    public function transition(OffboardingCase $case, string $action): OffboardingCase
    {
        $next = [
            'submit' => ['draft' => 'submitted'], 'approve' => ['submitted' => 'approved'],
            'clearance' => ['approved' => 'clearance'], 'final-settlement' => ['clearance' => 'final_settlement'],
            'complete' => ['final_settlement' => 'completed'],
        ][$action][$case->status] ?? null;
        if ($next === null) {
            throw ValidationException::withMessages(['status' => __('offboarding.invalid_transition')]);
        }

        $updated = DB::transaction(function () use ($case, $next): OffboardingCase {
            if ($next === 'clearance') {
                $this->repository->returnAssets((int) $case->tenant_id, (int) $case->employee_id);
            }
            if ($next === 'completed') {
                $case->employee()->update(['is_active' => false]);
                $case->employee->user()?->update(['is_active' => false, 'deactivated_at' => now()]);
            }

            return $this->repository->update($case, [
                'status' => $next,
                'deactivated_user_at' => $next === 'completed' ? now() : $case->deactivated_user_at,
            ]);
        });
        if ($next === 'submitted') {
            OffboardingSubmitted::dispatch($updated);
        }

        return $updated;
    }

    public function addChecklistItem(OffboardingCase $case, array $data, int $userId): OffboardingChecklistItem
    {
        $done = (bool) ($data['is_done'] ?? false);

        return $case->checklistItems()->create($data + [
            'is_done' => $done, 'done_at' => $done ? now() : null, 'done_by' => $done ? $userId : null,
        ]);
    }
}
