<?php

namespace App\Modules\HR\Recruitment\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\HR\Recruitment\DTOs\InterviewScorecardWriteData;
use App\Modules\HR\Recruitment\Models\RecruitmentInterviewScorecard;
use App\Modules\HR\Recruitment\Repositories\RecruitmentInterviewRepository;
use App\Modules\HR\Recruitment\Repositories\RecruitmentInterviewScorecardRepository;
use App\Modules\HR\Recruitment\Requests\BulkDestroyScorecardsRequest;
use App\Modules\HR\Recruitment\Requests\StoreInterviewScorecardRequest;
use App\Modules\HR\Recruitment\Requests\UpdateInterviewScorecardRequest;
use App\Modules\HR\Recruitment\Services\RecruitmentInterviewScorecardService;
use App\Modules\HR\Recruitment\Support\ScorecardRecommendation;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class InterviewScorecardsPageController extends Controller
{
    public function __construct(
        private readonly RecruitmentInterviewScorecardService $service,
        private readonly RecruitmentInterviewScorecardRepository $repository,
        private readonly RecruitmentInterviewRepository $interviews,
    ) {}

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

        return view('pages.hr.recruitment.interview-scorecards.index', [
            'scorecards' => $this->repository->paginateForTenant($tenantId, [
                'q' => $request->string('q')->toString() ?: null,
                'recommendation' => $request->string('recommendation')->toString() ?: null,
                'interview_id' => $request->integer('interview_id') ?: null,
            ]),
            'recommendationOptions' => $this->recommendationOptions(),
            'interviewOptions' => collect($this->interviews->searchForLookup($tenantId, '', 50))
                ->mapWithKeys(fn ($o) => [$o['value'] => $o['label']])->all(),
        ]);
    }

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

        return view('pages.hr.recruitment.interview-scorecards.create', $this->formShared());
    }

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

        return redirect()
            ->route('hr.recruitment.interview-scorecards.index')
            ->with('status', __('recruitment.interview_scorecards.flash.created'));
    }

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

        return view('pages.hr.recruitment.interview-scorecards.edit', array_merge($this->formShared(), [
            'scorecard' => $scorecard->load(['interview.application.candidate']),
        ]));
    }

    public function update(
        UpdateInterviewScorecardRequest $request,
        RecruitmentInterviewScorecard $scorecard,
    ): RedirectResponse {
        $this->service->update(
            $scorecard,
            InterviewScorecardWriteData::fromValidated($request->validated()),
        );

        return redirect()
            ->route('hr.recruitment.interview-scorecards.index')
            ->with('status', __('recruitment.interview_scorecards.flash.updated'));
    }

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

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

    public function bulkDestroy(BulkDestroyScorecardsRequest $request): RedirectResponse
    {
        $count = $this->service->destroyMany($request->validated('ids'));

        return back()->with(
            'status',
            __('recruitment.interview_scorecards.flash.bulk_deleted', ['count' => $count])
        );
    }

    /** @return array<string, mixed> */
    private function formShared(): array
    {
        return [
            'recommendationOptions' => $this->recommendationOptions(false),
        ];
    }

    /** @return array<string, string> */
    private function recommendationOptions(bool $withAll = true): array
    {
        $opts = $withAll ? ['' => __('recruitment.filters.all')] : [];
        foreach (ScorecardRecommendation::all() as $r) {
            $opts[$r] = __('recruitment.interview_scorecards.recommendation.'.$r);
        }

        return $opts;
    }

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

        return (int) $id;
    }
}
