<?php

namespace App\Modules\HR\Recruitment\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\HR\Departments\Models\Department;
use App\Modules\HR\Recruitment\DTOs\JobRequestWriteData;
use App\Modules\HR\Recruitment\Models\RecruitmentJobRequest;
use App\Modules\HR\Recruitment\Repositories\RecruitmentJobRequestRepository;
use App\Modules\HR\Recruitment\Requests\RejectJobRequestRequest;
use App\Modules\HR\Recruitment\Requests\StoreJobRequestRequest;
use App\Modules\HR\Recruitment\Requests\UpdateJobRequestRequest;
use App\Modules\HR\Recruitment\Services\RecruitmentJobRequestService;
use App\Modules\HR\Recruitment\Support\JobRequestStatus;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class JobRequestsPageController extends Controller
{
    public function __construct(
        private readonly RecruitmentJobRequestService $service,
        private readonly RecruitmentJobRequestRepository $repository,
    ) {}

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

        return view('pages.hr.recruitment.job-requests.index', [
            'jobRequests' => $this->repository->paginateForTenant($this->tenantId(), [
                'q' => $request->string('q')->toString() ?: null,
                'status' => $request->string('status')->toString() ?: null,
                'department_id' => $request->integer('department_id') ?: null,
            ]),
            'statusOptions' => $this->statusOptions(),
            'departments' => $this->departments(),
        ]);
    }

    public function create(): View
    {
        $this->authorize('create', RecruitmentJobRequest::class);

        return view('pages.hr.recruitment.job-requests.create', [
            'departments' => $this->departments(),
        ]);
    }

    public function store(StoreJobRequestRequest $request): RedirectResponse
    {
        $this->service->store(
            JobRequestWriteData::fromValidated($request->validated()),
            (int) $request->user()->id,
        );

        return redirect()
            ->route('hr.recruitment.job-requests.index')
            ->with('status', __('recruitment.job_requests.flash.created'));
    }

    public function edit(RecruitmentJobRequest $jobRequest): View
    {
        $this->authorize('update', $jobRequest);

        return view('pages.hr.recruitment.job-requests.edit', [
            'jobRequest' => $jobRequest,
            'departments' => $this->departments(),
        ]);
    }

    public function update(UpdateJobRequestRequest $request, RecruitmentJobRequest $jobRequest): RedirectResponse
    {
        $this->service->update($jobRequest, JobRequestWriteData::fromValidated($request->validated()));

        return redirect()
            ->route('hr.recruitment.job-requests.index')
            ->with('status', __('recruitment.job_requests.flash.updated'));
    }

    public function destroy(RecruitmentJobRequest $jobRequest): RedirectResponse
    {
        $this->authorize('delete', $jobRequest);
        $this->service->destroy($jobRequest);

        return redirect()
            ->route('hr.recruitment.job-requests.index')
            ->with('status', __('recruitment.job_requests.flash.deleted'));
    }

    public function submit(RecruitmentJobRequest $jobRequest): RedirectResponse
    {
        $this->authorize('submit', $jobRequest);
        $this->service->submit($jobRequest);

        return back()->with('status', __('recruitment.job_requests.flash.submitted'));
    }

    public function approve(RecruitmentJobRequest $jobRequest): RedirectResponse
    {
        $this->authorize('approve', $jobRequest);
        $this->service->approve($jobRequest, request()->user());

        return back()->with('status', __('recruitment.job_requests.flash.approved'));
    }

    public function reject(RejectJobRequestRequest $request, RecruitmentJobRequest $jobRequest): RedirectResponse
    {
        $this->service->reject(
            $jobRequest,
            $request->user(),
            $request->validated('review_notes'),
        );

        return back()->with('status', __('recruitment.job_requests.flash.rejected'));
    }

    /** @return array<string, string> */
    private function statusOptions(): array
    {
        $opts = ['' => __('recruitment.filters.all')];
        foreach (JobRequestStatus::all() as $s) {
            $opts[$s] = __('recruitment.job_requests.status.'.$s);
        }

        return $opts;
    }

    private function departments()
    {
        return Department::query()->where('tenant_id', $this->tenantId())->orderBy('name')->get();
    }

    private function tenantId(): int
    {
        $id = auth()->user()?->tenant_id;
        abort_if($id === null, 403);

        return (int) $id;
    }
}
