<?php

namespace App\Modules\HR\Offboarding\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\HR\Employees\Repositories\EmployeeRepository;
use App\Modules\HR\Offboarding\DTOs\OffboardingData;
use App\Modules\HR\Offboarding\Models\OffboardingCase;
use App\Modules\HR\Offboarding\Repositories\OffboardingRepository;
use App\Modules\HR\Offboarding\Requests\ChecklistItemRequest;
use App\Modules\HR\Offboarding\Requests\OffboardingRequest;
use App\Modules\HR\Offboarding\Services\OffboardingService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class OffboardingController extends Controller
{
    public function __construct(
        private readonly OffboardingRepository $repository,
        private readonly OffboardingService $service,
        private readonly EmployeeRepository $employees,
    ) {}

    public function index(Request $request): JsonResponse|View
    {
        $this->authorize('viewAny', OffboardingCase::class);

        if ($request->expectsJson()) {
            return response()->json($this->repository->paginate((int) auth()->user()->tenant_id));
        }

        return view('pages.hr.offboarding.index', [
            'cases' => $this->repository->paginateForIndex((int) auth()->user()->tenant_id, $request),
            'employees' => $this->employees->listForSelect((int) auth()->user()->tenant_id),
        ]);
    }

    public function store(OffboardingRequest $r): JsonResponse|RedirectResponse
    {
        $case = $this->service->create(OffboardingData::fromValidated($r->validated()), (int) $r->user()->tenant_id, (int) $r->user()->id);

        return $r->expectsJson()
            ? response()->json($case, 201)
            : redirect()->route('hr.offboarding.show', $case)->with('success', __('offboarding.flash.created'));
    }

    public function show(OffboardingCase $case): JsonResponse|View
    {
        $this->authorize('view', $case);

        $case->load(['employee', 'checklistItems']);

        return request()->expectsJson() ? response()->json($case) : view('pages.hr.offboarding.show', compact('case'));
    }

    public function update(OffboardingRequest $r, OffboardingCase $case): JsonResponse|RedirectResponse
    {
        $this->authorize('update', $case);
        abort_unless($case->status === 'draft', 422);

        $case = $this->repository->update($case, $r->validated());

        return $r->expectsJson() ? response()->json($case) : back()->with('success', __('offboarding.flash.updated'));
    }

    public function action(OffboardingCase $case, string $action): JsonResponse|RedirectResponse
    {
        $this->authorize('manage', $case);

        $case = $this->service->transition($case, $action);

        return request()->expectsJson() ? response()->json($case) : back()->with('success', __('offboarding.flash.action'));
    }

    public function addChecklistItem(ChecklistItemRequest $r, OffboardingCase $case): JsonResponse|RedirectResponse
    {
        $this->authorize('manage', $case);

        $item = $this->service->addChecklistItem($case, $r->validated(), (int) $r->user()->id);

        return $r->expectsJson() ? response()->json($item, 201) : back()->with('success', __('offboarding.flash.checklist'));
    }
}
