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

class SalaryStructureController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();
        $structures = $db->select(
            "SELECT ss.*, (SELECT COUNT(*) FROM hr_salary_components sc WHERE sc.structure_id = ss.id AND sc.is_active = 1) as component_count
             FROM hr_salary_structures ss
             WHERE ss.is_archived = 0
             ORDER BY ss.is_default DESC, ss.name_ar ASC"
        );

        return $this->view('HR.Views.salary_structures.index', [
            'structures' => $structures,
        ]);
    }

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

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

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

        $structure = HrSalaryStructure::create($data);

        return $this->redirect('/hr/salary-structures/' . $structure->id)->withSuccess('تم إنشاء هيكل الرواتب بنجاح');
    }

    public function show(Request $request, string $id): Response
    {
        $structure = HrSalaryStructure::find((int) $id);
        if (!$structure) {
            return $this->redirect('/hr/salary-structures')->withError('هيكل الرواتب غير موجود');
        }

        $components = HrSalaryStructure::getComponents((int) $id);

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

        $earnings = [];
        $deductions = [];
        foreach ($components as $comp) {
            if ($comp['type'] === 'earning') {
                $earnings[] = $comp;
            } else {
                $deductions[] = $comp;
            }
        }

        return $this->view('HR.Views.salary_structures.show', [
            'structure'     => $structure,
            'earnings'      => $earnings,
            'deductions'    => $deductions,
            'employeeCount' => (int) ($employeeCount['cnt'] ?? 0),
        ]);
    }

    public function edit(Request $request, string $id): Response
    {
        $structure = HrSalaryStructure::find((int) $id);
        if (!$structure) {
            return $this->redirect('/hr/salary-structures')->withError('هيكل الرواتب غير موجود');
        }

        $components = HrSalaryStructure::getComponents((int) $id);

        return $this->view('HR.Views.salary_structures.form', [
            'structure'  => $structure,
            'components' => $components,
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $structure = HrSalaryStructure::find((int) $id);
        if (!$structure) {
            return $this->redirect('/hr/salary-structures')->withError('هيكل الرواتب غير موجود');
        }

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

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

        $structure->update($data);

        return $this->redirect('/hr/salary-structures/' . $id)->withSuccess('تم تحديث هيكل الرواتب بنجاح');
    }

    public function updateComponents(Request $request, string $id): Response
    {
        $structure = HrSalaryStructure::find((int) $id);
        if (!$structure) {
            return $this->redirect('/hr/salary-structures')->withError('هيكل الرواتب غير موجود');
        }

        $db = App::getInstance()->db();
        $employee = $this->currentEmployee();
        $componentsData = $request->post('components', []);

        if (!is_array($componentsData)) {
            return $this->redirect('/hr/salary-structures/' . $id)->withError('بيانات المكونات غير صالحة');
        }

        $db->beginTransaction();
        try {
            // Update existing components
            foreach ($componentsData as $compId => $compData) {
                if (str_starts_with((string) $compId, 'new_')) {
                    // New component
                    $name = trim((string) ($compData['name_ar'] ?? ''));
                    if ($name === '') {
                        continue;
                    }
                    $db->insert('hr_salary_components', [
                        'structure_id'        => (int) $id,
                        'name_ar'             => $name,
                        'name_en'             => trim((string) ($compData['name_en'] ?? '')) ?: null,
                        'component_code'      => strtoupper(trim((string) ($compData['component_code'] ?? ''))),
                        'type'                => trim((string) ($compData['type'] ?? 'earning')),
                        'calculation_type'    => trim((string) ($compData['calculation_type'] ?? 'fixed')),
                        'default_amount'      => trim((string) ($compData['default_amount'] ?? '0.00')),
                        'percentage_of'       => trim((string) ($compData['percentage_of'] ?? '')) ?: null,
                        'is_taxable'          => (int) ($compData['is_taxable'] ?? 0),
                        'is_insurable'        => (int) ($compData['is_insurable'] ?? 0),
                        'sort_order'          => (int) ($compData['sort_order'] ?? 0),
                        'is_active'           => 1,
                        'created_at'          => date('Y-m-d H:i:s'),
                        'updated_at'          => date('Y-m-d H:i:s'),
                        'created_by'          => $employee ? (int) $employee->id : null,
                    ]);
                } else {
                    // Existing component
                    $db->update('hr_salary_components', [
                        'name_ar'          => trim((string) ($compData['name_ar'] ?? '')),
                        'name_en'          => trim((string) ($compData['name_en'] ?? '')) ?: null,
                        'type'             => trim((string) ($compData['type'] ?? 'earning')),
                        'calculation_type' => trim((string) ($compData['calculation_type'] ?? 'fixed')),
                        'default_amount'   => trim((string) ($compData['default_amount'] ?? '0.00')),
                        'percentage_of'    => trim((string) ($compData['percentage_of'] ?? '')) ?: null,
                        'is_taxable'       => (int) ($compData['is_taxable'] ?? 0),
                        'is_insurable'     => (int) ($compData['is_insurable'] ?? 0),
                        'sort_order'       => (int) ($compData['sort_order'] ?? 0),
                        'is_active'        => (int) ($compData['is_active'] ?? 1),
                        'updated_at'       => date('Y-m-d H:i:s'),
                        'updated_by'       => $employee ? (int) $employee->id : null,
                    ], '`id` = ? AND `structure_id` = ?', [(int) $compId, (int) $id]);
                }
            }

            $db->commit();

            return $this->redirect('/hr/salary-structures/' . $id)->withSuccess('تم تحديث مكونات الهيكل بنجاح');

        } catch (\Throwable $e) {
            $db->rollBack();
            return $this->redirect('/hr/salary-structures/' . $id)->withError('فشل تحديث المكونات: ' . $e->getMessage());
        }
    }

    private function extractData(Request $request): array
    {
        return [
            'name_ar'     => trim((string) $request->post('name_ar', '')),
            'name_en'     => trim((string) $request->post('name_en', '')) ?: null,
            'code'        => strtoupper(trim((string) $request->post('code', ''))),
            'description' => trim((string) $request->post('description', '')) ?: null,
            'is_default'  => (int) ($request->post('is_default', 0)),
            '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['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);
    }
}
