<?php

class MenuController
{
    private $db;
    
    public function __construct()
    {
        require_once __DIR__ . '/../../bootstrap/db.php';
        global $pdo;
        $this->db = $pdo;
        
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        $this->checkAuth();
    }
    
    private function checkAuth()
    {
        if (!isset($_SESSION['user_id'])) {
            header('Location: /samanta_crm/login');
            exit;
        }
    }
    
    private function render($view, $data = [])
    {
        extract($data);
        ob_start();
        require_once __DIR__ . '/../Views/' . $view . '.php';
        $content = ob_get_clean();
        
        require_once __DIR__ . '/../Views/layout.php';
    }
    
    // ==================== MENU ITEMS ====================
    
    public function items()
    {
        $search = $_GET['search'] ?? '';
        $category = $_GET['category'] ?? '';
        $location = $_GET['location'] ?? '';
        $hideNoLocation = isset($_GET['hide_no_location']);
        
        // Build query
        $sql = "SELECT mi.*, mc.name as category_name,
                GROUP_CONCAT(DISTINCT l.name ORDER BY l.display_order SEPARATOR ', ') as location_names,
                GROUP_CONCAT(DISTINCT mil.location_id) as location_ids
                FROM menu_items mi
                LEFT JOIN menu_categories mc ON mi.menu_category_id = mc.id
                LEFT JOIN menu_item_locations mil ON mi.id = mil.menu_item_id
                LEFT JOIN locations l ON mil.location_id = l.id
                WHERE 1=1";
        
        $params = [];
        
        if ($search) {
            $sql .= " AND (mi.name_pl LIKE ? OR mi.name_en LIKE ? OR mi.code LIKE ?)";
            $searchTerm = "%$search%";
            $params[] = $searchTerm;
            $params[] = $searchTerm;
            $params[] = $searchTerm;
        }
        
        if ($category) {
            $sql .= " AND mi.menu_category_id = ?";
            $params[] = $category;
        }
        
        if ($location) {
            $sql .= " AND EXISTS (
                SELECT 1 FROM menu_item_locations mil2 
                WHERE mil2.menu_item_id = mi.id AND mil2.location_id = ?
            )";
            $params[] = $location;
        }
        
        $sql .= " GROUP BY mi.id";
        
        // Filter out items without locations if checkbox is checked
        if ($hideNoLocation) {
            $sql .= " HAVING location_ids IS NOT NULL";
        }
        
        $sql .= " ORDER BY mc.sort_order ASC, mi.display_order ASC, mi.name_pl ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute($params);
        $allItems = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Group items by category
        $groupedItems = [];
        foreach ($allItems as $item) {
            $catId = $item['menu_category_id'] ?? 0;
            $catName = $item['category_name'] ?? 'Bez kategorii';
            
            if (!isset($groupedItems[$catId])) {
                $groupedItems[$catId] = [
                    'id' => $catId,
                    'name' => $catName,
                    'items' => []
                ];
            }
            $groupedItems[$catId]['items'][] = $item;
        }
        
        // Get categories for filter
        $categories = $this->db->query("SELECT * FROM menu_categories ORDER BY sort_order, name")->fetchAll(PDO::FETCH_ASSOC);
        
        // Get locations for filter
        $locations = $this->db->query("SELECT * FROM locations WHERE is_active = 1 ORDER BY display_order")->fetchAll(PDO::FETCH_ASSOC);
        
        $this->render('menu/items', [
            'groupedItems' => $groupedItems,
            'categories' => $categories,
            'locations' => $locations,
            'search' => $search,
            'selectedCategory' => $category,
            'selectedLocation' => $location,
            'hideNoLocation' => $hideNoLocation
        ]);
    }
    
    public function createItem()
    {
        $categories = $this->db->query("SELECT * FROM menu_categories ORDER BY sort_order, name")->fetchAll(PDO::FETCH_ASSOC);
        $locations = $this->db->query("SELECT * FROM locations WHERE is_active = 1 ORDER BY display_order")->fetchAll(PDO::FETCH_ASSOC);
        
        $this->render('menu/create_item', [
            'categories' => $categories,
            'locations' => $locations
        ]);
    }
    
    public function storeItem()
    {
        try {
            $this->db->beginTransaction();
            
            // Handle image upload
            $imageUrl = null;
            if (!empty($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
                $imageUrl = $this->uploadImage($_FILES['image']);
            }
            
            // Insert menu item
            $sql = "INSERT INTO menu_items (
                code, menu_category_id, name_pl, name_en, after_name_pl, after_name_en,
                description_pl, description_en, image_url,
                price_1_prefix_pl, price_1, price_1_prefix_en,
                price_2_prefix_pl, price_2, price_2_prefix_en,
                price_3_prefix_pl, price_3, price_3_prefix_en,
                display_order, font_size, custom_css, border_style, is_active
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([
                $_POST['code'] ?? null,
                $_POST['menu_category_id'] ?? null,
                $_POST['name_pl'],
                $_POST['name_en'] ?? null,
                $_POST['after_name_pl'] ?? null,
                $_POST['after_name_en'] ?? null,
                $_POST['description_pl'] ?? null,
                $_POST['description_en'] ?? null,
                $imageUrl,
                $_POST['price_1_prefix_pl'] ?? null,
                $_POST['price_1'] ?? null,
                $_POST['price_1_prefix_en'] ?? null,
                $_POST['price_2_prefix_pl'] ?? null,
                $_POST['price_2'] ?? null,
                $_POST['price_2_prefix_en'] ?? null,
                $_POST['price_3_prefix_pl'] ?? null,
                $_POST['price_3'] ?? null,
                $_POST['price_3_prefix_en'] ?? null,
                $_POST['display_order'] ?? 0,
                $_POST['font_size'] ?? null,
                $_POST['custom_css'] ?? null,
                $_POST['border_style'] ?? null,
                isset($_POST['is_active']) ? 1 : 0
            ]);
            
            $itemId = $this->db->lastInsertId();
            
            // Insert location associations
            if (!empty($_POST['locations'])) {
                $locationStmt = $this->db->prepare("INSERT INTO menu_item_locations (menu_item_id, location_id) VALUES (?, ?)");
                foreach ($_POST['locations'] as $locationId) {
                    $locationStmt->execute([$itemId, $locationId]);
                }
            }
            
            $this->db->commit();
            
            $_SESSION['success'] = 'Pozycja menu została dodana!';
            header('Location: /samanta_crm/menu/items');
            exit;
            
        } catch (Exception $e) {
            $this->db->rollBack();
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
            header('Location: /samanta_crm/menu/items/create');
            exit;
        }
    }
    
    public function editItem($id)
    {
        $item = $this->db->query("SELECT * FROM menu_items WHERE id = $id")->fetch(PDO::FETCH_ASSOC);
        
        if (!$item) {
            $_SESSION['error'] = 'Nie znaleziono pozycji menu';
            header('Location: /samanta_crm/menu/items');
            exit;
        }
        
        $categories = $this->db->query("SELECT * FROM menu_categories ORDER BY sort_order, name")->fetchAll(PDO::FETCH_ASSOC);
        $locations = $this->db->query("SELECT * FROM locations WHERE is_active = 1 ORDER BY display_order")->fetchAll(PDO::FETCH_ASSOC);
        
        // Get selected locations
        $selectedLocations = $this->db->query("SELECT location_id FROM menu_item_locations WHERE menu_item_id = $id")->fetchAll(PDO::FETCH_COLUMN);
        
        $this->render('menu/edit_item', [
            'item' => $item,
            'categories' => $categories,
            'locations' => $locations,
            'selectedLocations' => $selectedLocations
        ]);
    }
    
    public function updateItem($id)
    {
        try {
            $this->db->beginTransaction();
            
            // Get current item for image
            $currentItem = $this->db->query("SELECT image_url FROM menu_items WHERE id = $id")->fetch(PDO::FETCH_ASSOC);
            
            // Handle image upload
            $imageUrl = $currentItem['image_url'] ?? null;
            if (!empty($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
                $imageUrl = $this->uploadImage($_FILES['image']);
                // Delete old image if exists
                if ($currentItem['image_url']) {
                    $this->deleteImage($currentItem['image_url']);
                }
            }
            
            // Update menu item
            $sql = "UPDATE menu_items SET
                code = ?, menu_category_id = ?, name_pl = ?, name_en = ?,
                after_name_pl = ?, after_name_en = ?,
                description_pl = ?, description_en = ?, image_url = ?,
                price_1_prefix_pl = ?, price_1 = ?, price_1_prefix_en = ?,
                price_2_prefix_pl = ?, price_2 = ?, price_2_prefix_en = ?,
                price_3_prefix_pl = ?, price_3 = ?, price_3_prefix_en = ?,
                display_order = ?, font_size = ?, custom_css = ?, border_style = ?, is_active = ?
                WHERE id = ?";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute([
                $_POST['code'] ?? null,
                $_POST['menu_category_id'] ?? null,
                $_POST['name_pl'],
                $_POST['name_en'] ?? null,
                $_POST['after_name_pl'] ?? null,
                $_POST['after_name_en'] ?? null,
                $_POST['description_pl'] ?? null,
                $_POST['description_en'] ?? null,
                $imageUrl,
                $_POST['price_1_prefix_pl'] ?? null,
                $_POST['price_1'] ?? null,
                $_POST['price_1_prefix_en'] ?? null,
                $_POST['price_2_prefix_pl'] ?? null,
                $_POST['price_2'] ?? null,
                $_POST['price_2_prefix_en'] ?? null,
                $_POST['price_3_prefix_pl'] ?? null,
                $_POST['price_3'] ?? null,
                $_POST['price_3_prefix_en'] ?? null,
                $_POST['display_order'] ?? 0,
                $_POST['font_size'] ?? null,
                $_POST['custom_css'] ?? null,
                $_POST['border_style'] ?? null,
                isset($_POST['is_active']) ? 1 : 0,
                $id
            ]);
            
            // Update location associations
            $this->db->exec("DELETE FROM menu_item_locations WHERE menu_item_id = $id");
            
            if (!empty($_POST['locations'])) {
                $locationStmt = $this->db->prepare("INSERT INTO menu_item_locations (menu_item_id, location_id) VALUES (?, ?)");
                foreach ($_POST['locations'] as $locationId) {
                    $locationStmt->execute([$id, $locationId]);
                }
            }
            
            $this->db->commit();
            
            $_SESSION['success'] = 'Pozycja menu została zaktualizowana!';
            header('Location: /samanta_crm/menu/items');
            exit;
            
        } catch (Exception $e) {
            $this->db->rollBack();
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
            header('Location: /samanta_crm/menu/items/' . $id . '/edit');
            exit;
        }
    }
    
    public function deleteItem($id)
    {
        try {
            $this->db->exec("DELETE FROM menu_items WHERE id = $id");
            $_SESSION['success'] = 'Pozycja menu została usunięta!';
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
        }
        
        header('Location: /samanta_crm/menu/items');
        exit;
    }
    
    // ==================== LOCATIONS ====================
    
    public function locations()
    {
        $locations = $this->db->query("SELECT * FROM locations ORDER BY display_order ASC")->fetchAll(PDO::FETCH_ASSOC);
        
        $this->render('menu/locations', [
            'locations' => $locations
        ]);
    }
    
    public function storeLocation()
    {
        try {
            $stmt = $this->db->prepare("INSERT INTO locations (name, slug, address, phone, is_active, display_order) VALUES (?, ?, ?, ?, ?, ?)");
            $slug = strtolower(preg_replace('/[^a-z0-9]+/', '-', iconv('UTF-8', 'ASCII//TRANSLIT', $_POST['name'])));
            
            $stmt->execute([
                $_POST['name'],
                $slug,
                $_POST['address'] ?? null,
                $_POST['phone'] ?? null,
                isset($_POST['is_active']) ? 1 : 0,
                $_POST['display_order'] ?? 0
            ]);
            
            $_SESSION['success'] = 'Lokalizacja została dodana!';
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
        }
        
        header('Location: /samanta_crm/menu/locations');
        exit;
    }
    
    public function updateLocation($id)
    {
        try {
            $stmt = $this->db->prepare("UPDATE locations SET name = ?, address = ?, phone = ?, is_active = ?, display_order = ? WHERE id = ?");
            
            $stmt->execute([
                $_POST['name'],
                $_POST['address'] ?? null,
                $_POST['phone'] ?? null,
                isset($_POST['is_active']) ? 1 : 0,
                $_POST['display_order'] ?? 0,
                $id
            ]);
            
            $_SESSION['success'] = 'Lokalizacja została zaktualizowana!';
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
        }
        
        header('Location: /samanta_crm/menu/locations');
        exit;
    }
    
    public function deleteLocation($id)
    {
        try {
            $this->db->exec("DELETE FROM locations WHERE id = $id");
            $_SESSION['success'] = 'Lokalizacja została usunięta!';
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
        }
        
        header('Location: /samanta_crm/menu/locations');
        exit;
    }
    
    /**
     * Upload image file and return the URL path
     */
    private function uploadImage($file)
    {
        // Validate file type
        $allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
        if (!in_array($file['type'], $allowedTypes)) {
            throw new Exception('Invalid file type. Only JPG, PNG, GIF, and WEBP are allowed.');
        }
        
        // Validate file size (5MB max)
        $maxSize = 5 * 1024 * 1024; // 5MB in bytes
        if ($file['size'] > $maxSize) {
            throw new Exception('File size exceeds 5MB limit.');
        }
        
        // Create upload directory if it doesn't exist
        $uploadDir = __DIR__ . '/../../public/uploads/menu/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        
        // Generate unique filename
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        $filename = time() . '_' . bin2hex(random_bytes(8)) . '.' . $extension;
        $targetPath = $uploadDir . $filename;
        
        // Move uploaded file
        if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
            throw new Exception('Failed to upload file.');
        }
        
        // Return relative URL path
        return '/uploads/menu/' . $filename;
    }
    
    /**
     * Delete image file
     */
    private function deleteImage($imageUrl)
    {
        if (!$imageUrl) {
            return;
        }
        
        $filePath = __DIR__ . '/../../public' . $imageUrl;
        if (file_exists($filePath)) {
            unlink($filePath);
        }
    }
    
    /**
     * Toggle location for menu item
     */
    public function toggleLocation()
    {
        header('Content-Type: application/json');
        
        try {
            $input = json_decode(file_get_contents('php://input'), true);
            $itemId = $input['item_id'] ?? null;
            $locationId = $input['location_id'] ?? null;
            $enabled = $input['enabled'] ?? false;
            
            if (!$itemId || !$locationId) {
                echo json_encode(['success' => false, 'error' => 'Invalid data']);
                return;
            }
            
            if ($enabled) {
                // Add location
                $stmt = $this->db->prepare("INSERT IGNORE INTO menu_item_locations (menu_item_id, location_id) VALUES (?, ?)");
                $stmt->execute([$itemId, $locationId]);
            } else {
                // Remove location
                $stmt = $this->db->prepare("DELETE FROM menu_item_locations WHERE menu_item_id = ? AND location_id = ?");
                $stmt->execute([$itemId, $locationId]);
            }
            
            echo json_encode(['success' => true]);
            
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
    }
    
    /**
     * Reorder menu items
     */
    public function reorderItems()
    {
        header('Content-Type: application/json');
        
        try {
            $input = json_decode(file_get_contents('php://input'), true);
            $order = $input['order'] ?? [];
            
            if (empty($order)) {
                echo json_encode(['success' => false, 'error' => 'No order data']);
                return;
            }
            
            // Update display_order for each item
            foreach ($order as $index => $itemId) {
                $stmt = $this->db->prepare("UPDATE menu_items SET display_order = ? WHERE id = ?");
                $stmt->execute([$index, $itemId]);
            }
            
            echo json_encode(['success' => true]);
            
        } catch (Exception $e) {
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
    }
    
    /**
     * Preview menu for a location
     */
    public function preview($locationId)
    {
        // Get location details
        $stmt = $this->db->prepare("SELECT * FROM locations WHERE id = ?");
        $stmt->execute([$locationId]);
        $location = $stmt->fetch(PDO::FETCH_ASSOC);
        
        if (!$location) {
            die('Location not found');
        }
        
        // Get menu items for this location, grouped by category
        $sql = "SELECT mi.*, mc.name as category_name, mc.name_en as category_name_en, mc.sort_order as category_order
                FROM menu_items mi
                INNER JOIN menu_categories mc ON mi.menu_category_id = mc.id
                INNER JOIN menu_item_locations mil ON mi.id = mil.menu_item_id
                WHERE mil.location_id = ? AND mi.is_active = 1
                ORDER BY mc.sort_order ASC, mi.display_order ASC, mi.name_pl ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$locationId]);
        $allItems = $stmt->fetchAll(PDO::FETCH_ASSOC);
        
        // Group by category
        $groupedItems = [];
        foreach ($allItems as $item) {
            $catName = $item['category_name'] ?? 'Inne';
            if (!isset($groupedItems[$catName])) {
                $groupedItems[$catName] = [
                    'name' => $catName,
                    'name_en' => $item['category_name_en'] ?? '',
                    'items' => []
                ];
            }
            $groupedItems[$catName]['items'][] = $item;
        }
        
        // Render preview
        require_once __DIR__ . '/../Views/menu/preview.php';
    }
}
