<?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\StockMovement;
use App\Modules\Inventory\Models\InventoryItem;
use App\Modules\Inventory\Models\Warehouse;
use App\Modules\Inventory\Services\StockService;
use App\Modules\Inventory\Services\BatchService;

class StockMovementController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'warehouse_id'  => trim((string) $request->get('warehouse_id', '')),
            'movement_type' => trim((string) $request->get('movement_type', '')),
            'direction'     => trim((string) $request->get('direction', '')),
            'date_from'     => trim((string) $request->get('date_from', '')),
            'date_to'       => trim((string) $request->get('date_to', '')),
        ];

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

        return $this->view('Inventory.Views.stock.movements', [
            'movements'     => $result['data'],
            'pagination'    => $result['pagination'],
            'filters'       => $filters,
            'warehouses'    => Warehouse::allActive(),
            'movementTypes' => StockMovement::getMovementTypes(),
        ]);
    }

    public function create(Request $request): Response
    {
        return $this->view('Inventory.Views.stock.movement_form', [
            'warehouses' => Warehouse::allActive(),
            'items'      => InventoryItem::allActive(),
        ]);
    }

    public function store(Request $request): Response
    {
        $itemId      = (int) $request->post('item_id', 0);
        $warehouseId = (int) $request->post('warehouse_id', 0);
        $direction   = trim((string) $request->post('direction', ''));
        $moveType    = trim((string) $request->post('movement_type', ''));
        $quantity    = trim((string) $request->post('quantity', ''));
        $unitCost    = trim((string) $request->post('unit_cost', ''));
        $notes       = trim((string) $request->post('notes', ''));
        $moveDate    = trim((string) $request->post('movement_date', date('Y-m-d')));

        // Batch fields for expiry items
        $batchNumber = trim((string) $request->post('batch_number', ''));
        $expiryDate  = trim((string) $request->post('expiry_date', ''));

        $errors = [];
        if ($itemId <= 0) $errors[] = 'يجب اختيار الصنف';
        if ($warehouseId <= 0) $errors[] = 'يجب اختيار المخزن';
        if (!in_array($direction, ['in', 'out'], true)) $errors[] = 'اتجاه الحركة غير صالح';
        if (bccomp($quantity, '0', 3) <= 0) $errors[] = 'الكمية يجب أن تكون أكبر من صفر';

        if (!empty($errors)) {
            $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('/inventory/movements/create');
        }

        try {
            $batchId = null;

            // Check if the item is expiry-tracked and direction is IN — create a batch
            $db = App::getInstance()->db();
            $item = $db->selectOne(
                "SELECT `tracking_type` FROM `inventory_items` WHERE `id` = ?",
                [$itemId]
            );

            if ($item && $item['tracking_type'] === 'expiry' && $direction === 'in') {
                if ($batchNumber === '' || $expiryDate === '') {
                    $session = App::getInstance()->session();
                    $session->flash('_alerts', [['type' => 'error', 'message' => 'رقم الدفعة وتاريخ الصلاحية مطلوبان للأصناف ذات تاريخ انتهاء']]);
                    $session->flash('_old_input', $request->all());
                    return $this->redirect('/inventory/movements/create');
                }

                $batchId = BatchService::createBatch([
                    'item_id'       => $itemId,
                    'warehouse_id'  => $warehouseId,
                    'batch_number'  => $batchNumber,
                    'expiry_date'   => $expiryDate,
                    'quantity'      => $quantity,
                    'unit_cost'     => $unitCost ?: null,
                    'received_date' => $moveDate,
                ]);
            }

            // For expiry OUT, use FEFO allocation
            if ($item && $item['tracking_type'] === 'expiry' && $direction === 'out') {
                $allocations = BatchService::allocateBatch($itemId, $warehouseId, $quantity);
                foreach ($allocations as $alloc) {
                    StockService::moveStock([
                        'item_id'       => $itemId,
                        'warehouse_id'  => $warehouseId,
                        'movement_type' => $moveType,
                        'direction'     => 'out',
                        'quantity'      => $alloc['quantity'],
                        'unit_cost'     => $unitCost ?: null,
                        'batch_id'      => $alloc['batch_id'],
                        'notes'         => $notes,
                        'movement_date' => $moveDate,
                    ]);
                }
                return $this->redirect('/inventory/movements')->withSuccess('تم تسجيل الحركة بنجاح');
            }

            StockService::moveStock([
                'item_id'       => $itemId,
                'warehouse_id'  => $warehouseId,
                'movement_type' => $moveType,
                'direction'     => $direction,
                'quantity'      => $quantity,
                'unit_cost'     => $unitCost ?: null,
                'batch_id'      => $batchId,
                'notes'         => $notes,
                'movement_date' => $moveDate,
            ]);

            return $this->redirect('/inventory/movements')->withSuccess('تم تسجيل الحركة بنجاح');
        } catch (\RuntimeException $e) {
            return $this->redirect('/inventory/movements/create')->withError($e->getMessage());
        }
    }
}
