<?php
// Report all PHP errors
require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$pageTitle = 'Recipes / Menu Costings';

if (!function_exists('h')) {
    function h($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('money_fmt')) {
    function money_fmt($amount): string { return number_format((float)$amount, 2); }
}
if (!function_exists('recipe_flash')) {
    function recipe_flash(string $type, string $message): void {
        $_SESSION['recipes_flash'][] = ['type' => $type, 'message' => $message];
    }
}
if (!function_exists('recipe_get_flash')) {
    function recipe_get_flash(): array {
        $items = $_SESSION['recipes_flash'] ?? [];
        unset($_SESSION['recipes_flash']);
        return $items;
    }
}
if (!function_exists('recipe_table_exists')) {
    function recipe_table_exists(PDO $pdo, string $tableName): bool {
        static $cache = [];
        if (isset($cache[$tableName])) return $cache[$tableName];
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = :t");
        $stmt->execute([':t' => $tableName]);
        return $cache[$tableName] = ((int)$stmt->fetchColumn() > 0);
    }
}
if (!function_exists('recipe_column_exists')) {
    function recipe_column_exists(PDO $pdo, string $tableName, string $columnName): bool {
        static $cache = [];
        $key = $tableName . '.' . $columnName;
        if (isset($cache[$key])) return $cache[$key];
        $stmt = $pdo->prepare("SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = :t AND column_name = :c");
        $stmt->execute([':t' => $tableName, ':c' => $columnName]);
        return $cache[$key] = ((int)$stmt->fetchColumn() > 0);
    }
}
if (!function_exists('recipe_next_code')) {
    function recipe_next_code(PDO $pdo, string $prefix, string $name): string {
        $base = strtoupper(substr(preg_replace('/[^A-Za-z0-9]/', '', $name), 0, 3));
        if ($base === '') $base = 'ITM';
        do {
            $code = $prefix . '-' . $base . '-' . date('ymdHis') . '-' . random_int(100, 999);
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM inventory_items WHERE item_code = :code");
            $stmt->execute([':code' => $code]);
            $exists = (int)$stmt->fetchColumn() > 0;
        } while ($exists);
        return $code;
    }
}
if (!function_exists('recipe_current_user_id')) {
    function recipe_current_user_id(): ?int {
        foreach (['user_id','ss_user_id','id','uid','staffid'] as $key) {
            if (!empty($_SESSION[$key]) && (int)$_SESSION[$key] > 0) return (int)$_SESSION[$key];
        }
        return null;
    }
}
if (!function_exists('recipe_stock_balance')) {
    function recipe_stock_balance(PDO $pdo, int $itemId, int $storeId = 0): float {
        if (!recipe_table_exists($pdo, 'stock_movements')) return 0.0;
        $where = 'item_id = :item_id';
        $params = [':item_id' => $itemId];
        if ($storeId > 0) {
            $where .= ' AND store_id = :store_id';
            $params[':store_id'] = $storeId;
        }
        $stmt = $pdo->prepare("SELECT COALESCE(SUM(qty_in - qty_out),0) FROM stock_movements WHERE $where");
        $stmt->execute($params);
        return (float)$stmt->fetchColumn();
    }
}

if (!function_exists('recipe_menu_type')) {
    function recipe_menu_type(array $menu): string {
        $cat  = strtolower((string)($menu['category_path'] ?? $menu['category_name'] ?? ''));
        $name = strtolower((string)($menu['item_name'] ?? ''));

        if (strpos($cat, 'cocktail') !== false || strpos($name, 'cocktail') !== false) return 'cocktail';
        if (strpos($cat, 'mocktail') !== false || strpos($cat, 'virgin') !== false)    return 'mocktail';
        if (strpos($cat, 'bar')      !== false || strpos($cat, 'drink') !== false
         || strpos($cat, 'beverage') !== false)                                         return 'cocktail';
        if (strpos($cat, 'modifier') !== false)                                         return 'modifier';
        return 'food';
    }
}
if (!function_exists('recipe_existing_inventory_item_for_menu')) {
    function recipe_existing_inventory_item_for_menu(PDO $pdo, array $menuItem): ?int {
        // Kept only for backward compatibility. Recipes no longer require
        // or create an output inventory item.
        return null;
    }
}
$errors = [];

try {
    $pdo->exec("CREATE TABLE IF NOT EXISTS store_locations (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        location_code VARCHAR(50) NULL,
        location_name VARCHAR(150) NOT NULL,
        location_type ENUM('main_store','bar','restaurant','curio','kitchen','housekeeping','maintenance','other') NOT NULL DEFAULT 'main_store',
        is_pos_location TINYINT(1) NOT NULL DEFAULT 0,
        allow_room_charge TINYINT(1) NOT NULL DEFAULT 1,
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        notes TEXT NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uq_store_location_code (location_code)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_item_categories (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        category_name VARCHAR(120) NOT NULL,
        category_type ENUM('stock','food','bar','curio','consumable','service','other') NOT NULL DEFAULT 'stock',
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uq_inventory_category_name (category_name)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_units (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        unit_code VARCHAR(30) NOT NULL,
        unit_name VARCHAR(80) NOT NULL,
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        UNIQUE KEY uq_inventory_unit_code (unit_code)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $stmtUnitSeed = $pdo->prepare("INSERT IGNORE INTO inventory_units (unit_code, unit_name) VALUES (:code, :name)");
    foreach ([['EA','Each'],['KG','Kilogram'],['G','Gram'],['L','Litre'],['ML','Millilitre'],['BTL','Bottle'],['CAN','Can'],['PKT','Packet'],['BOX','Box'],['CASE','Case'],['TOT','Tot / Shot'],['SERVE','Serving'],['GLASS','Glass']] as $unit) {
        $stmtUnitSeed->execute([':code' => $unit[0], ':name' => $unit[1]]);
    }

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_items (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        item_code VARCHAR(60) NULL,
        item_name VARCHAR(180) NOT NULL,
        category_id INT UNSIGNED NULL,
        unit_id INT UNSIGNED NULL,
        item_type ENUM('stock','food','bar','curio','consumable','service','recipe','other') NOT NULL DEFAULT 'stock',
        barcode VARCHAR(100) NULL,
        description TEXT NULL,
        cost_price DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        avg_cost DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        selling_price DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        tax_rate DECIMAL(7,4) NOT NULL DEFAULT 0.0000,
        reorder_level DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        reorder_qty DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        is_stock_item TINYINT(1) NOT NULL DEFAULT 1,
        is_pos_item TINYINT(1) NOT NULL DEFAULT 0,
        allow_room_charge TINYINT(1) NOT NULL DEFAULT 1,
        track_expiry TINYINT(1) NOT NULL DEFAULT 0,
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uq_inventory_item_code (item_code),
        INDEX idx_inventory_item_name (item_name),
        INDEX idx_inventory_item_active (is_active)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS stock_movements (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        item_id INT UNSIGNED NOT NULL,
        store_id INT UNSIGNED NOT NULL,
        movement_type ENUM('OPENING','GRN','ISSUE','SALE','TRANSFER_IN','TRANSFER_OUT','ADJUSTMENT_IN','ADJUSTMENT_OUT','WASTAGE','RETURN') NOT NULL,
        qty_in DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        qty_out DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        unit_cost DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        total_cost DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        reference_type VARCHAR(60) NULL,
        reference_id BIGINT UNSIGNED NULL,
        notes TEXT NULL,
        movement_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_stock_item_store (item_id, store_id),
        INDEX idx_stock_reference (reference_type, reference_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS restaurant_menu_categories (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        property_id INT UNSIGNED NULL,
        parent_id INT UNSIGNED NULL,
        category_name VARCHAR(120) NOT NULL,
        slug VARCHAR(180) NULL,
        depth INT UNSIGNED NOT NULL DEFAULT 0,
        path VARCHAR(500) NULL,
        printer_role VARCHAR(60) NULL,
        sort_order INT NOT NULL DEFAULT 1,
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        INDEX idx_rest_cat_parent(parent_id),
        INDEX idx_rest_cat_active(is_active)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS restaurant_menu_items (
        id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        property_id INT UNSIGNED NULL,
        category_id INT UNSIGNED NULL,
        inventory_item_id INT UNSIGNED NULL,
        item_name VARCHAR(180) NOT NULL,
        item_code VARCHAR(60) NULL,
        description TEXT NULL,
        price DECIMAL(14,2) NOT NULL DEFAULT 0.00,
        tax_rate DECIMAL(7,4) NOT NULL DEFAULT 0.0000,
        tags VARCHAR(255) NULL,
        button_color VARCHAR(30) NULL,
        printer_role VARCHAR(60) NULL,
        default_printer_id INT UNSIGNED NULL,
        is_food TINYINT(1) NOT NULL DEFAULT 0,
        is_bar TINYINT(1) NOT NULL DEFAULT 0,
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        sort_order INT NOT NULL DEFAULT 1,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        INDEX idx_rest_item_cat(category_id),
        INDEX idx_rest_item_active(is_active)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    if (!recipe_column_exists($pdo, 'restaurant_menu_items', 'inventory_item_id')) {
        $pdo->exec("ALTER TABLE restaurant_menu_items ADD COLUMN inventory_item_id INT UNSIGNED NULL AFTER category_id");
    }
    if (!recipe_column_exists($pdo, 'restaurant_menu_items', 'tags')) {
        $pdo->exec("ALTER TABLE restaurant_menu_items ADD COLUMN tags VARCHAR(255) NULL AFTER tax_rate");
    }
    if (!recipe_column_exists($pdo, 'restaurant_menu_items', 'button_color')) {
        $pdo->exec("ALTER TABLE restaurant_menu_items ADD COLUMN button_color VARCHAR(30) NULL AFTER tags");
    }
    if (!recipe_column_exists($pdo, 'restaurant_menu_categories', 'parent_id')) {
        $pdo->exec("ALTER TABLE restaurant_menu_categories ADD COLUMN parent_id INT UNSIGNED NULL AFTER property_id");
    }
    if (!recipe_column_exists($pdo, 'restaurant_menu_categories', 'depth')) {
        $pdo->exec("ALTER TABLE restaurant_menu_categories ADD COLUMN depth INT UNSIGNED NOT NULL DEFAULT 0 AFTER category_name");
    }

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_recipes (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        restaurant_menu_item_id INT UNSIGNED NULL,
        recipe_item_id INT UNSIGNED NULL,
        recipe_category_id INT UNSIGNED NULL,
        recipe_type ENUM('food','cocktail','mocktail','modifier','prep','other') NOT NULL DEFAULT 'food',
        recipe_name VARCHAR(180) NOT NULL,
        yield_qty DECIMAL(14,4) NOT NULL DEFAULT 1.0000,
        default_store_id INT UNSIGNED NULL,
        preparation_notes TEXT NULL,
        cost_per_portion DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        selling_price DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        is_active TINYINT(1) NOT NULL DEFAULT 1,
        created_by INT UNSIGNED NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        UNIQUE KEY uq_recipe_item (recipe_item_id),
        UNIQUE KEY uq_recipe_menu_item (restaurant_menu_item_id),
        INDEX idx_recipe_menu_category (recipe_category_id),
        INDEX idx_recipe_type (recipe_type),
        INDEX idx_recipe_active (is_active)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $recipeAlters = [
        'restaurant_menu_item_id' => "ALTER TABLE inventory_recipes ADD COLUMN restaurant_menu_item_id INT UNSIGNED NULL AFTER id",
        'recipe_category_id' => "ALTER TABLE inventory_recipes ADD COLUMN recipe_category_id INT UNSIGNED NULL AFTER recipe_item_id",
        'recipe_type' => "ALTER TABLE inventory_recipes ADD COLUMN recipe_type ENUM('food','cocktail','mocktail','modifier','prep','other') NOT NULL DEFAULT 'food' AFTER recipe_category_id",
        'cost_per_portion' => "ALTER TABLE inventory_recipes ADD COLUMN cost_per_portion DECIMAL(14,4) NOT NULL DEFAULT 0.0000 AFTER preparation_notes",
        'selling_price' => "ALTER TABLE inventory_recipes ADD COLUMN selling_price DECIMAL(14,4) NOT NULL DEFAULT 0.0000 AFTER cost_per_portion",
    ];
    foreach ($recipeAlters as $col => $sql) {
        if (!recipe_column_exists($pdo, 'inventory_recipes', $col)) {
            $pdo->exec($sql);
        }
    }

    // Recipes are linked directly to restaurant_menu_items.
    // A separate output inventory item is no longer required.
    try {
        $pdo->exec("ALTER TABLE inventory_recipes MODIFY recipe_item_id INT UNSIGNED NULL");
    } catch (Throwable $ignored) {}

    try { $pdo->exec("ALTER TABLE inventory_recipes ADD UNIQUE KEY uq_recipe_menu_item (restaurant_menu_item_id)"); } catch (Throwable $ignored) {}
    try { $pdo->exec("ALTER TABLE inventory_recipes ADD INDEX idx_recipe_menu_category (recipe_category_id)"); } catch (Throwable $ignored) {}
    try { $pdo->exec("ALTER TABLE inventory_recipes ADD INDEX idx_recipe_type (recipe_type)"); } catch (Throwable $ignored) {}

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_recipe_lines (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        recipe_id BIGINT UNSIGNED NOT NULL,
        ingredient_item_id INT UNSIGNED NOT NULL,
        qty_required DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        wastage_percent DECIMAL(7,4) NOT NULL DEFAULT 0.0000,
        notes TEXT NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_recipe_line_recipe (recipe_id),
        INDEX idx_recipe_line_ingredient (ingredient_item_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");

    $pdo->exec("CREATE TABLE IF NOT EXISTS inventory_recipe_cost_logs (
        id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        recipe_id BIGINT UNSIGNED NOT NULL,
        cost_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        total_cost DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        selling_price DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        gross_profit DECIMAL(14,4) NOT NULL DEFAULT 0.0000,
        margin_percent DECIMAL(7,4) NOT NULL DEFAULT 0.0000,
        created_by INT UNSIGNED NULL,
        created_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX idx_recipe_cost_recipe (recipe_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
} catch (Throwable $e) {
    $errors[] = 'Could not prepare recipe tables: ' . $e->getMessage();
}

if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    try {
        if (function_exists('verify_csrf')) verify_csrf();
        $action = (string)($_POST['action'] ?? '');

        if ($action === 'save_recipe') {
            $recipeId = (int)($_POST['recipe_id'] ?? 0);
            $menuItemId = (int)($_POST['restaurant_menu_item_id'] ?? 0);
            $recipeName = trim((string)($_POST['recipe_name'] ?? ''));
            $recipeType = trim((string)($_POST['recipe_type'] ?? 'food'));
            $yieldQty = (float)($_POST['yield_qty'] ?? 1);
            $defaultStoreId = (int)($_POST['default_store_id'] ?? 0);
            $preparationNotes = trim((string)($_POST['preparation_notes'] ?? ''));
            $isActive = isset($_POST['is_active']) ? 1 : 0;

            $ingredientIds = $_POST['ingredient_item_id'] ?? [];
            $qtyRequired = $_POST['qty_required'] ?? [];
            $wastagePercents = $_POST['wastage_percent'] ?? [];
            $lineNotes = $_POST['line_notes'] ?? [];

            if ($menuItemId <= 0) throw new RuntimeException('Please select the restaurant menu item sold in POS.');
            if ($recipeName === '') throw new RuntimeException('Recipe name is required.');
            if ($yieldQty <= 0) throw new RuntimeException('Yield quantity must be greater than zero.');
            if (!in_array($recipeType, ['food','cocktail','mocktail','modifier','prep','other'], true)) $recipeType = 'food';

            $stmt = $pdo->prepare("SELECT mi.*, c.category_name, c.parent_id, c.path AS category_path
                FROM restaurant_menu_items mi
                LEFT JOIN restaurant_menu_categories c ON c.id = mi.category_id
                WHERE mi.id = :id AND mi.is_active = 1
                LIMIT 1");
            $stmt->execute([':id' => $menuItemId]);
            $menuItem = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$menuItem) throw new RuntimeException('Restaurant menu item was not found or is inactive.');

            /*
             * The recipe is identified entirely by restaurant_menu_item_id.
             * Do not use the menu item's direct inventory link as the recipe
             * output item; that inventory item may also legitimately appear
             * as an ingredient.
             */
            $recipeItemId = null;
            $recipeCategoryId = !empty($menuItem['category_id']) ? (int)$menuItem['category_id'] : null;
            $menuSellingPrice = (float)($menuItem['price'] ?? 0);

            $lines = [];
            $recipeTotalCost = 0.0;
            foreach ($ingredientIds as $idx => $ingredientIdRaw) {
                $ingredientId = (int)$ingredientIdRaw;
                $qty = (float)($qtyRequired[$idx] ?? 0);
                $waste = (float)($wastagePercents[$idx] ?? 0);
                $note = trim((string)($lineNotes[$idx] ?? ''));

                if ($ingredientId <= 0 && $qty <= 0) continue;
                if ($ingredientId <= 0) throw new RuntimeException('One recipe line is missing an ingredient.');
                
                if ($qty <= 0) throw new RuntimeException('Ingredient quantity must be greater than zero.');
                if ($waste < 0) throw new RuntimeException('Wastage percentage cannot be negative.');

                $stmt = $pdo->prepare("SELECT * FROM inventory_items WHERE id = :id AND is_active = 1 LIMIT 1");
                $stmt->execute([':id' => $ingredientId]);
                $ingredient = $stmt->fetch(PDO::FETCH_ASSOC);
                if (!$ingredient) throw new RuntimeException('Invalid or inactive ingredient selected: ' . $ingredientId);

                $effectiveQty = $qty + ($qty * ($waste / 100));
                $cost = (float)(($ingredient['avg_cost'] ?? 0) ?: ($ingredient['cost_price'] ?? 0));
                $recipeTotalCost += $effectiveQty * $cost;

                $lines[] = [
                    'ingredient_item_id' => $ingredientId,
                    'qty_required' => $qty,
                    'wastage_percent' => $waste,
                    'notes' => $note !== '' ? $note : null,
                ];
            }
            if (!$lines) throw new RuntimeException('Please add at least one recipe ingredient.');

            $costPerPortion = $yieldQty > 0 ? round($recipeTotalCost / $yieldQty, 4) : 0;

            $pdo->beginTransaction();

            if ($recipeId > 0) {
                $stmt = $pdo->prepare("UPDATE inventory_recipes
                    SET restaurant_menu_item_id = :restaurant_menu_item_id,
                        recipe_item_id = :recipe_item_id,
                        recipe_category_id = :recipe_category_id,
                        recipe_type = :recipe_type,
                        recipe_name = :recipe_name,
                        yield_qty = :yield_qty,
                        default_store_id = :default_store_id,
                        preparation_notes = :preparation_notes,
                        cost_per_portion = :cost_per_portion,
                        selling_price = :selling_price,
                        is_active = :is_active
                    WHERE id = :id");
                $stmt->execute([
                    ':restaurant_menu_item_id' => $menuItemId,
                    ':recipe_item_id' => $recipeItemId,
                    ':recipe_category_id' => $recipeCategoryId,
                    ':recipe_type' => $recipeType,
                    ':recipe_name' => $recipeName,
                    ':yield_qty' => $yieldQty,
                    ':default_store_id' => $defaultStoreId > 0 ? $defaultStoreId : null,
                    ':preparation_notes' => $preparationNotes !== '' ? $preparationNotes : null,
                    ':cost_per_portion' => $costPerPortion,
                    ':selling_price' => $menuSellingPrice,
                    ':is_active' => $isActive,
                    ':id' => $recipeId,
                ]);
                $stmt = $pdo->prepare("DELETE FROM inventory_recipe_lines WHERE recipe_id = :id");
                $stmt->execute([':id' => $recipeId]);
            } else {
                $stmt = $pdo->prepare("INSERT INTO inventory_recipes
                    (restaurant_menu_item_id, recipe_item_id, recipe_category_id, recipe_type, recipe_name, yield_qty, default_store_id, preparation_notes, cost_per_portion, selling_price, is_active, created_by)
                    VALUES
                    (:restaurant_menu_item_id, :recipe_item_id, :recipe_category_id, :recipe_type, :recipe_name, :yield_qty, :default_store_id, :preparation_notes, :cost_per_portion, :selling_price, :is_active, :created_by)
                    ON DUPLICATE KEY UPDATE
                        recipe_item_id = VALUES(recipe_item_id),
                        recipe_category_id = VALUES(recipe_category_id),
                        recipe_type = VALUES(recipe_type),
                        recipe_name = VALUES(recipe_name),
                        yield_qty = VALUES(yield_qty),
                        default_store_id = VALUES(default_store_id),
                        preparation_notes = VALUES(preparation_notes),
                        cost_per_portion = VALUES(cost_per_portion),
                        selling_price = VALUES(selling_price),
                        is_active = VALUES(is_active)");
                $stmt->execute([
                    ':restaurant_menu_item_id' => $menuItemId,
                    ':recipe_item_id' => $recipeItemId,
                    ':recipe_category_id' => $recipeCategoryId,
                    ':recipe_type' => $recipeType,
                    ':recipe_name' => $recipeName,
                    ':yield_qty' => $yieldQty,
                    ':default_store_id' => $defaultStoreId > 0 ? $defaultStoreId : null,
                    ':preparation_notes' => $preparationNotes !== '' ? $preparationNotes : null,
                    ':cost_per_portion' => $costPerPortion,
                    ':selling_price' => $menuSellingPrice,
                    ':is_active' => $isActive,
                    ':created_by' => recipe_current_user_id(),
                ]);
                if ((int)$pdo->lastInsertId() > 0) {
                    $recipeId = (int)$pdo->lastInsertId();
                } else {
                    $stmt = $pdo->prepare("SELECT id FROM inventory_recipes WHERE restaurant_menu_item_id = :id LIMIT 1");
                    $stmt->execute([':id' => $menuItemId]);
                    $recipeId = (int)$stmt->fetchColumn();
                    $pdo->prepare("DELETE FROM inventory_recipe_lines WHERE recipe_id = :id")->execute([':id' => $recipeId]);
                }
            }

            $stmt = $pdo->prepare("INSERT INTO inventory_recipe_lines
                (recipe_id, ingredient_item_id, qty_required, wastage_percent, notes)
                VALUES
                (:recipe_id, :ingredient_item_id, :qty_required, :wastage_percent, :notes)");
            foreach ($lines as $line) {
                $stmt->execute([
                    ':recipe_id' => $recipeId,
                    ':ingredient_item_id' => $line['ingredient_item_id'],
                    ':qty_required' => $line['qty_required'],
                    ':wastage_percent' => $line['wastage_percent'],
                    ':notes' => $line['notes'],
                ]);
            }

            // Ingredient deduction is controlled by inventory_recipe_lines.
            // Do not alter any inventory item classification here.
            $pdo->commit();
            recipe_flash('success', 'Recipe saved and linked to restaurant menu item successfully.');
            header('Location: recipes.php?view_id=' . $recipeId);
            exit;
        }

        if ($action === 'toggle_recipe') {
            $recipeId = (int)($_POST['recipe_id'] ?? 0);
            if ($recipeId <= 0) throw new RuntimeException('Invalid recipe selected.');
            $stmt = $pdo->prepare("UPDATE inventory_recipes SET is_active = CASE WHEN is_active = 1 THEN 0 ELSE 1 END WHERE id = :id");
            $stmt->execute([':id' => $recipeId]);
            recipe_flash('success', 'Recipe status updated.');
            header('Location: recipes.php');
            exit;
        }

        if ($action === 'delete_recipe') {
            $recipeId = (int)($_POST['recipe_id'] ?? 0);
            if ($recipeId <= 0) throw new RuntimeException('Invalid recipe selected.');
            $pdo->beginTransaction();
            $stmt = $pdo->prepare("DELETE FROM inventory_recipe_lines WHERE recipe_id = :id");
            $stmt->execute([':id' => $recipeId]);
            $stmt = $pdo->prepare("DELETE FROM inventory_recipes WHERE id = :id");
            $stmt->execute([':id' => $recipeId]);
            $pdo->commit();
            recipe_flash('warning', 'Recipe deleted.');
            header('Location: recipes.php');
            exit;
        }

        if ($action === 'log_cost') {
            $recipeId = (int)($_POST['recipe_id'] ?? 0);
            if ($recipeId <= 0) throw new RuntimeException('Invalid recipe selected.');
            $stmt = $pdo->prepare("SELECT r.*, mi.price AS menu_price FROM inventory_recipes r LEFT JOIN restaurant_menu_items mi ON mi.id = r.restaurant_menu_item_id WHERE r.id = :id LIMIT 1");
            $stmt->execute([':id' => $recipeId]);
            $recipe = $stmt->fetch(PDO::FETCH_ASSOC);
            if (!$recipe) throw new RuntimeException('Recipe not found.');

            $stmt = $pdo->prepare("SELECT rl.*, ii.avg_cost, ii.cost_price FROM inventory_recipe_lines rl INNER JOIN inventory_items ii ON ii.id = rl.ingredient_item_id WHERE rl.recipe_id = :recipe_id");
            $stmt->execute([':recipe_id' => $recipeId]);
            $total = 0;
            foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $line) {
                $effective = (float)$line['qty_required'] + ((float)$line['qty_required'] * ((float)$line['wastage_percent'] / 100));
                $cost = (float)(($line['avg_cost'] ?? 0) ?: ($line['cost_price'] ?? 0));
                $total += $effective * $cost;
            }
            $yield = max(1, (float)$recipe['yield_qty']);
            $costPerPortion = $total / $yield;
            $selling = (float)(($recipe['menu_price'] ?? 0) ?: ($recipe['selling_price'] ?? 0));
            $profit = $selling - $costPerPortion;
            $margin = $selling > 0 ? ($profit / $selling) * 100 : 0;

            $stmt = $pdo->prepare("INSERT INTO inventory_recipe_cost_logs (recipe_id,total_cost,selling_price,gross_profit,margin_percent,created_by) VALUES (:recipe_id,:total_cost,:selling_price,:gross_profit,:margin_percent,:created_by)");
            $stmt->execute([
                ':recipe_id' => $recipeId,
                ':total_cost' => $costPerPortion,
                ':selling_price' => $selling,
                ':gross_profit' => $profit,
                ':margin_percent' => $margin,
                ':created_by' => recipe_current_user_id(),
            ]);
            $pdo->prepare("UPDATE inventory_recipes SET cost_per_portion = :cost, selling_price = :selling WHERE id = :id")->execute([':cost' => $costPerPortion, ':selling' => $selling, ':id' => $recipeId]);
            recipe_flash('success', 'Cost snapshot logged.');
            header('Location: recipes.php?view_id=' . $recipeId);
            exit;
        }
    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        recipe_flash('danger', $e->getMessage());
        header('Location: recipes.php');
        exit;
    }
}

$stores = [];
$menuItems = [];
$ingredientItems = [];
$menuCategories = [];
$recipes = [];
$errorsLoad = [];

try {
    $stores = $pdo->query("SELECT * FROM store_locations WHERE is_active = 1 ORDER BY location_name ASC")->fetchAll(PDO::FETCH_ASSOC);

    $menuCategories = $pdo->query("SELECT c.*, p.category_name AS parent_category_name
        FROM restaurant_menu_categories c
        LEFT JOIN restaurant_menu_categories p ON p.id = c.parent_id
        WHERE c.is_active = 1
        ORDER BY COALESCE(p.category_name, c.category_name), c.depth, c.category_name")->fetchAll(PDO::FETCH_ASSOC);

    $menuItems = $pdo->query("SELECT
            mi.*,
            c.category_name,
            p.category_name AS parent_category_name,
            COALESCE(c.path, CONCAT_WS(' > ', p.category_name, c.category_name), c.category_name) AS category_path
        FROM restaurant_menu_items mi
        LEFT JOIN restaurant_menu_categories c ON c.id = mi.category_id
        LEFT JOIN restaurant_menu_categories p ON p.id = c.parent_id
        WHERE mi.is_active = 1
        ORDER BY COALESCE(p.category_name, c.category_name), c.category_name, mi.item_name")->fetchAll(PDO::FETCH_ASSOC);

    $ingredientItems = $pdo->query("SELECT ii.*, c.category_name, u.unit_code
        FROM inventory_items ii
        LEFT JOIN inventory_item_categories c ON c.id = ii.category_id
        LEFT JOIN inventory_units u ON u.id = ii.unit_id
        WHERE ii.is_active = 1
          AND ii.is_stock_item = 1
        ORDER BY c.category_name ASC, ii.item_name ASC")->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $e) {
    $errors[] = 'Could not load recipe form data: ' . $e->getMessage();
}

$editId = (int)($_GET['edit_id'] ?? 0);
$editRecipe = null;
$editLines = [];
if ($editId > 0) {
    try {
        $stmt = $pdo->prepare("SELECT * FROM inventory_recipes WHERE id = :id LIMIT 1");
        $stmt->execute([':id' => $editId]);
        $editRecipe = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
        if ($editRecipe) {
            $stmt = $pdo->prepare("SELECT * FROM inventory_recipe_lines WHERE recipe_id = :recipe_id ORDER BY id ASC");
            $stmt->execute([':recipe_id' => $editId]);
            $editLines = $stmt->fetchAll(PDO::FETCH_ASSOC);
        }
    } catch (Throwable $e) {
        $errors[] = 'Could not load recipe for edit: ' . $e->getMessage();
    }
}

/*
 * Persistent recipe filters
 * -------------------------
 * Search and filter selections remain active through edits, saves, status
 * changes, recipe views and page refreshes. They are cleared only when the
 * user explicitly selects Remove Filters.
 */
$recipeFilterSessionKey = 'recipes_filters';

if (isset($_GET['reset_recipe_filters']) && (string)$_GET['reset_recipe_filters'] === '1') {
    unset($_SESSION[$recipeFilterSessionKey]);
    header('Location: recipes.php');
    exit;
}

$recipeFilterKeys = ['status', 'category_id', 'recipe_type', 'q'];
$recipeFiltersSubmitted = false;

foreach ($recipeFilterKeys as $recipeFilterKey) {
    if (array_key_exists($recipeFilterKey, $_GET)) {
        $recipeFiltersSubmitted = true;
        break;
    }
}

if ($recipeFiltersSubmitted) {
    $savedRecipeFilters = [];
    foreach ($recipeFilterKeys as $recipeFilterKey) {
        $value = $_GET[$recipeFilterKey] ?? '';
        if (!is_array($value)) {
            $savedRecipeFilters[$recipeFilterKey] = trim((string)$value);
        }
    }
    $_SESSION[$recipeFilterSessionKey] = $savedRecipeFilters;
} elseif (!empty($_SESSION[$recipeFilterSessionKey]) && is_array($_SESSION[$recipeFilterSessionKey])) {
    foreach ($_SESSION[$recipeFilterSessionKey] as $recipeFilterKey => $value) {
        if (in_array($recipeFilterKey, $recipeFilterKeys, true)
            && !array_key_exists($recipeFilterKey, $_GET)) {
            $_GET[$recipeFilterKey] = (string)$value;
        }
    }
}

$status = trim((string)($_GET['status'] ?? ''));
$categoryId = (int)($_GET['category_id'] ?? 0);
$typeFilter = trim((string)($_GET['recipe_type'] ?? ''));
$search = trim((string)($_GET['q'] ?? ''));

$where = '1=1';
$params = [];
if ($status !== '') {
    $where .= ' AND r.is_active = :is_active';
    $params[':is_active'] = (int)$status;
}
if ($categoryId > 0) {
    $where .= ' AND mi.category_id = :category_id';
    $params[':category_id'] = $categoryId;
}
if ($typeFilter !== '') {
    $where .= ' AND r.recipe_type = :recipe_type';
    $params[':recipe_type'] = $typeFilter;
}
if ($search !== '') {
    $where .= " AND (
        r.recipe_name LIKE :q_recipe_name
        OR mi.item_name LIKE :q_menu_item
        OR mi.item_code LIKE :q_menu_code
        OR c.category_name LIKE :q_category
        OR p.category_name LIKE :q_parent_category
    )";
    $searchLike = '%' . $search . '%';
    $params[':q_recipe_name'] = $searchLike;
    $params[':q_menu_item'] = $searchLike;
    $params[':q_menu_code'] = $searchLike;
    $params[':q_category'] = $searchLike;
    $params[':q_parent_category'] = $searchLike;
}

$summary = ['recipes'=>0,'active'=>0,'inactive'=>0,'avg_margin'=>0,'low_margin'=>0,'linked_menu'=>0];
try {
    $stmt = $pdo->prepare("SELECT
            r.*,
            mi.item_name AS menu_item_name,
            mi.item_code AS menu_item_code,
            mi.price AS menu_price,
            mi.tax_rate AS menu_tax_rate,
            mi.inventory_item_id AS menu_inventory_item_id,
            c.category_name,
            p.category_name AS parent_category_name,
            COALESCE(c.path, CONCAT_WS(' > ', p.category_name, c.category_name), c.category_name) AS category_path,
            sl.location_name,
            COUNT(rl.id) AS ingredient_count,
            COALESCE(SUM((rl.qty_required + (rl.qty_required * (rl.wastage_percent / 100))) * COALESCE(NULLIF(ing.avg_cost,0), ing.cost_price, 0)),0) AS recipe_total_cost
        FROM inventory_recipes r
        LEFT JOIN restaurant_menu_items mi ON mi.id = r.restaurant_menu_item_id
        LEFT JOIN restaurant_menu_categories c ON c.id = mi.category_id
        LEFT JOIN restaurant_menu_categories p ON p.id = c.parent_id
        LEFT JOIN store_locations sl ON sl.id = r.default_store_id
        LEFT JOIN inventory_recipe_lines rl ON rl.recipe_id = r.id
        LEFT JOIN inventory_items ing ON ing.id = rl.ingredient_item_id
        WHERE $where
        GROUP BY r.id
        ORDER BY r.is_active DESC, COALESCE(p.category_name, c.category_name), c.category_name, r.recipe_name ASC
        LIMIT 500");
    $stmt->execute($params);
    $recipes = $stmt->fetchAll(PDO::FETCH_ASSOC);

    $marginTotal = 0;
    $marginCount = 0;
    foreach ($recipes as $row) {
        $summary['recipes']++;
        if ((int)$row['is_active'] === 1) $summary['active']++; else $summary['inactive']++;
        if (!empty($row['restaurant_menu_item_id'])) $summary['linked_menu']++;
        $cost = ((float)$row['recipe_total_cost']) / max(1, (float)$row['yield_qty']);
        $selling = (float)(($row['menu_price'] ?? 0) ?: ($row['selling_price'] ?? 0));
        $margin = $selling > 0 ? (($selling - $cost) / $selling) * 100 : 0;
        if ($selling > 0) { $marginTotal += $margin; $marginCount++; }
        if ($selling > 0 && $margin < 35) $summary['low_margin']++;
    }
    $summary['avg_margin'] = $marginCount > 0 ? ($marginTotal / $marginCount) : 0;
} catch (Throwable $e) {
    $errors[] = 'Could not load recipes: ' . $e->getMessage();
}

$viewId = (int)($_GET['view_id'] ?? 0);
$viewRecipe = null;
$viewLines = [];
$costLogs = [];
$canMakeQty = null;
if ($viewId > 0) {
    try {
        $stmt = $pdo->prepare("SELECT
                r.*,
                mi.item_name AS menu_item_name,
                mi.item_code AS menu_item_code,
                mi.price AS menu_price,
                mi.tax_rate AS menu_tax_rate,
                c.category_name,
                p.category_name AS parent_category_name,
                COALESCE(c.path, CONCAT_WS(' > ', p.category_name, c.category_name), c.category_name) AS category_path,
                sl.location_name
            FROM inventory_recipes r
            LEFT JOIN restaurant_menu_items mi ON mi.id = r.restaurant_menu_item_id
            LEFT JOIN restaurant_menu_categories c ON c.id = mi.category_id
            LEFT JOIN restaurant_menu_categories p ON p.id = c.parent_id
            LEFT JOIN store_locations sl ON sl.id = r.default_store_id
            WHERE r.id = :id
            LIMIT 1");
        $stmt->execute([':id' => $viewId]);
        $viewRecipe = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
        if ($viewRecipe) {
            $stmt = $pdo->prepare("SELECT rl.*, ing.item_name, ing.item_code, ing.avg_cost, ing.cost_price, u.unit_code, c.category_name
                FROM inventory_recipe_lines rl
                INNER JOIN inventory_items ing ON ing.id = rl.ingredient_item_id
                LEFT JOIN inventory_units u ON u.id = ing.unit_id
                LEFT JOIN inventory_item_categories c ON c.id = ing.category_id
                WHERE rl.recipe_id = :recipe_id
                ORDER BY c.category_name ASC, ing.item_name ASC");
            $stmt->execute([':recipe_id' => $viewId]);
            $viewLines = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $stmt = $pdo->prepare("SELECT * FROM inventory_recipe_cost_logs WHERE recipe_id = :recipe_id ORDER BY cost_date DESC, id DESC LIMIT 20");
            $stmt->execute([':recipe_id' => $viewId]);
            $costLogs = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $storeIdForCalc = (int)($viewRecipe['default_store_id'] ?? 0);
            foreach ($viewLines as $line) {
                $needed = (float)$line['qty_required'] + ((float)$line['qty_required'] * ((float)$line['wastage_percent'] / 100));
                if ($needed <= 0) continue;
                $balance = recipe_stock_balance($pdo, (int)$line['ingredient_item_id'], $storeIdForCalc);
                $possible = floor($balance / $needed);
                $canMakeQty = $canMakeQty === null ? $possible : min($canMakeQty, $possible);
            }
        }
    } catch (Throwable $e) {
        $errors[] = 'Could not load recipe view: ' . $e->getMessage();
    }
}

$flashes = recipe_get_flash();
require_once __DIR__ . '/../../includes/header.php';
?>

<div class="hero-band recipe-hero">
    <div class="row g-3 align-items-center">
        <div class="col-lg-8">
            <div class="page-eyebrow text-white-50"><i class="bi bi-journal-richtext"></i> Restaurant POS Recipes</div>
            <div class="hero-title mt-1">Recipes / Menu Costings</div>
            <div class="hero-subtitle mt-1">Link Food, Cocktails and Modifiers from Restaurant POS to stock ingredients and live costing.</div>
        </div>
        <div class="col-lg-4 text-lg-end">
            <a href="../restaurant/planner.php" class="btn btn-light me-2"><i class="bi bi-grid-3x3-gap me-2"></i>Planner</a>
            <a href="inventory_items.php" class="btn btn-outline-light"><i class="bi bi-box-seam me-2"></i>Stock Items</a>
        </div>
    </div>
</div>

<?php foreach ($flashes as $flash): ?>
    <div class="alert alert-<?php echo h($flash['type']); ?>"><?php echo h($flash['message']); ?></div>
<?php endforeach; ?>

<?php if ($errors): ?>
    <div class="alert alert-danger">
        <div class="fw-bold mb-2">Please fix the following:</div>
        <ul class="mb-0"><?php foreach ($errors as $err): ?><li><?php echo h($err); ?></li><?php endforeach; ?></ul>
    </div>
<?php endif; ?>

<div class="row g-3 mb-3">
    <div class="col-md-6 col-xl-3"><div class="metric-card"><div class="metric-icon bg-primary-subtle text-primary"><i class="bi bi-card-checklist"></i></div><div><div class="metric-label">Recipes</div><div class="metric-value"><?php echo (int)$summary['recipes']; ?></div></div></div></div>
    <div class="col-md-6 col-xl-3"><div class="metric-card"><div class="metric-icon bg-success-subtle text-success"><i class="bi bi-link-45deg"></i></div><div><div class="metric-label">Linked to Menu</div><div class="metric-value"><?php echo (int)$summary['linked_menu']; ?></div></div></div></div>
    <div class="col-md-6 col-xl-3"><div class="metric-card"><div class="metric-icon bg-warning-subtle text-warning"><i class="bi bi-exclamation-triangle"></i></div><div><div class="metric-label">Low Margin</div><div class="metric-value"><?php echo (int)$summary['low_margin']; ?></div></div></div></div>
    <div class="col-md-6 col-xl-3"><div class="metric-card"><div class="metric-icon bg-info-subtle text-info"><i class="bi bi-percent"></i></div><div><div class="metric-label">Avg Margin</div><div class="metric-value small-value"><?php echo money_fmt($summary['avg_margin']); ?>%</div></div></div></div>
</div>

<div class="recipe-workspace-bar">
    <div class="recipe-workspace-copy">
        <span class="recipe-workspace-kicker">Recipe Workspace</span>
        <strong>Search, review and cost menu recipes</strong>
        <small>The recipe list is the primary workspace. Creation and costing tools remain one click away.</small>
    </div>
    <div class="recipe-workspace-actions">
        <button type="button" class="recipe-jump active" data-jump-target="recipe-filter-card">
            <i class="bi bi-search"></i><span>Find Recipes</span>
        </button>
        <button type="button" class="recipe-jump" data-jump-target="recipe-editor-card">
            <i class="bi bi-plus-square"></i><span>New Recipe</span>
        </button>
        <button type="button" class="recipe-jump" data-jump-target="recipe-list-card">
            <i class="bi bi-card-list"></i><span>Recipe List</span>
        </button>
        <a class="recipe-jump" href="inventory_items.php">
            <i class="bi bi-box-seam"></i><span>Stock Items</span>
        </a>
        <a class="recipe-jump" href="../restaurant/planner.php">
            <i class="bi bi-grid-3x3-gap"></i><span>Planner</span>
        </a>
    </div>
</div>

<?php if ($viewRecipe): ?>
<?php
    $viewTotalCost = 0;
    foreach ($viewLines as $line) {
        $effective = (float)$line['qty_required'] + ((float)$line['qty_required'] * ((float)$line['wastage_percent'] / 100));
        $cost = (float)(($line['avg_cost'] ?? 0) ?: ($line['cost_price'] ?? 0));
        $viewTotalCost += $effective * $cost;
    }
    $viewYield = max(1, (float)$viewRecipe['yield_qty']);
    $viewCostPerPortion = $viewTotalCost / $viewYield;
    $viewSelling = (float)(($viewRecipe['menu_price'] ?? 0) ?: ($viewRecipe['selling_price'] ?? 0));
    $viewProfit = $viewSelling - $viewCostPerPortion;
    $viewMargin = $viewSelling > 0 ? ($viewProfit / $viewSelling) * 100 : 0;
?>
<div class="card panel-card recipe-view mb-3 recipe-focus-card" id="recipe-view-card">
    <div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
        <div>
            <h5 class="mb-0"><?php echo h($viewRecipe['recipe_name']); ?></h5>
            <div class="small text-muted">
                Menu: <?php echo h($viewRecipe['menu_item_name'] ?: 'Not linked'); ?>
                <?php echo !empty($viewRecipe['category_path']) ? ' • ' . h($viewRecipe['category_path']) : ''; ?>
            </div>
        </div>
        <div class="d-flex gap-2">
            <a href="recipes.php?edit_id=<?php echo (int)$viewRecipe['id']; ?>#recipe-editor-card" class="btn btn-outline-primary btn-sm"><i class="bi bi-pencil me-1"></i>Edit</a>
            <a href="recipes.php" class="btn btn-outline-secondary btn-sm">Close View</a>
        </div>
    </div>
    <div class="card-body">
        <div class="row g-3 mb-3">
            <div class="col-md-3"><div class="mini-stat"><span>Cost / Portion</span><strong><?php echo money_fmt($viewCostPerPortion); ?></strong></div></div>
            <div class="col-md-3"><div class="mini-stat"><span>POS Selling</span><strong><?php echo money_fmt($viewSelling); ?></strong></div></div>
            <div class="col-md-3"><div class="mini-stat"><span>Gross Profit</span><strong><?php echo money_fmt($viewProfit); ?></strong></div></div>
            <div class="col-md-3"><div class="mini-stat"><span>Margin</span><strong class="<?php echo $viewMargin < 35 ? 'text-danger' : 'text-success'; ?>"><?php echo money_fmt($viewMargin); ?>%</strong></div></div>
        </div>
        <?php if ($canMakeQty !== null): ?>
            <div class="alert alert-info small">Based on current stock<?php echo !empty($viewRecipe['location_name']) ? ' at ' . h($viewRecipe['location_name']) : ''; ?>, you can make about <strong><?php echo (int)$canMakeQty; ?></strong> portion(s).</div>
        <?php endif; ?>
        <?php if (!empty($viewRecipe['preparation_notes'])): ?>
            <div class="alert alert-light border small"><strong>Preparation Notes:</strong><br><?php echo nl2br(h($viewRecipe['preparation_notes'])); ?></div>
        <?php endif; ?>
        <div class="table-responsive">
            <table class="table table-sm table-modern align-middle">
                <thead><tr><th>Ingredient</th><th>Category</th><th class="text-end">Qty</th><th class="text-end">Waste</th><th class="text-end">Eff. Qty</th><th class="text-end">Cost</th><th class="text-end">Line Cost</th><th>Notes</th></tr></thead>
                <tbody>
                <?php foreach ($viewLines as $line): ?>
                    <?php
                        $effective = (float)$line['qty_required'] + ((float)$line['qty_required'] * ((float)$line['wastage_percent'] / 100));
                        $cost = (float)(($line['avg_cost'] ?? 0) ?: ($line['cost_price'] ?? 0));
                        $lineCost = $effective * $cost;
                    ?>
                    <tr>
                        <td><strong><?php echo h($line['item_name']); ?></strong><div class="small text-muted"><?php echo h($line['item_code'] ?: ''); ?> <?php echo h($line['unit_code'] ?: ''); ?></div></td>
                        <td><?php echo h($line['category_name'] ?: '—'); ?></td>
                        <td class="text-end"><?php echo money_fmt($line['qty_required']); ?></td>
                        <td class="text-end"><?php echo money_fmt($line['wastage_percent']); ?>%</td>
                        <td class="text-end"><?php echo money_fmt($effective); ?></td>
                        <td class="text-end"><?php echo money_fmt($cost); ?></td>
                        <td class="text-end fw-bold"><?php echo money_fmt($lineCost); ?></td>
                        <td><?php echo h($line['notes'] ?: ''); ?></td>
                    </tr>
                <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <form method="post" class="mt-2">
            <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
            <input type="hidden" name="action" value="log_cost">
            <input type="hidden" name="recipe_id" value="<?php echo (int)$viewRecipe['id']; ?>">
            <button class="btn btn-outline-success btn-sm"><i class="bi bi-graph-up me-1"></i>Log Cost Snapshot</button>
        </form>
        <?php if ($costLogs): ?>
            <h6 class="fw-bold mt-3">Recent Cost Snapshots</h6>
            <div class="table-responsive">
                <table class="table table-sm">
                    <thead><tr><th>Date</th><th class="text-end">Cost</th><th class="text-end">Selling</th><th class="text-end">Profit</th><th class="text-end">Margin</th></tr></thead>
                    <tbody>
                    <?php foreach ($costLogs as $log): ?>
                        <tr><td><?php echo h($log['cost_date']); ?></td><td class="text-end"><?php echo money_fmt($log['total_cost']); ?></td><td class="text-end"><?php echo money_fmt($log['selling_price']); ?></td><td class="text-end"><?php echo money_fmt($log['gross_profit']); ?></td><td class="text-end"><?php echo money_fmt($log['margin_percent']); ?>%</td></tr>
                    <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>
</div>
<?php endif; ?>

<div class="row g-4 recipe-workspace-grid">
    <div class="col-xl-5">
        <div class="card panel-card recipe-focus-card" id="recipe-editor-card">
            <div class="card-header"><h5 class="mb-0"><?php echo $editRecipe ? 'Edit Menu Recipe' : 'Create Menu Recipe'; ?></h5></div>
            <div class="card-body">
                <form method="post" id="recipeForm">
                    <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                    <input type="hidden" name="action" value="save_recipe">
                    <input type="hidden" name="recipe_id" value="<?php echo (int)($editRecipe['id'] ?? 0); ?>">

                    <div class="mb-3">
                        <label class="form-label fw-bold">Restaurant Menu Item</label>
                        <select name="restaurant_menu_item_id" class="form-select js-search-select" data-search-placeholder="Search menu item from planner..." required>
                            <option value="">Select item sold in POS</option>
                            <?php foreach ($menuItems as $item): ?>
                            
                                <?php $path = trim((string)($item['category_path'] ?: $item['category_name'])); ?>
                                <option value="<?php echo (int)$item['id']; ?>"
                                        data-name="<?php echo h($item['item_name']); ?>"
                                        data-type="<?php echo h(recipe_menu_type($item)); ?>"
                                        data-price="<?php echo h($item['price']); ?>"
                                        <?php echo (int)($editRecipe['restaurant_menu_item_id'] ?? 0) === (int)$item['id'] ? 'selected' : ''; ?>>
                                    <?php echo h($item['item_name']); ?><?php echo $item['item_code'] ? ' - ' . h($item['item_code']) : ''; ?><?php echo $path ? ' • ' . h($path) : ''; ?><?php echo (float)$item['price'] > 0 ? ' (' . money_fmt($item['price']) . ')' : ''; ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <div class="small text-muted mt-1">These are the Food, Cocktails, Mocktails and other buttons from Restaurant POS / planner.</div>
                    </div>

                    <div class="row g-3">
                        <div class="col-md-8">
                            <label class="form-label fw-bold">Recipe Name</label>
                            <input type="text" name="recipe_name" id="recipeName" class="form-control" required value="<?php echo h($editRecipe['recipe_name'] ?? ''); ?>">
                        </div>
                        <div class="col-md-4">
                            <label class="form-label fw-bold">Recipe Type</label>
                            <select name="recipe_type" id="recipeType" class="form-select">
                                <?php foreach (['food'=>'Food','cocktail'=>'Cocktail','mocktail'=>'Mocktail','modifier'=>'Modifier','prep'=>'Prep / Batch','other'=>'Other'] as $value => $label): ?>
                                    <option value="<?php echo h($value); ?>" <?php echo (($editRecipe['recipe_type'] ?? 'food') === $value) ? 'selected' : ''; ?>><?php echo h($label); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                    </div>

                    <div class="row g-3 mt-0">
                        <div class="col-md-6">
                            <label class="form-label fw-bold">Yield Qty</label>
                            <input type="number" step="0.0001" min="0.0001" name="yield_qty" class="form-control" value="<?php echo h($editRecipe['yield_qty'] ?? '1.0000'); ?>">
                            <div class="small text-muted">Usually 1 for one dish/cocktail. Use higher for batch prep.</div>
                        </div>
                        <div class="col-md-6">
                            <label class="form-label fw-bold">Default Store</label>
                            <select name="default_store_id" class="form-select js-search-select" data-search-placeholder="Search store...">
                                <option value="0">Any / POS store</option>
                                <?php foreach ($stores as $store): ?>
                                    <option value="<?php echo (int)$store['id']; ?>" <?php echo (int)($editRecipe['default_store_id'] ?? 0) === (int)$store['id'] ? 'selected' : ''; ?>><?php echo h($store['location_name']); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                    </div>

                    <div class="mt-3">
                        <label class="form-label fw-bold">Preparation Notes</label>
                        <textarea name="preparation_notes" class="form-control" rows="3"><?php echo h($editRecipe['preparation_notes'] ?? ''); ?></textarea>
                    </div>

                    <label class="setting-check mt-3"><input type="checkbox" name="is_active" value="1" <?php echo (int)($editRecipe['is_active'] ?? 1) === 1 ? 'checked' : ''; ?>><span>Active Recipe</span></label>

                    <hr>

                    <div class="d-flex justify-content-between align-items-center mb-2">
                        <h6 class="fw-bold mb-0">Ingredients</h6>
                        <button type="button" class="btn btn-sm btn-outline-primary" id="addLine"><i class="bi bi-plus-circle me-1"></i>Add Ingredient</button>
                    </div>
                    <div id="lineBox" class="recipe-lines"></div>

                    <div class="recipe-total-box mt-3">
                        <div><span>Ingredient Lines</span><strong id="lineCount">0</strong></div>
                        <div><span>Estimated Cost</span><strong id="estimatedCost">0.00</strong></div>
                    </div>

                    <div class="d-grid gap-2 mt-3">
                        <button class="btn btn-primary"><i class="bi bi-save me-2"></i><?php echo $editRecipe ? 'Update Recipe' : 'Save Recipe'; ?></button>
                        <?php if ($editRecipe): ?><a href="recipes.php" class="btn btn-outline-secondary">Cancel Edit</a><?php endif; ?>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <div class="col-xl-7">
        <div class="card panel-card mb-3 recipe-focus-card" id="recipe-filter-card">
            <div class="card-body">
                <?php
                $activeRecipeFilterCount = 0;
                foreach ([$status, $categoryId, $typeFilter, $search] as $activeRecipeFilterValue) {
                    if ((string)$activeRecipeFilterValue !== ''
                        && (string)$activeRecipeFilterValue !== '0') {
                        $activeRecipeFilterCount++;
                    }
                }
                ?>
                <?php if ($activeRecipeFilterCount > 0): ?>
                    <div class="recipe-active-filter-banner">
                        <div>
                            <i class="bi bi-funnel-fill me-2"></i>
                            <strong><?php echo $activeRecipeFilterCount; ?> active filter<?php echo $activeRecipeFilterCount === 1 ? '' : 's'; ?></strong>
                            <span>Your recipe results remain active until you remove the filters.</span>
                        </div>
                        <a href="recipes.php?reset_recipe_filters=1" class="btn btn-sm btn-outline-danger">
                            <i class="bi bi-x-circle me-1"></i>Remove Filters
                        </a>
                    </div>
                <?php endif; ?>
                <form method="get" class="row g-3 align-items-end recipe-filter-form">
                    <div class="col-md-3"><label class="form-label">Search</label><input type="text" name="q" class="form-control" value="<?php echo h($search); ?>" placeholder="Recipe / menu item"></div>
                    <div class="col-md-3"><label class="form-label">Menu Category</label><select name="category_id" class="form-select js-search-select" data-search-placeholder="Search category..."><option value="0">All categories</option><?php foreach ($menuCategories as $cat): ?><option value="<?php echo (int)$cat['id']; ?>" <?php echo $categoryId === (int)$cat['id'] ? 'selected' : ''; ?>><?php echo h(($cat['parent_category_name'] ? $cat['parent_category_name'] . ' > ' : '') . $cat['category_name']); ?></option><?php endforeach; ?></select></div>
                    <div class="col-md-2"><label class="form-label">Type</label><select name="recipe_type" class="form-select"><option value="">All</option><?php foreach (['food'=>'Food','cocktail'=>'Cocktail','mocktail'=>'Mocktail','modifier'=>'Modifier','prep'=>'Prep','other'=>'Other'] as $v=>$l): ?><option value="<?php echo h($v); ?>" <?php echo $typeFilter === $v ? 'selected' : ''; ?>><?php echo h($l); ?></option><?php endforeach; ?></select></div>
                    <div class="col-md-2"><label class="form-label">Status</label><select name="status" class="form-select"><option value="">All</option><option value="1" <?php echo $status === '1' ? 'selected' : ''; ?>>Active</option><option value="0" <?php echo $status === '0' ? 'selected' : ''; ?>>Inactive</option></select></div>
                    <div class="col-md-2 d-grid"><button class="btn btn-primary"><i class="bi bi-funnel me-2"></i>Filter</button></div>
                    <div class="col-md-2 d-grid">
                        <a href="recipes.php?reset_recipe_filters=1" class="btn btn-outline-secondary">
                            <i class="bi bi-x-circle me-1"></i>Remove Filters
                        </a>
                    </div>
                </form>
            </div>
        </div>

        <div class="card panel-card recipe-focus-card" id="recipe-list-card">
            <div class="card-header d-flex justify-content-between align-items-center">
                <h5 class="mb-0">Recipe List</h5>
                <span class="text-muted small">Showing up to 500 menu-linked recipes</span>
            </div>
            <div class="card-body p-0">
                <div class="table-responsive recipe-list-scroll">
                    <table class="table table-modern align-middle mb-0 recipe-list-table">
                        <thead><tr><th>Recipe / Menu Item</th><th>Category</th><th>Type</th><th class="text-end">Ingredients</th><th class="text-end">Cost</th><th class="text-end">Selling</th><th class="text-end">Margin</th><th>Store</th><th>Status</th><th class="text-end">Actions</th></tr></thead>
                        <tbody>
                        <?php if (!$recipes): ?>
                            <tr><td colspan="10" class="text-center text-muted py-4">No recipes found.</td></tr>
                        <?php else: ?>
                            <?php foreach ($recipes as $row): ?>
                                <?php
                                    $costPerSale = ((float)$row['recipe_total_cost']) / max(1, (float)$row['yield_qty']);
                                    $selling = (float)(($row['menu_price'] ?? 0) ?: ($row['selling_price'] ?? 0));
                                    $profit = $selling - $costPerSale;
                                    $margin = $selling > 0 ? ($profit / $selling) * 100 : 0;
                                ?>
                                <tr class="<?php echo ($selling > 0 && $margin < 35) ? 'table-warning' : ''; ?>">
                                    <td><strong><?php echo h($row['recipe_name']); ?></strong><div class="small text-muted">Menu: <?php echo h($row['menu_item_name'] ?: 'Not linked'); ?> <?php echo $row['menu_item_code'] ? '• ' . h($row['menu_item_code']) : ''; ?></div></td>
                                    <td><?php echo h($row['category_path'] ?: '—'); ?></td>
                                    <td><span class="badge text-bg-light"><?php echo h(ucwords((string)$row['recipe_type'])); ?></span></td>
                                    <td class="text-end"><?php echo (int)$row['ingredient_count']; ?></td>
                                    <td class="text-end fw-bold"><?php echo money_fmt($costPerSale); ?></td>
                                    <td class="text-end"><?php echo money_fmt($selling); ?></td>
                                    <td class="text-end <?php echo $margin < 35 ? 'text-danger fw-bold' : 'text-success fw-bold'; ?>"><?php echo money_fmt($margin); ?>%</td>
                                    <td><?php echo h($row['location_name'] ?: 'POS store'); ?></td>
                                    <td><span class="badge <?php echo (int)$row['is_active'] === 1 ? 'text-bg-success' : 'text-bg-secondary'; ?>"><?php echo (int)$row['is_active'] === 1 ? 'Active' : 'Inactive'; ?></span></td>
                                    <td class="text-end">
                                        <div class="btn-group btn-group-sm">
                                            <a href="recipes.php?view_id=<?php echo (int)$row['id']; ?>#recipe-view-card" class="btn btn-outline-info" title="View"><i class="bi bi-eye"></i></a>
                                            <a href="recipes.php?edit_id=<?php echo (int)$row['id']; ?>#recipe-editor-card" class="btn btn-outline-primary" title="Edit"><i class="bi bi-pencil"></i></a>
                                            <form method="post" class="d-inline"><?php if (function_exists('csrf_field')) echo csrf_field(); ?><input type="hidden" name="action" value="toggle_recipe"><input type="hidden" name="recipe_id" value="<?php echo (int)$row['id']; ?>"><button class="btn btn-outline-secondary" title="Toggle"><i class="bi bi-toggle-on"></i></button></form>
                                            <form method="post" class="d-inline" onsubmit="return confirm('Delete this recipe?');"><?php if (function_exists('csrf_field')) echo csrf_field(); ?><input type="hidden" name="action" value="delete_recipe"><input type="hidden" name="recipe_id" value="<?php echo (int)$row['id']; ?>"><button class="btn btn-outline-danger" title="Delete"><i class="bi bi-trash"></i></button></form>
                                        </div>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        <?php endif; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>

<template id="lineTemplate">
    <div class="recipe-line-card">
        <div class="d-flex justify-content-between align-items-center mb-2">
            <strong class="line-title">Ingredient</strong>
            <button type="button" class="btn btn-sm btn-outline-danger remove-line"><i class="bi bi-x-lg"></i></button>
        </div>
        <div class="row g-2">
            <div class="col-md-5">
                <label class="form-label">Ingredient</label>
                <select name="ingredient_item_id[]" class="form-select form-select-sm ingredient-select js-search-select" data-search-placeholder="Search ingredient..." required>
                    <option value="">Select ingredient</option>
                    <?php foreach ($ingredientItems as $item): ?>
                        <option value="<?php echo (int)$item['id']; ?>" data-cost="<?php echo h(($item['avg_cost'] ?: $item['cost_price']) ?: 0); ?>" data-unit="<?php echo h($item['unit_code'] ?: ''); ?>">
                            <?php echo h($item['item_name']); ?><?php echo $item['item_code'] ? ' - ' . h($item['item_code']) : ''; ?><?php echo !empty($item['unit_code']) ? ' (' . h($item['unit_code']) . ')' : ''; ?><?php echo !empty($item['category_name']) ? ' • ' . h($item['category_name']) : ''; ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="col-md-2"><label class="form-label">Qty</label><input type="number" step="0.0001" min="0.0001" name="qty_required[]" class="form-control form-control-sm qty-input" required></div>
            <div class="col-md-2"><label class="form-label">Waste %</label><input type="number" step="0.0001" min="0" name="wastage_percent[]" class="form-control form-control-sm waste-input" value="0"></div>
            <div class="col-md-3"><label class="form-label">Line Notes</label><input type="text" name="line_notes[]" class="form-control form-control-sm" placeholder="optional"></div>
        </div>
        <div class="small text-muted mt-1 line-cost-preview">Cost: 0.00</div>
    </div>
</template>

<style>
.recipe-hero{padding:14px 18px!important;margin-bottom:12px!important}.small-value{font-size:1rem!important;letter-spacing:0!important}.recipe-view{border:2px solid rgba(37,99,235,.18)}.mini-stat{background:#f8fafc;border:1px solid rgba(15,23,42,.08);border-radius:16px;padding:12px}.mini-stat span{display:block;color:#64748b;font-size:11px;text-transform:uppercase;font-weight:900;letter-spacing:.04em}.mini-stat strong{display:block;font-size:1.25rem;font-weight:950;color:#0f172a}.recipe-list-scroll{max-height:68vh;overflow:auto}.recipe-list-table thead th{position:sticky;top:0;z-index:5;background:#f8fafc!important;box-shadow:0 1px 0 rgba(15,23,42,.10);white-space:nowrap}.recipe-line-card{border:1px solid rgba(15,23,42,.10);border-radius:14px;background:#fff;padding:10px;margin-bottom:9px}.recipe-total-box{display:flex;justify-content:space-between;gap:10px;background:#f8fafc;border:1px solid rgba(15,23,42,.10);border-radius:14px;padding:10px}.recipe-total-box span{display:block;font-size:11px;text-transform:uppercase;font-weight:850;color:#64748b}.recipe-total-box strong{font-size:1.05rem}.setting-check{display:flex;align-items:center;gap:8px;border:1px solid rgba(15,23,42,.10);background:#fff;border-radius:12px;padding:9px 11px;font-weight:800;font-size:13px;color:#475569;cursor:pointer}.searchable-select{position:relative;width:100%}.searchable-select .native-search-select{position:absolute!important;left:-9999px!important;width:1px!important;height:1px!important;opacity:0!important}.searchable-select-input{width:100%;border:1px solid #dee2e6;border-radius:.375rem;background:#fff;padding:.375rem 2rem .375rem .75rem;font-size:1rem;line-height:1.5}.searchable-select-input.sm{min-height:31px;padding:.25rem 1.7rem .25rem .5rem;font-size:.875rem;border-radius:.25rem}.searchable-select:after{content:"⌄";position:absolute;right:.65rem;top:.38rem;color:#64748b;pointer-events:none;font-size:.95rem}.searchable-select.has-sm:after{top:.18rem;right:.5rem}.searchable-select-menu{display:none;position:absolute;left:0;right:0;top:calc(100% + 3px);z-index:1060;max-height:260px;overflow:auto;background:#fff;border:1px solid rgba(15,23,42,.16);border-radius:12px;box-shadow:0 18px 40px rgba(15,23,42,.18);padding:6px}.searchable-select.open .searchable-select-menu{display:block}.searchable-select-option{padding:8px 10px;border-radius:9px;cursor:pointer;font-size:.9rem;color:#0f172a}.searchable-select-option:hover,.searchable-select-option.active{background:#eef2ff}.searchable-select-empty{padding:10px;color:#64748b;font-size:.85rem}

/* Elite, management-first recipe workspace */
.recipe-workspace-bar{
    position:sticky;
    top:72px;
    z-index:32;
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:16px;
    margin:0 0 14px;
    padding:12px 14px;
    border:1px solid #dbe3ef;
    border-radius:18px;
    background:rgba(255,255,255,.96);
    box-shadow:0 12px 30px rgba(15,23,42,.08);
    backdrop-filter:blur(14px);
}
.recipe-workspace-copy{min-width:250px}
.recipe-workspace-copy strong{
    display:block;
    color:#0f172a;
    font-size:.96rem;
    line-height:1.2;
}
.recipe-workspace-copy small{
    display:block;
    margin-top:2px;
    color:#64748b;
    font-size:.72rem;
}
.recipe-workspace-kicker{
    display:block;
    margin-bottom:2px;
    color:#2563eb;
    font-size:.63rem;
    font-weight:950;
    text-transform:uppercase;
    letter-spacing:.1em;
}
.recipe-workspace-actions{
    display:flex;
    align-items:center;
    justify-content:flex-end;
    gap:6px;
    flex-wrap:wrap;
}
.recipe-jump{
    border:1px solid #dbe3ef;
    background:#f8fafc;
    color:#334155;
    border-radius:12px;
    padding:7px 10px;
    min-width:78px;
    display:inline-flex;
    flex-direction:column;
    align-items:center;
    gap:2px;
    font-size:.66rem;
    font-weight:900;
    text-decoration:none;
    transition:.16s ease;
}
.recipe-jump i{font-size:.94rem}
.recipe-jump:hover,
.recipe-jump.active{
    border-color:#2563eb;
    background:#eff6ff;
    color:#1d4ed8;
    transform:translateY(-1px);
}
.recipe-workspace-grid{
    display:block!important;
}
.recipe-workspace-grid>.col-xl-5,
.recipe-workspace-grid>.col-xl-7{
    display:contents;
}
.recipe-workspace-grid .panel-card{
    width:100%;
    margin-top:14px!important;
}
#recipe-filter-card{margin-top:0!important}
#recipe-list-card{margin-top:12px!important}
#recipe-editor-card{margin-top:14px!important}
.recipe-filter-form{
    padding:10px;
    border:1px solid #e2e8f0;
    border-radius:14px;
    background:#f8fafc;
}
.recipe-active-filter-banner{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:12px;
    padding:9px 11px;
    margin-bottom:10px;
    border:1px solid #bfdbfe;
    border-radius:12px;
    background:#eff6ff;
    color:#1e3a8a;
    font-size:.78rem;
}
.recipe-active-filter-banner span{
    margin-left:6px;
    color:#475569;
}
.recipe-focus-card{
    border-color:#cbd5e1;
    box-shadow:0 14px 34px rgba(15,23,42,.075);
}
#recipe-list-card .recipe-list-scroll{
    max-height:600px;
}
.recipe-panel-subtitle{
    display:block;
    margin-top:2px;
    color:#64748b;
    font-size:.68rem;
    font-weight:600;
}
.recipe-panel-highlight{
    animation:recipePanelPulse 1.25s ease;
}
@keyframes recipePanelPulse{
    0%{box-shadow:0 0 0 0 rgba(37,99,235,.26)}
    45%{box-shadow:0 0 0 7px rgba(37,99,235,.08)}
    100%{box-shadow:0 12px 28px rgba(15,23,42,.07)}
}
@media (max-width:991.98px){
    .recipe-workspace-bar{
        position:static;
        display:block;
    }
    .recipe-workspace-actions{
        justify-content:flex-start;
        margin-top:10px;
    }
    .recipe-jump{
        flex:1 1 74px;
    }
}
@media (max-width:767.98px){
    .recipe-active-filter-banner{
        align-items:flex-start;
        flex-direction:column;
    }
    #recipe-list-card .recipe-list-scroll{
        max-height:none;
    }
}

</style>

<script>
document.addEventListener('DOMContentLoaded', function(){
    /*
     * Daily management first:
     * filters and recipe list, then recipe creation/editing.
     */
    const workspaceGrid = document.querySelector('.recipe-workspace-grid');
    if (workspaceGrid) {
        ['recipe-filter-card','recipe-list-card','recipe-editor-card'].forEach(function(id){
            const card = document.getElementById(id);
            if (card) workspaceGrid.appendChild(card);
        });

        Array.from(workspaceGrid.children).forEach(function(child){
            if (child.classList
                && (child.classList.contains('col-xl-5') || child.classList.contains('col-xl-7'))) {
                while (child.firstChild) workspaceGrid.appendChild(child.firstChild);
                child.remove();
            }
        });
    }

    document.querySelectorAll('.recipe-jump[data-jump-target]').forEach(function(button){
        button.addEventListener('click', function(){
            const target = document.getElementById(this.dataset.jumpTarget || '');
            if (!target) return;

            document.querySelectorAll('.recipe-jump').forEach(function(item){
                item.classList.remove('active');
            });
            this.classList.add('active');

            target.scrollIntoView({behavior:'smooth', block:'start'});
            target.classList.remove('recipe-panel-highlight');
            void target.offsetWidth;
            target.classList.add('recipe-panel-highlight');
            window.setTimeout(function(){
                target.classList.remove('recipe-panel-highlight');
            }, 1400);
        });
    });

    const recipePanelSubtitles = {
        'recipe-filter-card':'Search and filters remain active until removed',
        'recipe-list-card':'Review cost, selling price, margin and recipe status',
        'recipe-editor-card':'Create a recipe or update the selected menu recipe',
        'recipe-view-card':'Detailed ingredients, costing and stock availability'
    };
    Object.keys(recipePanelSubtitles).forEach(function(id){
        const card = document.getElementById(id);
        const title = card ? card.querySelector(':scope > .card-header h5') : null;
        if (title && !title.querySelector('.recipe-panel-subtitle')) {
            const subtitle = document.createElement('span');
            subtitle.className = 'recipe-panel-subtitle';
            subtitle.textContent = recipePanelSubtitles[id];
            title.appendChild(subtitle);
        }
    });

    <?php if ($editRecipe): ?>
    window.setTimeout(function(){
        const editor = document.getElementById('recipe-editor-card');
        if (editor) editor.scrollIntoView({behavior:'smooth', block:'start'});
    }, 120);
    <?php elseif ($viewRecipe): ?>
    window.setTimeout(function(){
        const viewer = document.getElementById('recipe-view-card');
        if (viewer) viewer.scrollIntoView({behavior:'smooth', block:'start'});
    }, 120);
    <?php endif; ?>

    const lineBox = document.getElementById('lineBox');
    const template = document.getElementById('lineTemplate');
    const addLineBtn = document.getElementById('addLine');
    const menuSelect = document.querySelector('select[name="restaurant_menu_item_id"]');
    const recipeName = document.getElementById('recipeName');
    const recipeType = document.getElementById('recipeType');
    const existingLines = <?php echo json_encode($editLines, JSON_UNESCAPED_SLASHES); ?>;

    function money(n){ return Number(n || 0).toFixed(2); }

    function initSearchableSelect(select){
        if (!select || select.dataset.searchReady === '1') return;
        select.dataset.searchReady = '1';
        const isSmall = select.classList.contains('form-select-sm');
        const wrapper = document.createElement('div');
        wrapper.className = 'searchable-select' + (isSmall ? ' has-sm' : '');
        select.parentNode.insertBefore(wrapper, select);
        wrapper.appendChild(select);
        select.classList.add('native-search-select');
        select.tabIndex = -1;
        const input = document.createElement('input');
        input.type = 'text';
        input.className = 'searchable-select-input' + (isSmall ? ' sm' : '');
        input.placeholder = select.getAttribute('data-search-placeholder') || 'Search...';
        input.autocomplete = 'off';
        const menu = document.createElement('div');
        menu.className = 'searchable-select-menu';
        wrapper.appendChild(input);
        wrapper.appendChild(menu);
        function selectedText(){
            if (!select.value) return '';
            const opt = select.options[select.selectedIndex];
            return opt ? opt.text.replace(/\s+/g,' ').trim() : '';
        }
        function syncInput(){ input.value = selectedText(); }
        function chooseOption(opt){
            select.value = opt.value;
            select.dispatchEvent(new Event('change', {bubbles:true}));
            syncInput();
            wrapper.classList.remove('open');
        }
        function render(){
            const q = input.value.toLowerCase().trim();
            menu.innerHTML = '';
            let count = 0;
            Array.from(select.options).forEach(function(opt, idx){
                if (idx === 0 || !opt.value) return;
                const text = (opt.text || '').replace(/\s+/g,' ').trim();
                if (q && text.toLowerCase().indexOf(q) === -1) return;
                const div = document.createElement('div');
                div.className = 'searchable-select-option' + (opt.value === select.value ? ' active' : '');
                div.textContent = text;
                div.addEventListener('mousedown', function(e){ e.preventDefault(); chooseOption(opt); });
                menu.appendChild(div);
                count++;
            });
            if (!count) {
                const empty = document.createElement('div');
                empty.className = 'searchable-select-empty';
                empty.textContent = 'No matches found';
                menu.appendChild(empty);
            }
        }
        input.addEventListener('focus', function(){ wrapper.classList.add('open'); input.select(); render(); });
        input.addEventListener('input', function(){ wrapper.classList.add('open'); render(); });
        document.addEventListener('mousedown', function(e){ if (!wrapper.contains(e.target)) { wrapper.classList.remove('open'); syncInput(); } });
        select.addEventListener('change', syncInput);
        syncInput();
    }

    function updateTotals(){
        let lineCount = 0;
        let total = 0;
        lineBox.querySelectorAll('.recipe-line-card').forEach(function(card){
            lineCount++;
            const select = card.querySelector('.ingredient-select');
            const qty = Number(card.querySelector('.qty-input').value || 0);
            const waste = Number(card.querySelector('.waste-input').value || 0);
            const opt = select && select.options[select.selectedIndex] ? select.options[select.selectedIndex] : null;
            const cost = opt ? Number(opt.getAttribute('data-cost') || 0) : 0;
            const eff = qty + (qty * (waste / 100));
            const lineCost = eff * cost;
            total += lineCost;
            const preview = card.querySelector('.line-cost-preview');
            if (preview) preview.textContent = 'Cost: ' + money(lineCost) + (opt && opt.getAttribute('data-unit') ? ' | Unit: ' + opt.getAttribute('data-unit') : '');
            const title = card.querySelector('.line-title');
            if (title) title.textContent = 'Ingredient ' + lineCount;
        });
        document.getElementById('lineCount').textContent = String(lineCount);
        document.getElementById('estimatedCost').textContent = money(total);
    }

    function addLine(data){
        const node = template.content.cloneNode(true);
        const card = node.querySelector('.recipe-line-card');
        lineBox.appendChild(node);
        const added = lineBox.lastElementChild;
        initSearchableSelect(added.querySelector('.ingredient-select'));
        if (data) {
            added.querySelector('.ingredient-select').value = data.ingredient_item_id || '';
            added.querySelector('.ingredient-select').dispatchEvent(new Event('change', {bubbles:true}));
            added.querySelector('.qty-input').value = data.qty_required || '';
            added.querySelector('.waste-input').value = data.wastage_percent || 0;
            const notes = added.querySelector('input[name="line_notes[]"]');
            if (notes) notes.value = data.notes || '';
        }
        added.querySelector('.remove-line').addEventListener('click', function(){ added.remove(); updateTotals(); });
        added.querySelectorAll('select,input').forEach(function(el){ el.addEventListener('change', updateTotals); el.addEventListener('input', updateTotals); });
        updateTotals();
    }

    document.querySelectorAll('.js-search-select').forEach(initSearchableSelect);
    if (addLineBtn) addLineBtn.addEventListener('click', function(){ addLine(null); });
    if (existingLines && existingLines.length) existingLines.forEach(addLine); else addLine(null);

    if (menuSelect && recipeName) {
        menuSelect.addEventListener('change', function(){
            const opt = menuSelect.options[menuSelect.selectedIndex];
            if (opt) {
                if (!recipeName.value.trim()) recipeName.value = opt.getAttribute('data-name') || opt.text.trim();
                const t = opt.getAttribute('data-type') || '';
                if (t && recipeType) recipeType.value = t;
            }
        });
    }
});
</script>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
