<?php
declare(strict_types=1);

namespace App\Modules\HR\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\HR\Models\HrJobTitle;

class JobTitleController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'q'           => trim((string) $request->get('q', '')),
            'grade_level' => trim((string) $request->get('grade_level', '')),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = HrJobTitle::search($filters, 25, $page);

        return $this->view('HR.Views.job_titles.index', [
            'jobTitles'  => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
        ]);
    }

    public function create(Request $request): Response
    {
        return $this->view('HR.Views.job_titles.form', [
            'jobTitle' => null,
        ]);
    }

    public function store(Request $request): Response
    {
        $data = $this->extractData($request);
        $errors = $this->validateInput($data);

        if (!empty($errors)) {
            return $this->flashErrorsAndRedirect($errors, $request, '/hr/job-titles/create');
        }

        $jobTitle = HrJobTitle::create($data);

        return $this->redirect('/hr/job-titles')->withSuccess('تم إنشاء المسمى الوظيفي بنجاح');
    }

    public function edit(Request $request, string $id): Response
    {
        $jobTitle = HrJobTitle::find((int) $id);
        if (!$jobTitle) {
            return $this->redirect('/hr/job-titles')->withError('المسمى الوظيفي غير موجود');
        }

        return $this->view('HR.Views.job_titles.form', [
            'jobTitle' => $jobTitle,
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $jobTitle = HrJobTitle::find((int) $id);
        if (!$jobTitle) {
            return $this->redirect('/hr/job-titles')->withError('المسمى الوظيفي غير موجود');
        }

        $data = $this->extractData($request);
        $errors = $this->validateInput($data);

        if (!empty($errors)) {
            return $this->flashErrorsAndRedirect($errors, $request, '/hr/job-titles/' . $id . '/edit');
        }

        $jobTitle->update($data);

        return $this->redirect('/hr/job-titles')->withSuccess('تم تحديث المسمى الوظيفي بنجاح');
    }

    public function archive(Request $request, string $id): Response
    {
        $jobTitle = HrJobTitle::find((int) $id);
        if (!$jobTitle) {
            return $this->redirect('/hr/job-titles')->withError('المسمى الوظيفي غير موجود');
        }

        $db = App::getInstance()->db();
        $count = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM hr_employee_profiles WHERE job_title_id = ? AND employment_status = 'active' AND is_archived = 0",
            [(int) $id]
        );

        if ((int) ($count['cnt'] ?? 0) > 0) {
            return $this->redirect('/hr/job-titles')->withError('لا يمكن حذف مسمى وظيفي مرتبط بموظفين نشطين');
        }

        $jobTitle->archive();

        return $this->redirect('/hr/job-titles')->withSuccess('تم حذف المسمى الوظيفي بنجاح');
    }

    private function extractData(Request $request): array
    {
        return [
            'name_ar'            => trim((string) $request->post('name_ar', '')),
            'name_en'            => trim((string) $request->post('name_en', '')) ?: null,
            'title_code'         => strtoupper(trim((string) $request->post('title_code', ''))),
            'grade_level'        => ((int) $request->post('grade_level', 0)) ?: null,
            'min_salary'         => trim((string) $request->post('min_salary', '')) ?: null,
            'max_salary'         => trim((string) $request->post('max_salary', '')) ?: null,
            'description_ar'     => trim((string) $request->post('description_ar', '')) ?: null,
            'job_description_ar' => trim((string) $request->post('job_description_ar', '')) ?: null,
            'job_description_en' => trim((string) $request->post('job_description_en', '')) ?: null,
            'is_active'          => (int) ($request->post('is_active', 1)),
        ];
    }

    private function validateInput(array $data): array
    {
        $errors = [];
        if ($data['name_ar'] === '' || mb_strlen($data['name_ar']) < 2) {
            $errors[] = 'اسم المسمى الوظيفي بالعربي مطلوب (حرفان على الأقل)';
        }
        if ($data['title_code'] === '') {
            $errors[] = 'كود المسمى الوظيفي مطلوب';
        }
        if ($data['min_salary'] !== null && $data['max_salary'] !== null) {
            if (bccomp($data['min_salary'], $data['max_salary'], 2) > 0) {
                $errors[] = 'الحد الأدنى للراتب يجب أن يكون أقل من أو يساوي الحد الأقصى';
            }
        }
        return $errors;
    }

    public function descriptionCard(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $jobTitle = $db->selectOne(
            "SELECT * FROM hr_job_titles WHERE id = ? AND is_archived = 0",
            [(int) $id]
        );
        if (!$jobTitle) {
            return $this->redirect('/hr/job-titles')->withError('المسمى الوظيفي غير موجود');
        }

        $description = $db->selectOne(
            "SELECT * FROM hr_job_descriptions WHERE job_title_id = ? AND is_archived = 0 ORDER BY id DESC LIMIT 1",
            [(int) $id]
        );

        return $this->view('HR.Views.forms.job-description', [
            'jobTitle'    => $jobTitle,
            'description' => $description,
        ]);
    }

    private function flashErrorsAndRedirect(array $errors, Request $request, string $url): Response
    {
        $session = App::getInstance()->session();
        $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
        $session->flash('_old_input', $request->all());
        return $this->redirect($url);
    }
}
