<?php
declare(strict_types=1);

namespace App\Modules\Inventory\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Inventory\Models\ItemCategory;

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

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

        $tree = ItemCategory::getTree();
        $roots = ItemCategory::getRoots();

        return $this->view('Inventory.Views.categories.index', [
            'categories' => $result['data'],
            'pagination'  => $result['pagination'],
            'filters'     => $filters,
            'tree'        => $tree,
            'roots'       => $roots,
        ]);
    }

    public function create(Request $request): Response
    {
        $roots = ItemCategory::getRoots();

        return $this->view('Inventory.Views.categories.form', [
            'category' => null,
            'roots'    => $roots,
        ]);
    }

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

        // Unique code
        if ($data['code'] !== '') {
            $existing = ItemCategory::query()->where('code', '=', $data['code'])->first();
            if ($existing) {
                $errors[] = 'كود التصنيف مستخدم بالفعل';
            }
        }

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

        $category = ItemCategory::create($data);

        return $this->redirect('/inventory/categories')->withSuccess('تم إضافة التصنيف بنجاح');
    }

    public function edit(Request $request, string $id): Response
    {
        $category = ItemCategory::find((int) $id);
        if (!$category) {
            return $this->redirect('/inventory/categories')->withError('التصنيف غير موجود');
        }

        $roots = ItemCategory::getRoots();

        return $this->view('Inventory.Views.categories.form', [
            'category' => $category,
            'roots'    => $roots,
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $category = ItemCategory::find((int) $id);
        if (!$category) {
            return $this->redirect('/inventory/categories')->withError('التصنيف غير موجود');
        }

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

        // Unique code (exclude current)
        if ($data['code'] !== '') {
            $existing = ItemCategory::query()
                ->where('code', '=', $data['code'])
                ->whereRaw('`id` != ?', [(int) $id])
                ->first();
            if ($existing) {
                $errors[] = 'كود التصنيف مستخدم بالفعل';
            }
        }

        // Prevent self-parenting
        if ($data['parent_id'] !== null && (int) $data['parent_id'] === (int) $id) {
            $errors[] = 'لا يمكن أن يكون التصنيف أبًا لنفسه';
        }

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

        $category->update($data);

        return $this->redirect('/inventory/categories')->withSuccess('تم تحديث التصنيف بنجاح');
    }

    private function extractData(Request $request): array
    {
        return [
            'parent_id'      => ((int) $request->post('parent_id', 0)) ?: null,
            'code'           => strtoupper(trim((string) $request->post('code', ''))),
            'name_ar'        => trim((string) $request->post('name_ar', '')),
            'name_en'        => trim((string) $request->post('name_en', '')) ?: null,
            'description_ar' => trim((string) $request->post('description_ar', '')) ?: null,
            'sort_order'     => (int) $request->post('sort_order', 0),
            'is_active'      => (int) ($request->post('is_active', 1)),
        ];
    }

    private function validateInput(array $data): array
    {
        $errors = [];
        if ($data['code'] === '') {
            $errors[] = 'كود التصنيف مطلوب';
        }
        if ($data['name_ar'] === '' || mb_strlen($data['name_ar']) < 2) {
            $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);
    }
}
