<?php

namespace App\Controllers\Api\V1;

use App\Controllers\BaseController;
use App\Services\Candidate\CandidateProfileService;
use App\Services\Candidate\ResumeUploadService;

class CandidateController extends BaseController
{
    private CandidateProfileService $profiles;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->profiles = new CandidateProfileService();
    }

    public function me()
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $full = $this->profiles->getFullProfile($user->id);
        return $this->jsonSuccess($full);
    }

    public function updateMe()
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $rules = [
            'headline'               => 'permit_empty|max_length[150]',
            'salary_expectation_min' => 'permit_empty|decimal',
            'salary_expectation_max' => 'permit_empty|decimal',
            'availability_status'    => 'permit_empty|in_list[open_to_work,actively_looking,not_looking,available_immediately]',
        ];
        if (! $this->validate($rules)) {
            return $this->jsonValidationError($this->validator->getErrors());
        }

        $updated = $this->profiles->updateBasics($user->id, $this->request->getJSON(true));
        $this->profiles->touchLastActive($user->id);

        return $this->jsonSuccess(['profile' => $updated]);
    }

    public function addExperience()
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $rules = [
            'job_title'    => 'required|max_length[150]',
            'company_name' => 'required|max_length[150]',
            'start_date'   => 'required|valid_date',
        ];
        if (! $this->validate($rules)) {
            return $this->jsonValidationError($this->validator->getErrors());
        }

        $profile = $this->profiles->getFullProfile($user->id)['profile'];
        $experience = $this->profiles->addExperience($profile['id'], $this->request->getJSON(true));

        return $this->jsonSuccess(['experience' => $experience], [], 201);
    }

    public function addEducation()
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $rules = [
            'institution' => 'required|max_length[150]',
            'degree'      => 'required|max_length[150]',
        ];
        if (! $this->validate($rules)) {
            return $this->jsonValidationError($this->validator->getErrors());
        }

        $profile = $this->profiles->getFullProfile($user->id)['profile'];
        $education = $this->profiles->addEducation($profile['id'], $this->request->getJSON(true));

        return $this->jsonSuccess(['education' => $education], [], 201);
    }

    public function addSkill()
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $input = $this->request->getJSON(true);
        if (empty($input['name'])) {
            return $this->jsonValidationError(['name' => 'Skill name is required.']);
        }

        $profile = $this->profiles->getFullProfile($user->id)['profile'];
        $this->profiles->addSkill(
            $profile['id'],
            $input['name'],
            $input['proficiency'] ?? 'intermediate',
            $input['years_experience'] ?? null
        );

        return $this->jsonSuccess(['message' => 'Skill added.']);
    }

    public function removeSkill(int $skillId)
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $profile = $this->profiles->getFullProfile($user->id)['profile'];
        $this->profiles->removeSkill($profile['id'], $skillId);

        return $this->jsonSuccess(['message' => 'Skill removed.']);
    }

    public function uploadResume()
    {
        $user = $this->currentUser();
        $this->guardCandidate($user);

        $file = $this->request->getFile('resume');
        if (! $file) {
            return $this->jsonError([['code' => 'FILE_MISSING', 'message' => 'No file uploaded under field "resume".']], 400);
        }

        try {
            $uploader = new ResumeUploadService();
            $stored = $uploader->validateAndStore($file);
        } catch (\InvalidArgumentException $e) {
            return $this->jsonError([['code' => 'INVALID_FILE', 'message' => $e->getMessage()]], 422);
        } catch (\RuntimeException $e) {
            return $this->jsonError([['code' => 'UPLOAD_FAILED', 'message' => $e->getMessage()]], 500);
        }

        $profile = $this->profiles->getFullProfile($user->id)['profile'];
        $resume = $this->profiles->attachResume(
            $profile['id'],
            $stored['file_path'],
            $stored['original_filename'],
            (bool) ($this->request->getPost('make_primary') ?? true)
        );

        return $this->jsonSuccess(['resume' => $resume], [], 201);
    }

    private function guardCandidate($user): void
    {
        if (! $user->isCandidate()) {
            throw new \App\Exceptions\ForbiddenException('This endpoint is only available to candidate accounts.');
        }
    }
}
