<?php
require_once '../app/Models/Order.php';
require_once '../app/Models/Customer.php';
require_once '../app/Models/CakeFlavor.php';
require_once '../app/Models/CakeSize.php';
require_once '../app/Models/CakeType.php';
require_once '../app/Models/PickupLocation.php';
require_once '../app/Models/CakeOrderDetails.php';
require_once '../app/Models/CakeFlavorPricing.php';

class CakeOrderController {
    private $orderModel;
    private $customerModel;
    private $flavorModel;
    private $sizeModel;
    private $typeModel;
    private $locationModel;
    private $cakeDetailsModel;
    private $pricingModel;

    public function __construct() {
        $this->orderModel = new Order();
        $this->customerModel = new Customer();
        $this->flavorModel = new CakeFlavor();
        $this->sizeModel = new CakeSize();
        $this->typeModel = new CakeType();
        $this->locationModel = new PickupLocation();
        $this->cakeDetailsModel = new CakeOrderDetails();
        $this->pricingModel = new CakeFlavorPricing();
    }

    public function publicForm() {
        $flavors = $this->flavorModel->all();
        $sizes = $this->sizeModel->all();
        $types = $this->typeModel->all();
        $locations = $this->locationModel->all();
        
        require_once '../app/Views/cake_order/public_form.php';
    }

    public function index() {
        // Admin only
        if (!isset($_SESSION['user_id'])) {
            redirect('login');
            exit;
        }

        // Apply filters
        $filters = [];
        if (!empty($_GET['status'])) {
            $filters['status'] = $_GET['status'];
        }
        if (!empty($_GET['date_from'])) {
            $filters['date_from'] = $_GET['date_from'];
        }
        if (!empty($_GET['date_to'])) {
            $filters['date_to'] = $_GET['date_to'];
        }

        // Pagination
        $page = max(1, (int)($_GET['page'] ?? 1));
        $perPage = max(10, min(100, (int)($_GET['per_page'] ?? 20)));
        $filters['limit'] = $perPage;
        $filters['offset'] = ($page - 1) * $perPage;

        try {
            $orders = $this->orderModel->getCakeOrders($filters);
            $totalCount = $this->orderModel->getCakeOrdersCount($filters);
            $totalPages = ceil($totalCount / $perPage);
        } catch (Exception $e) {
            $_SESSION['error'] = 'Database error: ' . $e->getMessage();
            $orders = [];
            $totalCount = 0;
            $totalPages = 0;
        }

        // AJAX request - return JSON
        if (!empty($_GET['ajax'])) {
            header('Content-Type: application/json');
            echo json_encode([
                'orders' => $orders,
                'pagination' => [
                    'current_page' => $page,
                    'per_page' => $perPage,
                    'total_count' => $totalCount,
                    'total_pages' => $totalPages,
                    'has_prev' => $page > 1,
                    'has_next' => $page < $totalPages
                ]
            ]);
            exit;
        }
        
        // Regular request - return HTML
        $pagination = [
            'current_page' => $page,
            'per_page' => $perPage,
            'total_count' => $totalCount,
            'total_pages' => $totalPages
        ];
        
        require_once '../app/Views/cake_order/list.php';
    }

    public function create() {
        // Admin only
        if (!isset($_SESSION['user_id'])) {
            redirect('login');
            exit;
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            return $this->store();
        }

        // Load form data
        $customers = $this->customerModel->all();
        $flavors = $this->flavorModel->all();
        $sizes = $this->sizeModel->all();
        $types = $this->typeModel->all();
        $locations = $this->locationModel->all();

        require_once '../app/Views/cake_order/admin_form.php';
    }

    public function edit($id) {
        // Admin only
        if (!isset($_SESSION['user_id'])) {
            redirect('login');
            exit;
        }

        $order = $this->orderModel->find($id);
        if (!$order || !$order['is_cake_order']) {
            $_SESSION['error'] = 'Zamówienie nie zostało znalezione';
            redirect('cake-orders');
            exit;
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            return $this->update($id);
        }

        // Load form data
        $customers = $this->customerModel->all();
        $flavors = $this->flavorModel->all();
        $sizes = $this->sizeModel->all();
        $types = $this->typeModel->all();
        $locations = $this->locationModel->all();
        $cakeDetails = $this->cakeDetailsModel->findByOrderId($id);

        require_once '../app/Views/cake_order/admin_form.php';
    }

    public function view($id) {
        if (!isset($_SESSION['user_id'])) {
            redirect('login');
            exit;
        }

        $order = $this->orderModel->find($id);
        if (!$order || !$order['is_cake_order']) {
            $_SESSION['error'] = 'Cake order not found';
            redirect('cake-orders');
            exit;
        }

        // Check if AJAX request
        if (isset($_GET['ajax']) && $_GET['ajax'] == '1') {
            header('Content-Type: application/json');
            
            // Get complete cake order data with all joins
            $orderData = $this->orderModel->getCakeOrderComplete($id);
            
            if (!$orderData) {
                http_response_code(404);
                echo json_encode(['error' => 'Order not found']);
                exit;
            }
            
            echo json_encode($orderData);
            exit;
        }

        // Load all necessary data for the view
        $cakeDetailsModel = $this->cakeDetailsModel;
        $customerModel = $this->customerModel;
        $flavorModel = $this->flavorModel;
        $sizeModel = $this->sizeModel;
        $typeModel = $this->typeModel;
        $locationModel = $this->locationModel;

        $title = 'Cake Order #' . $order['id'];
        ob_start();
        require_once '../app/Views/cake_order/view.php';
        $content = ob_get_clean();
        require_once '../app/Views/layout.php';
    }

    private function store() {
        try {
            // Build delivery address if needed
            $deliveryAddress = trim($_POST['delivery_address'] ?? '');
            
            // Create order
            $orderData = [
                'customer_id' => $_POST['customer_id'],
                'is_cake_order' => 1,
                'pickup_date' => $_POST['pickup_date'],
                'pickup_time' => $_POST['pickup_time'],
                'pickup_location_id' => $_POST['pickup_location_id'],
                'delivery_address' => $deliveryAddress ?: null,
                'payment_method' => $_POST['payment_method'] ?? 'on_pickup',
                'deposit_amount' => $_POST['deposit_amount'] ?: null,
                'status' => $_POST['status'] ?? 'pending',
                'created_by' => $_SESSION['user_id']
            ];

            $orderId = $this->orderModel->create($orderData);

            // Handle file uploads
            $waferFile = $this->handleFileUpload('wafer_file', 'wafer');
            $referencePhoto = $this->handleFileUpload('reference_photo', 'reference');

            // Collect cake types
            $cakeTypeIds = isset($_POST['cake_types']) ? implode(',', $_POST['cake_types']) : null;

            // Create cake order details
            $cakeDetailsData = [
                'flavor_id' => $_POST['flavor_id'] !== 'custom' ? $_POST['flavor_id'] : null,
                'flavor_custom' => $_POST['flavor_custom'] ?? null,
                'size_id' => $_POST['size_id'] !== 'custom' ? $_POST['size_id'] : null,
                'size_custom' => $_POST['size_custom'] ?? null,
                'cake_type_ids' => $cakeTypeIds,
                'cake_type_custom' => $_POST['cake_type_custom'] ?? null,
                'has_inscription' => isset($_POST['has_inscription']) ? 1 : 0,
                'inscription_text' => $_POST['inscription_text'] ?? null,
                'has_candles' => isset($_POST['has_candles']) ? 1 : 0,
                'candles_count' => $_POST['candles_count'] ?? 0,
                'has_number_candle' => isset($_POST['has_number_candle']) ? 1 : 0,
                'number_candle_value' => $_POST['number_candle_value'] ?? null,
                'has_sparkler' => isset($_POST['has_sparkler']) ? 1 : 0,
                'has_wafer_photo' => isset($_POST['has_wafer_photo']) ? 1 : 0,
                'wafer_file' => $waferFile,
                'has_card' => isset($_POST['has_card']) ? 1 : 0,
                'card_text' => $_POST['card_text'] ?? null,
                'card_pattern' => $_POST['card_pattern'] ?? null,
                'has_figurine' => isset($_POST['has_figurine']) ? 1 : 0,
                'figurine_description' => $_POST['figurine_description'] ?? null,
                'reference_photo' => $referencePhoto,
                'notes' => $_POST['notes'] ?? null
            ];

            $this->cakeDetailsModel->create($orderId, $cakeDetailsData);

            $_SESSION['success'] = 'Zamówienie zostało utworzone pomyślnie!';
            redirect('cake-orders');
            
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
            redirect('cake-orders/create');
        }
    }

    private function update($id) {
        try {
            // Build delivery address if needed
            $deliveryAddress = trim($_POST['delivery_address'] ?? '');
            
            // Update order
            $orderData = [
                'customer_id' => $_POST['customer_id'],
                'pickup_date' => $_POST['pickup_date'],
                'pickup_time' => $_POST['pickup_time'],
                'pickup_location_id' => $_POST['pickup_location_id'],
                'delivery_address' => $deliveryAddress ?: null,
                'payment_method' => $_POST['payment_method'] ?? 'on_pickup',
                'deposit_amount' => $_POST['deposit_amount'] ?: null,
                'status' => $_POST['status']
            ];

            $this->orderModel->update($id, $orderData);

            // Handle file uploads (only if new files uploaded)
            $waferFile = $this->handleFileUpload('wafer_file', 'wafer');
            $referencePhoto = $this->handleFileUpload('reference_photo', 'reference');

            // Get existing cake details to preserve files if not updated
            $existingDetails = $this->cakeDetailsModel->findByOrderId($id);
            
            // Collect cake types
            $cakeTypeIds = isset($_POST['cake_types']) ? implode(',', $_POST['cake_types']) : null;

            // Update cake order details
            $cakeDetailsData = [
                'flavor_id' => $_POST['flavor_id'] !== 'custom' ? $_POST['flavor_id'] : null,
                'flavor_custom' => $_POST['flavor_custom'] ?? null,
                'size_id' => $_POST['size_id'] !== 'custom' ? $_POST['size_id'] : null,
                'size_custom' => $_POST['size_custom'] ?? null,
                'cake_type_ids' => $cakeTypeIds,
                'cake_type_custom' => $_POST['cake_type_custom'] ?? null,
                'has_inscription' => isset($_POST['has_inscription']) ? 1 : 0,
                'inscription_text' => $_POST['inscription_text'] ?? null,
                'has_candles' => isset($_POST['has_candles']) ? 1 : 0,
                'candles_count' => $_POST['candles_count'] ?? 0,
                'has_number_candle' => isset($_POST['has_number_candle']) ? 1 : 0,
                'number_candle_value' => $_POST['number_candle_value'] ?? null,
                'has_sparkler' => isset($_POST['has_sparkler']) ? 1 : 0,
                'has_wafer_photo' => isset($_POST['has_wafer_photo']) ? 1 : 0,
                'wafer_file' => $waferFile ?: ($existingDetails['wafer_file'] ?? null),
                'has_card' => isset($_POST['has_card']) ? 1 : 0,
                'card_text' => $_POST['card_text'] ?? null,
                'card_pattern' => $_POST['card_pattern'] ?? null,
                'has_figurine' => isset($_POST['has_figurine']) ? 1 : 0,
                'figurine_description' => $_POST['figurine_description'] ?? null,
                'reference_photo' => $referencePhoto ?: ($existingDetails['reference_photo'] ?? null),
                'notes' => $_POST['notes'] ?? null
            ];

            $this->cakeDetailsModel->update($id, $cakeDetailsData);

            $_SESSION['success'] = 'Zamówienie zostało zaktualizowane!';
            redirect('cake-orders');
            
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
            redirect('cake-orders/edit/' . $id);
        }
    }

    public function delete($id) {
        // Admin only
        if (!isset($_SESSION['user_id'])) {
            redirect('login');
            exit;
        }

        try {
            $this->orderModel->delete($id);
            $_SESSION['success'] = 'Zamówienie zostało usunięte';
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
        }

        redirect('cake-orders');
    }

    public function submit() {
        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            redirect('cake-order');
            exit;
        }

        try {
            // Find or create customer
            $customerData = [
                'name' => trim($_POST['first_name'] . ' ' . $_POST['last_name']),
                'phone' => trim($_POST['phone'] ?? ''),
                'email' => trim($_POST['email'] ?? ''),
                'type' => 'individual'
            ];

            // Check if customer exists by phone
            $existingCustomer = $this->customerModel->findByPhone($customerData['phone']);
            if ($existingCustomer) {
                $customerId = $existingCustomer['id'];
            } else {
                $customerId = $this->customerModel->create($customerData);
            }

            // Build delivery address if needed
            $deliveryAddress = null;
            $pickupLocationId = $_POST['pickup_location_id'] ?? null;
            $location = $this->locationModel->find($pickupLocationId);
            
            if ($location && stripos($location['name'], 'dostawa') !== false) {
                $deliveryAddress = trim(implode(', ', array_filter([
                    $_POST['delivery_street'] ?? '',
                    $_POST['delivery_number'] ?? '',
                    $_POST['delivery_city'] ?? '',
                    $_POST['delivery_postal'] ?? ''
                ])));
            }

            // Create order
            $orderData = [
                'customer_id' => $customerId,
                'is_cake_order' => 1,
                'pickup_date' => $_POST['pickup_date'] ?? null,
                'pickup_time' => $_POST['pickup_time'] ?? null,
                'pickup_location_id' => $pickupLocationId,
                'delivery_address' => $deliveryAddress,
                'payment_method' => $_POST['payment_method'] ?? 'on_pickup',
                'deposit_amount' => $_POST['deposit_amount'] ?? null,
                'status' => 'pending',
                'created_by' => $_SESSION['user_id'] ?? null
            ];

            $orderId = $this->orderModel->create($orderData);

            // Handle file uploads
            $waferFile = $this->handleFileUpload('wafer_file', 'wafer');
            $referencePhoto = $this->handleFileUpload('reference_photo', 'reference');

            // Collect cake types
            $cakeTypeIds = isset($_POST['cake_types']) ? implode(',', $_POST['cake_types']) : null;

            // Calculate pricing
            $pricing = $this->calculatePricing($_POST, $cakeTypeIds);

            // Create cake order details
            $cakeDetailsData = [
                'flavor_id' => $_POST['flavor_id'] ?? null,
                'flavor_custom' => $_POST['flavor_custom'] ?? null,
                'size_id' => $_POST['size_id'] ?? null,
                'size_custom' => $_POST['size_custom'] ?? null,
                'cake_type_ids' => $cakeTypeIds,
                'cake_type_custom' => $_POST['cake_type_custom'] ?? null,
                'has_inscription' => isset($_POST['has_inscription']) && $_POST['has_inscription'] == '1' ? 1 : 0,
                'inscription_text' => $_POST['inscription_text'] ?? null,
                'inscription_price' => $pricing['inscription'],
                'has_candles' => isset($_POST['has_candles']) && $_POST['has_candles'] == '1' ? 1 : 0,
                'candles_price' => $pricing['candles'],
                'candles_count' => $_POST['candles_count'] ?? 0,
                'has_number_candle' => isset($_POST['has_number_candle']) && $_POST['has_number_candle'] == '1' ? 1 : 0,
                'number_candle_price' => $pricing['number_candle'],
                'number_candle_value' => $_POST['number_candle_value'] ?? null,
                'has_sparkler' => isset($_POST['has_sparkler']) && $_POST['has_sparkler'] == '1' ? 1 : 0,
                'sparkler_price' => $pricing['sparkler'],
                'has_wafer_photo' => isset($_POST['has_wafer_photo']) && $_POST['has_wafer_photo'] == '1' ? 1 : 0,
                'wafer_photo_price' => $pricing['wafer'],
                'wafer_file' => $waferFile,
                'has_card' => isset($_POST['has_card']) && $_POST['has_card'] == '1' ? 1 : 0,
                'card_price' => $pricing['card'],
                'card_text' => $_POST['card_text'] ?? null,
                'card_pattern' => $_POST['card_pattern'] ?? null,
                'has_figurine' => isset($_POST['has_figurine']) && $_POST['has_figurine'] == '1' ? 1 : 0,
                'figurine_price' => $pricing['figurine'],
                'figurine_description' => $_POST['figurine_description'] ?? null,
                'reference_photo' => $referencePhoto,
                'notes' => $_POST['notes'] ?? null,
                'base_price' => $pricing['base'],
                'extras_price' => $pricing['extras'],
                'total_price' => $pricing['total']
            ];

            $this->cakeDetailsModel->create($orderId, $cakeDetailsData);

            $_SESSION['success'] = 'Zamówienie zostało przyjęte! Numer zamówienia: #' . $orderId;
            redirect('cake-order');
            
        } catch (Exception $e) {
            $_SESSION['error'] = 'Błąd: ' . $e->getMessage();
            redirect('cake-order');
        }
    }

    private function calculatePricing($postData, $cakeTypeIds) {
        $basePrice = 0;
        $extrasPrice = 0;
        
        // Get base price (flavor + size)
        if (!empty($postData['flavor_id']) && !empty($postData['size_id'])) {
            $basePrice = $this->pricingModel->getPrice($postData['flavor_id'], $postData['size_id']);
        }
        
        // Add cake type prices
        if (!empty($cakeTypeIds)) {
            $typeIds = explode(',', $cakeTypeIds);
            foreach ($typeIds as $typeId) {
                $type = $this->typeModel->find(trim($typeId));
                if ($type) {
                    $basePrice += (float)($type['price'] ?? 0);
                }
            }
        }
        
        // Individual prices for extras (these can be set in settings or hardcoded)
        $pricing = [
            'base' => $basePrice,
            'inscription' => (isset($postData['has_inscription']) && $postData['has_inscription'] == '1') ? (float)($postData['inscription_price'] ?? 10) : 0,
            'candles' => (isset($postData['has_candles']) && $postData['has_candles'] == '1') ? (float)($postData['candles_price'] ?? 5) : 0,
            'number_candle' => (isset($postData['has_number_candle']) && $postData['has_number_candle'] == '1') ? (float)($postData['number_candle_price'] ?? 15) : 0,
            'sparkler' => (isset($postData['has_sparkler']) && $postData['has_sparkler'] == '1') ? (float)($postData['sparkler_price'] ?? 5) : 0,
            'wafer' => (isset($postData['has_wafer_photo']) && $postData['has_wafer_photo'] == '1') ? (float)($postData['wafer_photo_price'] ?? 20) : 0,
            'card' => (isset($postData['has_card']) && $postData['has_card'] == '1') ? (float)($postData['card_price'] ?? 10) : 0,
            'figurine' => (isset($postData['has_figurine']) && $postData['has_figurine'] == '1') ? (float)($postData['figurine_price'] ?? 30) : 0,
        ];
        
        $extrasPrice = $pricing['inscription'] + $pricing['candles'] + $pricing['number_candle'] + 
                       $pricing['sparkler'] + $pricing['wafer'] + $pricing['card'] + $pricing['figurine'];
        
        $pricing['extras'] = $extrasPrice;
        $pricing['total'] = $basePrice + $extrasPrice;
        
        return $pricing;
    }

    private function handleFileUpload($fieldName, $prefix) {
        if (empty($_FILES[$fieldName]['tmp_name'])) {
            return null;
        }

        $file = $_FILES[$fieldName];
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
        
        if (!in_array($ext, $allowed)) {
            return null;
        }

        $uploadDir = __DIR__ . '/../../public/uploads/cakes';
        if (!is_dir($uploadDir)) {
            @mkdir($uploadDir, 0777, true);
            @chmod($uploadDir, 0777);
        }

        $fileName = $prefix . '_' . time() . '_' . uniqid() . '.' . $ext;
        $fullPath = $uploadDir . '/' . $fileName;

        if (@move_uploaded_file($file['tmp_name'], $fullPath)) {
            @chmod($fullPath, 0644);
            return '/samanta_crm/public/uploads/cakes/' . $fileName;
        }

        return null;
    }
}
