<?php
/**
 * Server Create Order API - Dine-In Orders
 * Allows servers to create orders for their assigned tables
 */

session_start();
header('Content-Type: application/json');
require_once 'config.php';

// Check server authentication
if (!isset($_SESSION['server_id'])) {
    http_response_code(401);
    echo json_encode([
        'success' => false,
        'message' => 'Unauthorized access'
    ]);
    exit;
}

$server_id = $_SESSION['server_id'];

// Get request body
$input = json_decode(file_get_contents('php://input'), true);

if (!$input || !isset($input['table_id']) || !isset($input['items'])) {
    echo json_encode([
        'success' => false,
        'message' => 'Invalid request. Missing table_id or items.'
    ]);
    exit;
}

$table_id = (int)$input['table_id'];
$items = $input['items'];
$special_requests = isset($input['special_requests']) ? $input['special_requests'] : '';
$requested_assignment_id = isset($input['assignment_id']) ? (int)$input['assignment_id'] : 0;
$table_source = isset($input['table_source']) ? strtolower(trim($input['table_source'])) : 'restaurant';
$table_source = ($table_source === 'online') ? 'online' : 'restaurant';
$table_number = isset($input['table_number']) ? trim((string)$input['table_number']) : '';

if (empty($items)) {
    echo json_encode([
        'success' => false,
        'message' => 'Cannot create order with no items'
    ]);
    exit;
}

try {
    // Verify that the table assignment is assigned to this server and get the active assignment id.
    $assignment_id = null;
    if ($table_source === 'online') {
        // Online booking assignments are stored in online_table_bookings.
        $checkServerCol = $conn->query("SHOW COLUMNS FROM online_table_bookings LIKE 'assigned_server_id'");
        if (!$checkServerCol || $checkServerCol->num_rows === 0) {
            @$conn->query("ALTER TABLE online_table_bookings ADD COLUMN assigned_server_id INT NULL AFTER online_table_id");
        }

        if ($requested_assignment_id > 0) {
            $stmt = $conn->prepare("
                SELECT otb.id, b.booking_date, b.slot_time
                FROM online_table_bookings otb
                INNER JOIN bookings b ON b.id = otb.booking_id
                WHERE otb.id = ?
                  AND otb.online_table_id = ?
                  AND otb.assigned_server_id = ?
                  AND b.status IN ('pending', 'confirmed', 'checked_in')
                  AND otb.allocation_status = 'allocated'
                LIMIT 1
            ");
            $stmt->bind_param("iii", $requested_assignment_id, $table_id, $server_id);
        } else {
            $stmt = $conn->prepare("
                SELECT otb.id, b.booking_date, b.slot_time
                FROM online_table_bookings otb
                INNER JOIN bookings b ON b.id = otb.booking_id
                WHERE otb.online_table_id = ?
                  AND otb.assigned_server_id = ?
                  AND b.status IN ('pending', 'confirmed', 'checked_in')
                  AND otb.allocation_status = 'allocated'
                ORDER BY b.booking_date DESC, b.slot_time DESC
                LIMIT 1
            ");
            $stmt->bind_param("ii", $table_id, $server_id);
        }
    } else {
        if ($requested_assignment_id > 0) {
            $stmt = $conn->prepare("
                SELECT ta.id FROM table_assignments ta
                WHERE ta.id = ? AND ta.table_id = ? AND ta.server_id = ? AND ta.status = 'assigned'
                LIMIT 1
            ");
            $stmt->bind_param("iii", $requested_assignment_id, $table_id, $server_id);
        } else {
            $stmt = $conn->prepare("
                SELECT ta.id FROM table_assignments ta
                WHERE ta.table_id = ? AND ta.server_id = ? AND ta.status = 'assigned'
                ORDER BY ta.assigned_at DESC
                LIMIT 1
            ");
            $stmt->bind_param("ii", $table_id, $server_id);
        }
    }
    $stmt->execute();
    $result = $stmt->get_result();
    
    if ($result->num_rows === 0) {
        echo json_encode([
            'success' => false,
            'message' => 'You do not have permission to create orders for this table'
        ]);
        $stmt->close();
        exit;
    }
    $assignment_row = $result->fetch_assoc();
    $assignment_id = (int)$assignment_row['id'];
    $stmt->close();

    if ($table_source === 'online') {
        $booking_date = isset($assignment_row['booking_date']) ? trim((string)$assignment_row['booking_date']) : '';
        $slot_time = isset($assignment_row['slot_time']) ? trim((string)$assignment_row['slot_time']) : '';
        if ($booking_date !== '' && $slot_time !== '') {
            try {
                $restaurant_tz = new DateTimeZone('Asia/Kolkata');
                $slot_start = new DateTime($booking_date . ' ' . $slot_time, $restaurant_tz);
                $now = new DateTime('now', $restaurant_tz);
                if ($now < $slot_start) {
                    echo json_encode([
                        'success' => false,
                        'message' => 'Order taking opens at slot time (' . $slot_start->format('Y-m-d H:i') . ' IST)'
                    ]);
                    exit;
                }
            } catch (Exception $e) {
                // Ignore parsing failure and continue with normal flow.
            }
        }
    }

    // Begin transaction
    $conn->begin_transaction();

    // Create dine-in order
    // Generate order number
    $order_number = ($table_source === 'online' ? 'ONL-' : 'DIN-') . $table_id . '-' . time();
    $order_date = date('Y-m-d H:i:s');
    $status = 'pending';
    $payment_status = 'unpaid';
    
    // Create dine_in_orders table if it doesn't exist
    $create_table_sql = "CREATE TABLE IF NOT EXISTS dine_in_orders (
        id INT PRIMARY KEY AUTO_INCREMENT,
        assignment_id INT NULL,
        server_id INT NOT NULL,
        table_id INT NULL,
        order_number VARCHAR(50) UNIQUE,
        total_amount DECIMAL(10, 2) DEFAULT 0,
        status VARCHAR(50) DEFAULT 'pending' COMMENT 'pending, confirmed, preparing, ready, completed, cancelled',
        payment_status VARCHAR(50) DEFAULT 'unpaid' COMMENT 'unpaid, paid, partial',
        special_requests TEXT,
        notes TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        FOREIGN KEY (assignment_id) REFERENCES table_assignments(id) ON DELETE SET NULL,
        FOREIGN KEY (server_id) REFERENCES servers(id) ON DELETE CASCADE,
        FOREIGN KEY (table_id) REFERENCES restaurant_tables(id) ON DELETE SET NULL
    )";
    $conn->query($create_table_sql);

    // Backward-compatible migration: add assignment_id for existing installations.
    $check_assignment_col_sql = "SHOW COLUMNS FROM dine_in_orders LIKE 'assignment_id'";
    $assignment_col_result = $conn->query($check_assignment_col_sql);
    if (!$assignment_col_result || $assignment_col_result->num_rows === 0) {
        $conn->query("ALTER TABLE dine_in_orders ADD COLUMN assignment_id INT NULL AFTER id");
        $conn->query("CREATE INDEX idx_dine_in_orders_assignment_id ON dine_in_orders(assignment_id)");
    }

    // Backward-compatible migration for separate source tracking (restaurant vs online).
    $source_type_col = $conn->query("SHOW COLUMNS FROM dine_in_orders LIKE 'table_source'");
    if (!$source_type_col || $source_type_col->num_rows === 0) {
        $conn->query("ALTER TABLE dine_in_orders ADD COLUMN table_source VARCHAR(20) NOT NULL DEFAULT 'restaurant' AFTER table_id");
    }
    $source_table_col = $conn->query("SHOW COLUMNS FROM dine_in_orders LIKE 'source_table_id'");
    if (!$source_table_col || $source_table_col->num_rows === 0) {
        $conn->query("ALTER TABLE dine_in_orders ADD COLUMN source_table_id INT NULL AFTER table_source");
        $conn->query("CREATE INDEX idx_dine_in_orders_source_table ON dine_in_orders(source_table_id)");
    }
    $source_assignment_col = $conn->query("SHOW COLUMNS FROM dine_in_orders LIKE 'source_assignment_id'");
    if (!$source_assignment_col || $source_assignment_col->num_rows === 0) {
        $conn->query("ALTER TABLE dine_in_orders ADD COLUMN source_assignment_id INT NULL AFTER source_table_id");
        $conn->query("CREATE INDEX idx_dine_in_orders_source_assignment ON dine_in_orders(source_assignment_id)");
    }
    $display_table_col = $conn->query("SHOW COLUMNS FROM dine_in_orders LIKE 'display_table_number'");
    if (!$display_table_col || $display_table_col->num_rows === 0) {
        $conn->query("ALTER TABLE dine_in_orders ADD COLUMN display_table_number VARCHAR(50) NULL AFTER source_assignment_id");
    }

    // Allow NULL table_id for online orders (keeps restaurant FK valid for direct orders).
    @$conn->query("ALTER TABLE dine_in_orders MODIFY COLUMN table_id INT NULL");

    // Insert dine-in order
    $restaurant_assignment_id = ($table_source === 'restaurant') ? $assignment_id : 0;
    $restaurant_table_id = ($table_source === 'restaurant') ? $table_id : 0;
    $source_table_id = $table_id;
    $source_assignment_id = $assignment_id;
    $display_table_number = $table_number !== '' ? $table_number : ($table_source === 'online' ? ('ON-' . $table_id) : ('Table-' . $table_id));

    $stmt = $conn->prepare("
        INSERT INTO dine_in_orders (
            assignment_id, server_id, table_id, table_source, source_table_id, source_assignment_id, display_table_number,
            order_number, status, payment_status, special_requests, created_at
        )
        VALUES (NULLIF(?, 0), ?, NULLIF(?, 0), ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    $stmt->bind_param(
        "iiisiissssss",
        $restaurant_assignment_id,
        $server_id,
        $restaurant_table_id,
        $table_source,
        $source_table_id,
        $source_assignment_id,
        $display_table_number,
        $order_number,
        $status,
        $payment_status,
        $special_requests,
        $order_date
    );
    
    if (!$stmt->execute()) {
        throw new Exception('Failed to create order: ' . $stmt->error);
    }
    
    $dine_in_order_id = $conn->insert_id;
    $stmt->close();

    // Create dine_in_order_items table if it doesn't exist
    $create_items_table_sql = "CREATE TABLE IF NOT EXISTS dine_in_order_items (
        id INT PRIMARY KEY AUTO_INCREMENT,
        dine_in_order_id INT NOT NULL,
        item_id INT NOT NULL,
        item_name VARCHAR(100) NOT NULL,
        quantity INT NOT NULL DEFAULT 1,
        unit_price DECIMAL(10, 2) NOT NULL,
        total_price DECIMAL(10, 2) NOT NULL,
        status VARCHAR(50) DEFAULT 'pending' COMMENT 'pending, preparing, ready, served',
        is_reorder TINYINT(1) DEFAULT 0 COMMENT 'Indicates if this is a reordered item',
        special_instructions TEXT,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        FOREIGN KEY (dine_in_order_id) REFERENCES dine_in_orders(id) ON DELETE CASCADE,
        FOREIGN KEY (item_id) REFERENCES menu_items(id) ON DELETE RESTRICT
    )";
    $conn->query($create_items_table_sql);
    
    // Add is_reorder column if it doesn't exist (for backward compatibility)
    $check_column_sql = "SHOW COLUMNS FROM dine_in_order_items LIKE 'is_reorder'";
    $column_result = $conn->query($check_column_sql);
    
    if (!$column_result || $column_result->num_rows === 0) {
        $alter_sql = "ALTER TABLE dine_in_order_items ADD COLUMN is_reorder TINYINT(1) DEFAULT 0 COMMENT 'Indicates if this is a reordered item'";
        $conn->query($alter_sql);
    }

    // Add order items
    $items_added = 0;
    $total_amount = 0;
    
    foreach ($items as $item) {
        $item_id = (int)$item['id'];
        $item_name = $item['name'];
        $quantity = (int)$item['quantity'];
        $item_status = 'pending';
        
        // Verify item exists
        $stmt = $conn->prepare("
            SELECT id, price FROM menu_items WHERE id = ? AND is_available = 1
        ");
        $stmt->bind_param("i", $item_id);
        $stmt->execute();
        $item_result = $stmt->get_result();
        
        if ($item_result->num_rows === 0) {
            throw new Exception('Item #' . $item_id . ' not found or not available');
        }
        
        $item_data = $item_result->fetch_assoc();
        // Always use canonical menu price from DB, not client-sent price.
        $current_price = (float)$item_data['price'];
        $unit_price = $current_price;
        $total_price = $unit_price * $quantity;
        $stmt->close();

        // Add item to dine-in order
        $stmt = $conn->prepare("
            INSERT INTO dine_in_order_items (dine_in_order_id, item_id, item_name, quantity, unit_price, total_price, status) 
            VALUES (?, ?, ?, ?, ?, ?, ?)
        ");
        $item_name_db = substr($item_name, 0, 100); // Limit to column size
        $stmt->bind_param("iisidds", $dine_in_order_id, $item_id, $item_name_db, $quantity, $unit_price, $total_price, $item_status);
        
        if (!$stmt->execute()) {
            throw new Exception('Failed to add item to order: ' . $stmt->error);
        }
        
        $items_added++;
        $total_amount += $total_price;
        $stmt->close();
    }

    // Update dine-in order with total
    $stmt = $conn->prepare("
        UPDATE dine_in_orders SET total_amount = ? WHERE id = ?
    ");
    $stmt->bind_param("di", $total_amount, $dine_in_order_id);
    $stmt->execute();
    $stmt->close();

    // Commit transaction
    $conn->commit();

    echo json_encode([
        'success' => true,
        'message' => 'Order created successfully',
        'data' => [
            'order_id' => $dine_in_order_id,
            'order_number' => $order_number,
            'table_id' => $table_id,
            'items_count' => $items_added,
            'total' => $total_amount,
        ]
    ]);

} catch (Exception $e) {
    // Rollback transaction on error
    $conn->rollback();
    
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'message' => 'Error creating order: ' . $e->getMessage()
    ]);
}
?>

