<?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\HrDepartment;
use App\Modules\HR\Models\HrEmployeeProfile;

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

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

        $db = App::getInstance()->db();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");

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

    public function create(Request $request): Response
    {
        $db = App::getInstance()->db();
        $departments = HrDepartment::allActive();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");
        $employees = HrEmployeeProfile::getActiveIds();

        return $this->view('HR.Views.departments.form', [
            'department'  => null,
            'departments' => $departments,
            'branches'    => $branches,
            'employees'   => $employees,
        ]);
    }

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

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

        $department = HrDepartment::create($data);

        return $this->redirect('/hr/departments/' . $department->id)->withSuccess('تم إنشاء القسم بنجاح');
    }

    public function show(Request $request, string $id): Response
    {
        $department = HrDepartment::find((int) $id);
        if (!$department) {
            return $this->redirect('/hr/departments')->withError('القسم غير موجود');
        }

        $db = App::getInstance()->db();

        $parent = $department->parent_id ? HrDepartment::find((int) $department->parent_id) : null;

        $manager = $department->manager_employee_id
            ? $db->selectOne("SELECT hp.id, hp.first_name_ar, hp.last_name_ar FROM hr_employee_profiles hp WHERE hp.employee_id = ? AND hp.is_archived = 0", [(int) $department->manager_employee_id])
            : null;

        $branch = $department->branch_id
            ? $db->selectOne("SELECT id, name_ar FROM branches WHERE id = ?", [(int) $department->branch_id])
            : null;

        $children = $db->select(
            "SELECT id, name_ar, department_code FROM hr_departments WHERE parent_id = ? AND is_archived = 0 ORDER BY name_ar",
            [(int) $id]
        );

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

        return $this->view('HR.Views.departments.show', [
            'department'    => $department,
            'parent'        => $parent,
            'manager'       => $manager,
            'branch'        => $branch,
            'children'      => $children,
            'employeeCount' => (int) ($employeeCount['cnt'] ?? 0),
        ]);
    }

    public function edit(Request $request, string $id): Response
    {
        $department = HrDepartment::find((int) $id);
        if (!$department) {
            return $this->redirect('/hr/departments')->withError('القسم غير موجود');
        }

        $db = App::getInstance()->db();
        $departments = HrDepartment::allActive();
        $branches = $db->select("SELECT id, name_ar FROM branches WHERE is_active = 1 ORDER BY name_ar");
        $employees = HrEmployeeProfile::getActiveIds();

        return $this->view('HR.Views.departments.form', [
            'department'  => $department,
            'departments' => $departments,
            'branches'    => $branches,
            'employees'   => $employees,
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $department = HrDepartment::find((int) $id);
        if (!$department) {
            return $this->redirect('/hr/departments')->withError('القسم غير موجود');
        }

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

        // Prevent circular parent
        if ((int) ($data['parent_id'] ?? 0) === (int) $id) {
            $errors[] = 'لا يمكن أن يكون القسم هو الأب لنفسه';
        }

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

        $department->update($data);

        return $this->redirect('/hr/departments/' . $id)->withSuccess('تم تحديث القسم بنجاح');
    }

    public function archive(Request $request, string $id): Response
    {
        $department = HrDepartment::find((int) $id);
        if (!$department) {
            return $this->redirect('/hr/departments')->withError('القسم غير موجود');
        }

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

        if ((int) ($employeeCount['cnt'] ?? 0) > 0) {
            return $this->redirect('/hr/departments/' . $id)->withError('لا يمكن حذف قسم يحتوي على موظفين نشطين');
        }

        $childCount = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM hr_departments WHERE parent_id = ? AND is_archived = 0",
            [(int) $id]
        );

        if ((int) ($childCount['cnt'] ?? 0) > 0) {
            return $this->redirect('/hr/departments/' . $id)->withError('لا يمكن حذف قسم يحتوي على أقسام فرعية');
        }

        $department->archive();

        return $this->redirect('/hr/departments')->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,
            'department_code' => strtoupper(trim((string) $request->post('department_code', ''))),
            'parent_id'       => ((int) $request->post('parent_id', 0)) ?: null,
            'manager_employee_id' => ((int) $request->post('manager_employee_id', 0)) ?: null,
            'branch_id'  => ((int) $request->post('branch_id', 0)) ?: 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['department_code'] === '') {
            $errors[] = 'كود القسم مطلوب';
        }
        return $errors;
    }

    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);
    }
}
