<?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\Services\StockService;

class OpeningBalanceController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('inventory.opening.manage');
        $db = App::getInstance()->db();

        $warehouseId = (int) $request->get('warehouse_id', 0);
        $where = '1=1';
        $params = [];

        if ($warehouseId) {
            $where .= ' AND ob.warehouse_id = ?';
            $params[] = $warehouseId;
        }

        $balances = $db->select(
            "SELECT ob.*, i.name_ar as item_name, i.sku, w.name_ar as warehouse_name
             FROM inventory_opening_balances ob
             JOIN inventory_items i ON i.id = ob.item_id
             JOIN warehouses w ON w.id = ob.warehouse_id
             WHERE {$where}
             ORDER BY ob.balance_date DESC, ob.created_at DESC
             LIMIT 200",
            $params
        );

        $warehouses = $db->select("SELECT id, name_ar FROM warehouses WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('Inventory.Views.opening_balance.index', [
            'balances' => $balances,
            'warehouses' => $warehouses,
            'warehouse_id' => $warehouseId,
        ]);
    }

    public function create(Request $request): Response
    {
        $this->authorize('inventory.opening.manage');
        $db = App::getInstance()->db();

        $warehouses = $db->select("SELECT id, name_ar FROM warehouses WHERE is_archived = 0 ORDER BY name_ar");
        $items = $db->select("SELECT id, name_ar, sku FROM inventory_items WHERE is_archived = 0 ORDER BY name_ar");

        return $this->view('Inventory.Views.opening_balance.form', [
            'warehouses' => $warehouses,
            'items' => $items,
        ]);
    }

    public function store(Request $request): Response
    {
        $this->authorize('inventory.opening.manage');
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

        $warehouseId = (int) $request->post('warehouse_id');
        $balanceDate = $request->post('balance_date', date('Y-m-d'));
        $batchReference = 'OB-' . date('Ymd-His');

        $itemIds = $request->post('item_ids', []);
        $quantities = $request->post('quantities', []);
        $unitCosts = $request->post('unit_costs', []);

        $count = 0;
        $db->beginTransaction();
        try {
            for ($i = 0; $i < count($itemIds); $i++) {
                $itemId = (int) ($itemIds[$i] ?? 0);
                $qty = (string) ($quantities[$i] ?? '0');
                $unitCost = (string) ($unitCosts[$i] ?? '0');

                if ($itemId <= 0 || bccomp($qty, '0', 3) <= 0) continue;

                $totalCost = bcmul($qty, $unitCost, 2);

                $movementId = StockService::moveStock([
                    'item_id' => $itemId,
                    'warehouse_id' => $warehouseId,
                    'movement_type' => 'opening_balance',
                    'direction' => 'in',
                    'quantity' => $qty,
                    'unit_cost' => $unitCost,
                    'reference_type' => 'inventory_opening_balances',
                    'notes' => 'رصيد افتتاحي — ' . $batchReference,
                    'movement_date' => $balanceDate,
                ]);

                $db->insert('inventory_opening_balances', [
                    'warehouse_id' => $warehouseId,
                    'item_id' => $itemId,
                    'quantity' => $qty,
                    'unit_cost' => $unitCost,
                    'total_cost' => $totalCost,
                    'balance_date' => $balanceDate,
                    'batch_reference' => $batchReference,
                    'stock_movement_id' => $movementId,
                    'created_by' => $employee ? (int) $employee->id : null,
                ]);

                $count++;
            }

            $db->commit();
            return $this->redirect('/inventory/opening-balances')->withSuccess("تم تسجيل الأرصدة الافتتاحية بنجاح — {$count} صنف");
        } catch (\Throwable $e) {
            $db->rollBack();
            return $this->redirect('/inventory/opening-balances/create')->withError('خطأ: ' . $e->getMessage());
        }
    }
}
