<?php
class StockTakingController {
    public function index(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');

        $tid = Auth::tenantId();
        $page = (int)($_GET['page'] ?? 1) ?: 1;
        $stockTakings = StockTaking::listPaginated($page);

        $pageTitle = 'Stock Taking';
        ob_start();
        include APP_ROOT . '/views/tenant/stock_takings/index.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function create(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');

        $tid = Auth::tenantId();
        
        // Get locations for dropdown
        $stmt = db()->prepare("SELECT * FROM locations WHERE tenant_id = ? AND is_active = 1 ORDER BY name");
        $stmt->execute([$tid]);
        $locations = $stmt->fetchAll();

        // Get categories for filter
        $stmt = db()->prepare("SELECT * FROM categories WHERE tenant_id = ? AND is_active = 1 ORDER BY name");
        $stmt->execute([$tid]);
        $categories = $stmt->fetchAll();

        $pageTitle = 'New Stock Taking';
        ob_start();
        include APP_ROOT . '/views/tenant/stock_takings/create.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function start(): void {
        error_reporting(E_ALL);
        ini_set('display_errors', 1);
        
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');
        Security::checkCsrf();

        $tid = Auth::tenantId();
        $mode = $_POST['mode'] ?? 'item';
        $locationId = (int)($_POST['location_id'] ?? 0);
        $notes = $_POST['notes'] ?? null;

        if (empty($locationId)) {
            flash('error', 'Location is required');
            redirect('stock-takings/create');
            return;
        }

        try {
            $stockTakingId = StockTaking::createSession($mode, $locationId, $notes);
            redirect("stock-takings/count/{$stockTakingId}");
        } catch (Exception $e) {
            error_log('StockTaking start error: ' . $e->getMessage());
            flash('error', 'Failed to create stock taking session: ' . $e->getMessage());
            redirect('stock-takings/create');
        }
    }

    public function count(int $id): void {
        error_reporting(E_ALL);
        ini_set('display_errors', 1);
        
        try {
            Auth::requireLogin();
            Auth::requireActiveTenant();
            Auth::requirePermission('stock.adjust');

            $tid = Auth::tenantId();
            $stockTaking = StockTaking::find($id);

            if (!$stockTaking) {
                flash('error', 'Stock taking session not found');
                redirect('stock-takings');
                return;
            }

            if ($stockTaking['status'] === 'completed') {
                redirect("stock-takings/report/{$id}");
                return;
            }

            // Get products for stock taking
            $products = StockTaking::getProductsForStockTaking($id, $stockTaking['mode'], $stockTaking['location_id']);

            // Get already counted items
            $countedItems = StockTaking::getItems($id);
            $countedMap = [];
            foreach ($countedItems as $item) {
                $countedMap[$item['product_id']] = $item;
            }

            $pageTitle = 'Count Stock - ' . $stockTaking['reference'];
            ob_start();
            include APP_ROOT . '/views/tenant/stock_takings/count.php';
            $content = ob_get_clean();
            include APP_ROOT . '/views/tenant/layouts/main.php';
        } catch (Exception $e) {
            error_log('StockTaking count error: ' . $e->getMessage());
            error_log('Stack trace: ' . $e->getTraceAsString());
            echo '<h1>Error</h1>';
            echo '<p>' . htmlspecialchars($e->getMessage()) . '</p>';
            echo '<pre>' . htmlspecialchars($e->getTraceAsString()) . '</pre>';
            exit;
        }
    }

    public function save(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');
        Security::checkCsrf();

        $tid = Auth::tenantId();
        $stockTakingId = (int)($_POST['stock_taking_id'] ?? 0);
        $action = $_POST['action'] ?? 'save';

        if (empty($stockTakingId)) {
            flash('error', 'Invalid stock taking session');
            redirect('stock-takings');
            return;
        }

        $stockTaking = StockTaking::find($stockTakingId);
        if (!$stockTaking || $stockTaking['status'] === 'completed') {
            flash('error', 'Cannot modify completed stock taking');
            redirect('stock-takings');
            return;
        }

        try {
            // Save all counted items
            if (isset($_POST['items']) && is_array($_POST['items'])) {
                foreach ($_POST['items'] as $productId => $data) {
                    // Treat empty counted_qty as 0
                    $countedQty = (isset($data['counted_qty']) && $data['counted_qty'] !== '') ? (float)($data['counted_qty']) : 0;
                    $currentStock = (float)($data['current_stock'] ?? 0);
                    $categoryId = (int)($data['category_id'] ?? 0);
                    $unitCost = (float)($data['unit_cost'] ?? 0);

                    // Only save if counted qty is different from current stock
                    if ($countedQty != $currentStock) {
                        StockTaking::saveItem($stockTakingId, (int)$productId, $categoryId, $currentStock, $countedQty, $unitCost);
                    }
                }
            }

            if ($action === 'save') {
                flash('success', 'Stock count saved successfully');
                redirect("stock-takings/count/{$stockTakingId}");
            } elseif ($action === 'save_complete') {
                StockTaking::complete($stockTakingId);
                flash('success', 'Stock taking completed successfully');
                redirect("stock-takings/report/{$stockTakingId}");
            } elseif ($action === 'save_update') {
                StockTaking::complete($stockTakingId);
                StockTaking::updateStockFromCount($stockTakingId);
                flash('success', 'Stock taking completed and stock updated successfully');
                redirect("stock-takings/report/{$stockTakingId}");
            }
        } catch (Exception $e) {
            flash('error', 'Failed to save stock count: ' . $e->getMessage());
            redirect("stock-takings/count/{$stockTakingId}");
        }
    }

    public function report(int $id): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');

        $tid = Auth::tenantId();
        $stockTaking = StockTaking::find($id);

        if (!$stockTaking) {
            flash('error', 'Stock taking session not found');
            redirect('stock-takings');
            return;
        }

        $items = StockTaking::getItems($id);
        $summary = StockTaking::getSummary($id);

        $pageTitle = 'Stock Taking Report - ' . $stockTaking['reference'];
        ob_start();
        include APP_ROOT . '/views/tenant/stock_takings/report.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function view(int $id): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');

        $tid = Auth::tenantId();
        $stockTaking = StockTaking::find($id);

        if (!$stockTaking) {
            flash('error', 'Stock taking session not found');
            redirect('stock-takings');
            return;
        }

        $items = StockTaking::getItems($id);
        $summary = StockTaking::getSummary($id);

        $pageTitle = 'View Stock Taking - ' . $stockTaking['reference'];
        ob_start();
        include APP_ROOT . '/views/tenant/stock_takings/view.php';
        $content = ob_get_clean();
        include APP_ROOT . '/views/tenant/layouts/main.php';
    }

    public function delete(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requirePermission('stock.adjust');
        Security::checkCsrf();

        $tid = Auth::tenantId();
        $id = (int)($_POST['id'] ?? 0);

        try {
            $stockTaking = StockTaking::find($id);
            if (!$stockTaking) {
                flash('error', 'Stock taking not found');
                redirect('stock-takings');
                return;
            }

            // Note: We allow deleting completed sessions too, but the UI will warn if stock was updated

            // Delete the stock taking (cascade will delete items)
            $stmt = db()->prepare("DELETE FROM stock_takings WHERE id = ? AND tenant_id = ?");
            $stmt->execute([$id, $tid]);
            
            flash('success', 'Stock taking deleted successfully');
        } catch (Exception $e) {
            flash('error', 'Failed to delete stock taking: ' . $e->getMessage());
        }

        redirect('stock-takings');
    }

    public function updateStock(): void {
        Auth::requireLogin();
        Auth::requireActiveTenant();
        Auth::requireRole(['admin','owner']);
        Security::checkCsrf();

        $tid = Auth::tenantId();
        $id = (int)($_POST['id'] ?? 0);

        try {
            $stockTaking = StockTaking::find($id);
            if (!$stockTaking) {
                flash('error', 'Stock taking not found');
                redirect('stock-takings');
                return;
            }

            if ($stockTaking['status'] !== 'completed') {
                flash('error', 'Stock taking must be completed before updating stock');
                redirect('stock-takings');
                return;
            }

            if ($stockTaking['stock_updated'] == 1) {
                flash('error', 'Stock has already been updated for this stock taking');
                redirect("stock-takings/report/{$id}");
                return;
            }

            // Update stock from the count
            StockTaking::updateStockFromCount($id);
            flash('success', 'Stock updated successfully');
            redirect("stock-takings/report/{$id}");
        } catch (Exception $e) {
            flash('error', 'Failed to update stock: ' . $e->getMessage());
            redirect("stock-takings/report/{$id}");
        }
    }
}
