<?php

namespace App\Modules\HR\Recruitment\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\HR\Recruitment\DTOs\VacancyWriteData;
use App\Modules\HR\Recruitment\Models\RecruitmentVacancy;
use App\Modules\HR\Recruitment\Repositories\RecruitmentVacancyRepository;
use App\Modules\HR\Recruitment\Requests\StoreVacancyRequest;
use App\Modules\HR\Recruitment\Requests\UpdateVacancyRequest;
use App\Modules\HR\Recruitment\Services\RecruitmentVacancyService;
use App\Modules\HR\Recruitment\Services\VacancyDetailPageService;
use App\Modules\HR\Recruitment\Services\VacancyFormOptionsService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class VacanciesPageController extends Controller
{
    public function __construct(
        private readonly RecruitmentVacancyService $service,
        private readonly RecruitmentVacancyRepository $repository,
        private readonly VacancyDetailPageService $detailPages,
        private readonly VacancyFormOptionsService $formOptions,
    ) {}

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

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

    public function show(Request $request, RecruitmentVacancy $vacancy): View
    {
        $this->authorize('view', $vacancy);

        return view(
            'pages.hr.recruitment.vacancies.show',
            $this->detailPages->build(
                $this->tenantId(),
                $vacancy,
                $request->string('tab')->toString() ?: 'overview',
            ),
        );
    }

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

        return view('pages.hr.recruitment.vacancies.create', $this->formOptions->forForm($this->tenantId()));
    }

    public function store(StoreVacancyRequest $request): RedirectResponse
    {
        $row = $this->service->store(
            VacancyWriteData::fromValidated($request->validated()),
            (int) $request->user()->id,
        );

        return redirect()
            ->route('hr.recruitment.vacancies.show', $row)
            ->with('status', __('recruitment.vacancies.flash.created'));
    }

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

        return view('pages.hr.recruitment.vacancies.edit', array_merge(
            $this->formOptions->forForm($this->tenantId()),
            ['vacancy' => $vacancy],
        ));
    }

    public function update(UpdateVacancyRequest $request, RecruitmentVacancy $vacancy): RedirectResponse
    {
        $this->service->update($vacancy, VacancyWriteData::fromValidated($request->validated()));

        return redirect()
            ->route('hr.recruitment.vacancies.show', $vacancy)
            ->with('status', __('recruitment.vacancies.flash.updated'));
    }

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

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

    public function publish(RecruitmentVacancy $vacancy): RedirectResponse
    {
        $this->authorize('publish', $vacancy);
        $this->service->publish($vacancy);

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

    public function close(RecruitmentVacancy $vacancy): RedirectResponse
    {
        $this->authorize('close', $vacancy);
        $this->service->close($vacancy);

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

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

        return (int) $id;
    }
}
