<?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\Warehouse;

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

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

        return $this->view('Inventory.Views.warehouses.index', [
            'warehouses'     => $result['data'],
            'pagination'     => $result['pagination'],
            'filters'        => $filters,
            'warehouseTypes' => Warehouse::getTypes(),
        ]);
    }

    public function create(Request $request): Response
    {
        $db = App::getInstance()->db();
        $employees = $db->select(
            "SELECT `id`, `full_name_ar` FROM `employees` WHERE `is_active` = 1 ORDER BY `full_name_ar` ASC"
        );

        return $this->view('Inventory.Views.warehouses.form', [
            'warehouse'      => null,
            'warehouseTypes' => Warehouse::getTypes(),
            'employees'      => $employees,
        ]);
    }

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

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

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

        $warehouse = Warehouse::create($data);

        return $this->redirect('/inventory/warehouses/' . $warehouse->id)->withSuccess('تم إضافة المخزن بنجاح');
    }

    public function show(Request $request, string $id): Response
    {
        $warehouse = Warehouse::find((int) $id);
        if (!$warehouse) {
            return $this->redirect('/inventory/warehouses')->withError('المخزن غير موجود');
        }

        $db = App::getInstance()->db();
        $keeper = $warehouse->keeper_employee_id
            ? $db->selectOne("SELECT `id`, `full_name_ar` FROM `employees` WHERE `id` = ?", [(int) $warehouse->keeper_employee_id])
            : null;

        // Stock summary in this warehouse
        $stockSummary = $db->select(
            "SELECT iws.*, i.`name_ar`, i.`sku`, i.`unit_of_measure`
             FROM `item_warehouse_stock` iws
             JOIN `inventory_items` i ON i.`id` = iws.`item_id`
             WHERE iws.`warehouse_id` = ?
             ORDER BY i.`name_ar` ASC",
            [(int) $id]
        );

        return $this->view('Inventory.Views.warehouses.show', [
            'warehouse'      => $warehouse,
            'keeper'         => $keeper,
            'stockSummary'   => $stockSummary,
            'warehouseTypes' => Warehouse::getTypes(),
        ]);
    }

    public function edit(Request $request, string $id): Response
    {
        $warehouse = Warehouse::find((int) $id);
        if (!$warehouse) {
            return $this->redirect('/inventory/warehouses')->withError('المخزن غير موجود');
        }

        $db = App::getInstance()->db();
        $employees = $db->select(
            "SELECT `id`, `full_name_ar` FROM `employees` WHERE `is_active` = 1 ORDER BY `full_name_ar` ASC"
        );

        return $this->view('Inventory.Views.warehouses.form', [
            'warehouse'      => $warehouse,
            'warehouseTypes' => Warehouse::getTypes(),
            'employees'      => $employees,
        ]);
    }

    public function update(Request $request, string $id): Response
    {
        $warehouse = Warehouse::find((int) $id);
        if (!$warehouse) {
            return $this->redirect('/inventory/warehouses')->withError('المخزن غير موجود');
        }

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

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

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

        $warehouse->update($data);

        return $this->redirect('/inventory/warehouses/' . $id)->withSuccess('تم تحديث المخزن بنجاح');
    }

    private function extractData(Request $request): array
    {
        return [
            'code'               => strtoupper(trim((string) $request->post('code', ''))),
            'name_ar'            => trim((string) $request->post('name_ar', '')),
            'name_en'            => trim((string) $request->post('name_en', '')) ?: null,
            'warehouse_type'     => trim((string) $request->post('warehouse_type', 'general')),
            'location_ar'        => trim((string) $request->post('location_ar', '')) ?: null,
            'keeper_employee_id' => ((int) $request->post('keeper_employee_id', 0)) ?: null,
            'capacity_units'     => ((int) $request->post('capacity_units', 0)) ?: null,
            'phone'              => trim((string) $request->post('phone', '')) ?: null,
            'is_active'          => (int) ($request->post('is_active', 1)),
            'notes'              => trim((string) $request->post('notes', '')) ?: null,
        ];
    }

    private function validate(array $data): array
    {
        $errors = [];
        if ($data['code'] === '') {
            $errors[] = 'كود المخزن مطلوب';
        }
        if ($data['name_ar'] === '' || mb_strlen($data['name_ar']) < 2) {
            $errors[] = 'اسم المخزن بالعربي مطلوب (حرفان على الأقل)';
        }
        if (!array_key_exists($data['warehouse_type'], Warehouse::getTypes())) {
            $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);
    }
}
