<?php

namespace App\Modules\HR\Compensation\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\HR\Compensation\Repositories\CompensationRepository;
use App\Modules\HR\Compensation\Requests\CompensationRequest;
use App\Modules\HR\Compensation\Services\CompensationService;
use App\Modules\HR\Employees\Models\Employee;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class CompensationController extends Controller
{
    public function __construct(private readonly CompensationRepository $repository, private readonly CompensationService $service) {}

    public function index(Request $request, string $kind): JsonResponse|View
    {
        abort_unless(in_array($kind, ['allowance', 'deduction'], true), 404);

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

        $types = $this->repository->paginateTypesForIndex((int) auth()->user()->tenant_id, $kind, $request);

        return view('pages.hr.'.($kind === 'allowance' ? 'allowances' : 'deductions').'.index', compact('types', 'kind'));
    }

    public function store(CompensationRequest $request, string $kind): JsonResponse|RedirectResponse
    {
        $type = $this->service->createType((int) $request->user()->tenant_id, $kind, $request->validated());

        return $request->expectsJson() ? response()->json($type, 201) : back()->with('success', __('compensation.flash.created'));
    }

    public function attach(CompensationRequest $request, string $kind, Employee $employee): JsonResponse|RedirectResponse
    {
        abort_unless((int) $employee->tenant_id === (int) $request->user()->tenant_id, 404);

        $item = $this->service->attach((int) $employee->tenant_id, (int) $employee->id, $kind, $request->validated());

        return $request->expectsJson()
            ? response()->json($item, 201)
            : redirect()
                ->route('hr.employees.show', ['employee' => $employee, 'tab' => 'payroll'])
                ->with('status', __('compensation.flash.attached'));
    }

    public function detach(Request $request, string $kind, Employee $employee, int $item): JsonResponse|RedirectResponse
    {
        abort_unless((int) $employee->tenant_id === (int) $request->user()->tenant_id, 404);
        abort_unless($request->user()?->can('compensation.manage'), 403);

        $this->repository->deactivateItem((int) $employee->tenant_id, (int) $employee->id, $item);

        return $request->expectsJson()
            ? response()->json([], 204)
            : redirect()
                ->route('hr.employees.show', ['employee' => $employee, 'tab' => 'payroll'])
                ->with('status', __('compensation.flash.detached'));
    }

    public function update(CompensationRequest $request, string $kind, int $id): JsonResponse|RedirectResponse
    {
        $type = $this->repository->updateType((int) $request->user()->tenant_id, $kind, $id, $request->validated());

        return $request->expectsJson() ? response()->json($type) : back()->with('success', __('compensation.flash.updated'));
    }

    public function destroy(string $kind, int $id): JsonResponse|RedirectResponse
    {
        $this->repository->deleteType((int) auth()->user()->tenant_id, $kind, $id);

        return request()->expectsJson() ? response()->json([], 204) : back()->with('success', __('compensation.flash.deleted'));
    }
}
