<?php

class StockController extends Controller
{
    public function index(): void
    {
        Auth::requirePermission('stock', 'view');

        $materialModel = new RawMaterial();
        $materials = $materialModel->allOrdered();
        $consumptionMap = $materialModel->consumptionMap(14);

        // Compute a "days of stock left" prediction for every active material
        foreach ($materials as &$m) {
            $avgDaily = $consumptionMap[$m['id']] ?? 0;
            $m['avg_daily_use'] = $avgDaily;
            $m['days_left'] = $avgDaily > 0 ? round((float) $m['current_stock'] / $avgDaily, 1) : null;
        }
        unset($m);

        $historyByMaterial = [];
        foreach ($materials as $m) {
            $historyByMaterial[$m['id']] = $materialModel->transactionsFor((int) $m['id'], 30);
        }

        // --- Smart Alerts ---
        $stats = $materialModel->stats();
        $staleMaterials = $materialModel->staleMaterials(30);
        $runningOutSoon = array_filter($materials, fn($m) => $m['is_active'] && $m['days_left'] !== null && $m['days_left'] <= 3 && $m['current_stock'] > 0);

        $alerts = [];
        if ((int) $stats['expired'] > 0) {
            $alerts[] = ['icon' => 'fa-triangle-exclamation', 'color' => 'red', 'text' => (int) $stats['expired'] . " material(s) EXPIRED — remove from stock"];
        }
        if ((int) $stats['out_of_stock'] > 0) {
            $alerts[] = ['icon' => 'fa-ban', 'color' => 'red', 'text' => (int) $stats['out_of_stock'] . " material(s) completely out of stock"];
        }
        if ((int) $stats['expiring_soon'] > 0) {
            $alerts[] = ['icon' => 'fa-clock', 'color' => 'gold', 'text' => (int) $stats['expiring_soon'] . " material(s) expiring within 30 days"];
        }
        if (count($runningOutSoon) > 0) {
            $alerts[] = ['icon' => 'fa-hourglass-half', 'color' => 'gold', 'text' => count($runningOutSoon) . " material(s) predicted to run out within 3 days"];
        }
        if ((int) $stats['low_stock'] > 0) {
            $alerts[] = ['icon' => 'fa-arrow-down-wide-short', 'color' => 'gold', 'text' => (int) $stats['low_stock'] . " material(s) at/below reorder level"];
        }
        if (count($staleMaterials) > 0) {
            $alerts[] = ['icon' => 'fa-box-archive', 'color' => 'blue', 'text' => count($staleMaterials) . " material(s) with no movement in 30 days — possible dead stock"];
        }

        $trend = $materialModel->topConsumedTrend(7, 5);
        $allMovements = $materialModel->recentMovementsAll(60);

        $this->view('stock.index', [
            'pageTitle'         => 'Stock / Raw Materials',
            'materials'         => $materials,
            'historyByMaterial' => $historyByMaterial,
            'stats'             => $stats,
            'alerts'            => $alerts,
            'trendLabels'       => $trend['labels'],
            'trendDatasets'     => $trend['datasets'],
            'allMovements'      => $allMovements,
            'csrf'              => $this->csrfField(),
        ]);
    }

    public function store(): void
    {
        Auth::requirePermission('stock', 'add');
        $this->verifyCsrf();

        $name = trim($this->input('material_name', ''));
        $unit = trim($this->input('unit', ''));
        if ($name === '' || $unit === '') {
            $this->redirect('stock');
            return;
        }

        $materialModel = new RawMaterial();
        $materialModel->insert([
            'material_name'  => $name,
            'unit'           => $unit,
            'current_stock'  => (float) $this->input('opening_stock', 0),
            'reorder_level'  => (float) $this->input('reorder_level', 0),
            'unit_cost'      => (float) $this->input('unit_cost', 0),
            'expiry_date'    => $this->input('expiry_date', '') ?: null,
            'is_active'      => 1,
        ]);

        AuditLogger::log(Auth::id(), 'STOCK_MATERIAL_CREATE', 'stock', "Added raw material: {$name}");
        $this->redirect('stock');
    }

    public function update(): void
    {
        Auth::requirePermission('stock', 'edit');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $materialModel = new RawMaterial();
        $existing = $materialModel->find($id);
        if (!$existing) {
            $this->redirect('stock');
            return;
        }

        $materialModel->update($id, [
            'material_name'  => trim($this->input('material_name', $existing['material_name'])),
            'unit'           => trim($this->input('unit', $existing['unit'])),
            'reorder_level'  => (float) $this->input('reorder_level', $existing['reorder_level']),
            'unit_cost'      => (float) $this->input('unit_cost', $existing['unit_cost']),
            'expiry_date'    => $this->input('expiry_date', '') ?: null,
        ]);

        AuditLogger::log(Auth::id(), 'STOCK_MATERIAL_UPDATE', 'stock', "Updated raw material #{$id}");
        $this->redirect('stock');
    }

    public function toggle(): void
    {
        Auth::requirePermission('stock', 'edit');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $materialModel = new RawMaterial();
        $material = $materialModel->find($id);
        if ($material) {
            $materialModel->update($id, ['is_active' => $material['is_active'] ? 0 : 1]);
            AuditLogger::log(Auth::id(), 'STOCK_MATERIAL_TOGGLE', 'stock', "Material #{$id} active -> " . ($material['is_active'] ? '0' : '1'));
        }
        $this->redirect('stock');
    }

    public function delete(): void
    {
        Auth::requirePermission('stock', 'delete');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $materialModel = new RawMaterial();

        if ($materialModel->hasTransactions($id)) {
            // Preserve transaction history — deactivate instead of deleting
            $materialModel->update($id, ['is_active' => 0]);
            AuditLogger::log(Auth::id(), 'STOCK_MATERIAL_DEACTIVATE', 'stock', "Material #{$id} has transaction history — deactivated instead of deleted");
        } else {
            $materialModel->delete($id);
            AuditLogger::log(Auth::id(), 'STOCK_MATERIAL_DELETE', 'stock', "Deleted raw material #{$id}");
        }
        $this->redirect('stock');
    }

    public function stockIn(): void
    {
        Auth::requirePermission('stock', 'edit');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $qty = (float) $this->input('quantity', 0);
        $unitCost = $this->input('unit_cost', '');
        $notes = trim($this->input('notes', ''));
        $expiryDate = $this->input('expiry_date', '') ?: null;

        if ($id > 0 && $qty > 0) {
            $materialModel = new RawMaterial();
            $materialModel->stockIn($id, $qty, $unitCost !== '' ? (float) $unitCost : null, Auth::id(), $notes, $expiryDate);
            AuditLogger::log(Auth::id(), 'STOCK_IN', 'stock', "Stock in: material #{$id}, qty {$qty}");
        }
        $this->redirect('stock');
    }

    public function adjust(): void
    {
        Auth::requirePermission('stock', 'edit');
        $this->verifyCsrf();

        $id = (int) $this->input('id');
        $direction = $this->input('direction', 'add'); // 'add' or 'remove'
        $type = $this->input('adjust_type', 'ADJUSTMENT'); // ADJUSTMENT or WASTAGE
        $qty = abs((float) $this->input('quantity', 0));
        $notes = trim($this->input('notes', ''));

        if ($id > 0 && $qty > 0) {
            $signedQty = $direction === 'remove' ? -$qty : $qty;
            $materialModel = new RawMaterial();
            $materialModel->adjust($id, $signedQty, $type, Auth::id(), $notes);
            AuditLogger::log(Auth::id(), 'STOCK_ADJUST', 'stock', "Adjusted material #{$id}: {$signedQty} ({$type})");
        }
        $this->redirect('stock');
    }
}
