<?php
/**
 * RUHONDO BEACH RESORT HMS + POS System
 * POS API
 * Developer: JOACHIM'S INNOTECH
 */

// Verify authentication
$user_id = verify_api_request();
if (!$user_id) {
    json_response(['error' => 'Authentication required'], 401);
}

// Get current user
$current_user = db_fetch_one("SELECT * FROM users WHERE user_id = ?", [$user_id]);

// Check for open shift
$active_shift = db_fetch_one("
    SELECT * FROM pos_shifts 
    WHERE user_id = ? AND status = 'open'
    ORDER BY opened_at DESC LIMIT 1
", [$user_id]);

// Handle different methods based on subresource
$subresource = $subresource ?? '';

switch ($method) {
    case 'GET':
        if ($id === 'products') {
            get_products();
        } elseif ($id === 'categories') {
            get_categories();
        } elseif ($id === 'outlets') {
            get_outlets();
        } elseif ($id === 'shift') {
            get_current_shift();
        } elseif ($id === 'sales') {
            if ($subresource) {
                get_sale($subresource);
            } else {
                get_sales();
            }
        } else {
            json_response(['error' => 'Invalid endpoint'], 400);
        }
        break;
        
    case 'POST':
        if ($id === 'sales') {
            create_sale();
        } elseif ($id === 'shift') {
            if ($subresource === 'open') {
                open_shift();
            } elseif ($subresource === 'close') {
                close_shift();
            } else {
                json_response(['error' => 'Invalid shift action'], 400);
            }
        } elseif ($id === 'void') {
            void_sale();
        } else {
            json_response(['error' => 'Invalid endpoint'], 400);
        }
        break;
        
    default:
        json_response(['error' => 'Method not allowed'], 405);
}

/**
 * Get products list
 */
function get_products() {
    $category_id = isset($_GET['category_id']) ? (int)$_GET['category_id'] : null;
    $outlet_id = isset($_GET['outlet_id']) ? (int)$_GET['outlet_id'] : null;
    $search = $_GET['search'] ?? '';
    
    $sql = "
        SELECT 
            p.*,
            c.category_name,
            o.outlet_name
        FROM pos_products p
        LEFT JOIN pos_categories c ON p.category_id = c.category_id
        LEFT JOIN pos_outlets o ON p.outlet_id = o.outlet_id
        WHERE p.is_active = 1
    ";
    
    $params = [];
    
    if ($category_id) {
        $sql .= " AND p.category_id = ?";
        $params[] = $category_id;
    }
    
    if ($outlet_id) {
        $sql .= " AND (p.outlet_id = ? OR p.outlet_id IS NULL)";
        $params[] = $outlet_id;
    }
    
    if (!empty($search)) {
        $sql .= " AND (p.product_name LIKE ? OR p.product_code LIKE ? OR p.barcode LIKE ?)";
        $search_term = "%$search%";
        $params = array_merge($params, [$search_term, $search_term, $search_term]);
    }
    
    $sql .= " ORDER BY c.sort_order, p.product_name LIMIT 200";
    
    $products = db_fetch_all($sql, $params);
    
    json_response([
        'success' => true,
        'data' => $products
    ]);
}

/**
 * Get categories
 */
function get_categories() {
    $categories = db_fetch_all("
        SELECT c.*, COUNT(p.product_id) as product_count
        FROM pos_categories c
        LEFT JOIN pos_products p ON c.category_id = p.category_id AND p.is_active = 1
        WHERE c.is_active = 1
        GROUP BY c.category_id
        ORDER BY c.sort_order, c.category_name
    ");
    
    json_response([
        'success' => true,
        'data' => $categories
    ]);
}

/**
 * Get outlets
 */
function get_outlets() {
    $outlets = db_fetch_all("
        SELECT * FROM pos_outlets 
        WHERE is_active = 1 
        ORDER BY outlet_name
    ");
    
    json_response([
        'success' => true,
        'data' => $outlets
    ]);
}

/**
 * Get current shift
 */
function get_current_shift() {
    global $active_shift, $user_id;
    
    if (!$active_shift) {
        json_response([
            'success' => true,
            'data' => null,
            'message' => 'No active shift'
        ]);
    }
    
    // Get shift summary
    $sales = db_fetch_all("
        SELECT 
            COUNT(*) as transaction_count,
            COALESCE(SUM(total_amount), 0) as total_sales
        FROM pos_sales 
        WHERE shift_id = ? AND payment_status = 'completed'
    ", [$active_shift['shift_id']]);
    
    $active_shift['summary'] = $sales[0] ?? ['transaction_count' => 0, 'total_sales' => 0];
    
    json_response([
        'success' => true,
        'data' => $active_shift
    ]);
}

/**
 * Get sales list
 */
function get_sales() {
    global $user_id;
    
    $page = max(1, (int)($_GET['page'] ?? 1));
    $limit = min(100, max(1, (int)($_GET['limit'] ?? 20)));
    $date_from = $_GET['date_from'] ?? '';
    $date_to = $_GET['date_to'] ?? '';
    $outlet_id = isset($_GET['outlet_id']) ? (int)$_GET['outlet_id'] : null;
    
    $where = "1=1";
    $params = [];
    
    if (!empty($date_from)) {
        $where .= " AND DATE(sale_time) >= ?";
        $params[] = $date_from;
    }
    
    if (!empty($date_to)) {
        $where .= " AND DATE(sale_time) <= ?";
        $params[] = $date_to;
    }
    
    if ($outlet_id) {
        $where .= " AND outlet_id = ?";
        $params[] = $outlet_id;
    }
    
    // Get total count
    $count_sql = "SELECT COUNT(*) FROM pos_sales WHERE $where";
    $total = db_fetch_value($count_sql, $params);
    
    // Get paginated results
    $offset = ($page - 1) * $limit;
    $sql = "
        SELECT 
            s.*,
            o.outlet_name,
            pm.method_name
        FROM pos_sales s
        JOIN pos_outlets o ON s.outlet_id = o.outlet_id
        LEFT JOIN payment_methods pm ON s.payment_method_id = pm.payment_method_id
        WHERE $where
        ORDER BY s.sale_time DESC
        LIMIT $limit OFFSET $offset
    ";
    
    $sales = db_fetch_all($sql, $params);
    
    json_response([
        'success' => true,
        'data' => $sales,
        'pagination' => [
            'page' => $page,
            'limit' => $limit,
            'total' => (int)$total,
            'pages' => ceil($total / $limit)
        ]
    ]);
}

/**
 * Get single sale
 */
function get_sale($sale_id) {
    $sale = db_fetch_one("
        SELECT 
            s.*,
            o.outlet_name,
            u.first_name, u.last_name,
            pm.method_name
        FROM pos_sales s
        JOIN pos_outlets o ON s.outlet_id = o.outlet_id
        JOIN users u ON s.user_id = u.user_id
        LEFT JOIN payment_methods pm ON s.payment_method_id = pm.payment_method_id
        WHERE s.sale_id = ?
    ", [$sale_id]);
    
    if (!$sale) {
        json_response(['error' => 'Sale not found'], 404);
    }
    
    // Get sale items
    $items = db_fetch_all("
        SELECT si.*, p.product_name
        FROM pos_sale_items si
        JOIN pos_products p ON si.product_id = p.product_id
        WHERE si.sale_id = ?
    ", [$sale_id]);
    
    $sale['items'] = $items;
    
    json_response([
        'success' => true,
        'data' => $sale
    ]);
}

/**
 * Create new sale
 */
function create_sale() {
    global $current_user, $active_shift;
    
    // Check for open shift
    if (!$active_shift) {
        json_response(['error' => 'No open shift found'], 400);
    }
    
    // Get POST data
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input) {
        json_response(['error' => 'Invalid request data'], 400);
    }
    
    // Validate required fields
    if (empty($input['outlet_id'])) {
        json_response(['error' => 'Outlet ID is required'], 400);
    }
    
    if (empty($input['items'])) {
        json_response(['error' => 'No items in sale'], 400);
    }
    
    try {
        begin_transaction();
        
        // Calculate totals
        $subtotal = 0;
        foreach ($input['items'] as $item) {
            $subtotal += $item['price'] * $item['quantity'];
        }
        
        $discount = (float)($input['discount'] ?? 0);
        $discount_type = $input['discount_type'] ?? 'fixed';
        
        // Calculate discount amount
        $discount_amount = $discount;
        if ($discount_type === 'percentage') {
            $discount_amount = ($subtotal * $discount) / 100;
        }
        
        // Calculate tax (simplified - in production use actual tax rates)
        $tax_amount = $subtotal * 0.18;
        $total_amount = $subtotal + $tax_amount - $discount_amount;
        
        // Generate receipt number
        $receipt_number = generate_receipt_number();
        
        // Create sale
        $sale_id = db_insert('pos_sales', [
            'receipt_number' => $receipt_number,
            'shift_id' => $active_shift['shift_id'],
            'user_id' => $current_user['user_id'],
            'outlet_id' => $input['outlet_id'],
            'guest_id' => $input['guest_id'] ?? null,
            'customer_name' => $input['customer_name'] ?? 'Walk-in Customer',
            'subtotal' => $subtotal,
            'tax_amount' => $tax_amount,
            'discount_amount' => $discount_amount,
            'discount_type' => $discount_type,
            'discount_value' => $discount,
            'total_amount' => $total_amount,
            'payment_method_id' => $input['payment_method_id'] ?? 1,
            'payment_status' => 'completed',
            'sale_time' => date(DATETIME_FORMAT)
        ]);
        
        // Insert items and update stock
        foreach ($input['items'] as $item) {
            db_insert('pos_sale_items', [
                'sale_id' => $sale_id,
                'product_id' => $item['product_id'],
                'quantity' => $item['quantity'],
                'unit_price' => $item['price'],
                'total_amount' => $item['price'] * $item['quantity']
            ]);
            
            // Update stock if tracked
            $product = db_fetch_one("SELECT stock_item FROM pos_products WHERE product_id = ?", [$item['product_id']]);
            if ($product && $product['stock_item']) {
                db_query("
                    UPDATE pos_products 
                    SET current_stock = current_stock - ? 
                    WHERE product_id = ?
                ", [$item['quantity'], $item['product_id']]);
                
                // Record stock movement
                db_insert('stock_movements', [
                    'product_id' => $item['product_id'],
                    'movement_type' => 'sale',
                    'quantity' => -$item['quantity'],
                    'reference_type' => 'sale',
                    'reference_id' => $sale_id,
                    'created_by' => $current_user['user_id']
                ]);
            }
        }
        
        // Update shift totals
        db_query("
            UPDATE pos_shifts 
            SET total_sales = total_sales + ? 
            WHERE shift_id = ?
        ", [$total_amount, $active_shift['shift_id']]);
        
        commit_transaction();
        
        // Get created sale
        $sale = db_fetch_one("
            SELECT s.*, o.outlet_name
            FROM pos_sales s
            JOIN pos_outlets o ON s.outlet_id = o.outlet_id
            WHERE s.sale_id = ?
        ", [$sale_id]);
        
        json_response([
            'success' => true,
            'message' => 'Sale completed successfully',
            'data' => $sale
        ], 201);
        
    } catch (Exception $e) {
        rollback_transaction();
        json_response(['error' => 'Failed to create sale: ' . $e->getMessage()], 500);
    }
}

/**
 * Open shift
 */
function open_shift() {
    global $current_user, $active_shift;
    
    // Check if already has open shift
    if ($active_shift) {
        json_response(['error' => 'You already have an open shift'], 400);
    }
    
    // Get POST data
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input) {
        json_response(['error' => 'Invalid request data'], 400);
    }
    
    $outlet_id = (int)($input['outlet_id'] ?? 0);
    $opening_cash = (float)($input['opening_cash'] ?? 0);
    
    if (!$outlet_id) {
        json_response(['error' => 'Outlet ID is required'], 400);
    }
    
    if ($opening_cash < 0) {
        json_response(['error' => 'Opening cash cannot be negative'], 400);
    }
    
    // Generate shift code
    $shift_code = 'SHIFT-' . date('Ymd') . '-' . str_pad(rand(1, 999), 3, '0', STR_PAD_LEFT);
    
    $shift_id = db_insert('pos_shifts', [
        'shift_code' => $shift_code,
        'user_id' => $current_user['user_id'],
        'outlet_id' => $outlet_id,
        'opened_at' => date(DATETIME_FORMAT),
        'opening_cash' => $opening_cash,
        'status' => 'open'
    ]);
    
    $shift = db_fetch_one("SELECT * FROM pos_shifts WHERE shift_id = ?", [$shift_id]);
    
    json_response([
        'success' => true,
        'message' => 'Shift opened successfully',
        'data' => $shift
    ], 201);
}

/**
 * Close shift
 */
function close_shift() {
    global $current_user, $active_shift;
    
    if (!$active_shift) {
        json_response(['error' => 'No open shift found'], 400);
    }
    
    // Get POST data
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input) {
        json_response(['error' => 'Invalid request data'], 400);
    }
    
    $closing_cash = (float)($input['closing_cash'] ?? 0);
    $notes = $input['notes'] ?? '';
    
    if ($closing_cash < 0) {
        json_response(['error' => 'Closing cash cannot be negative'], 400);
    }
    
    // Get shift sales
    $sales = db_fetch_all("
        SELECT 
            payment_method_id,
            COALESCE(SUM(total_amount), 0) as total
        FROM pos_sales
        WHERE shift_id = ? AND payment_status = 'completed'
        GROUP BY payment_method_id
    ", [$active_shift['shift_id']]);
    
    $cash_sales = 0;
    $card_sales = 0;
    $mobile_sales = 0;
    $room_charge_sales = 0;
    $total_sales = 0;
    
    foreach ($sales as $sale) {
        $total_sales += $sale['total'];
        
        switch ($sale['payment_method_id']) {
            case 1: // Cash
                $cash_sales = $sale['total'];
                break;
            case 2: case 3: case 4: // Cards
                $card_sales += $sale['total'];
                break;
            case 5: // Mobile Money
                $mobile_sales = $sale['total'];
                break;
            case 8: // Room Charge
                $room_charge_sales = $sale['total'];
                break;
        }
    }
    
    $expected_cash = $active_shift['opening_cash'] + $cash_sales;
    
    // Update shift
    db_update('pos_shifts', [
        'closed_at' => date(DATETIME_FORMAT),
        'closing_cash' => $closing_cash,
        'expected_cash' => $expected_cash,
        'cash_sales' => $cash_sales,
        'card_sales' => $card_sales,
        'mobile_sales' => $mobile_sales,
        'room_charge_sales' => $room_charge_sales,
        'total_sales' => $total_sales,
        'status' => 'closed',
        'notes' => $notes
    ], 'shift_id = ?', [$active_shift['shift_id']]);
    
    $shift = db_fetch_one("SELECT * FROM pos_shifts WHERE shift_id = ?", [$active_shift['shift_id']]);
    
    json_response([
        'success' => true,
        'message' => 'Shift closed successfully',
        'data' => $shift
    ]);
}

/**
 * Void sale
 */
function void_sale() {
    global $current_user;
    
    // Get POST data
    $input = json_decode(file_get_contents('php://input'), true);
    
    if (!$input) {
        json_response(['error' => 'Invalid request data'], 400);
    }
    
    $sale_id = (int)($input['sale_id'] ?? 0);
    $reason = $input['reason'] ?? '';
    
    if (!$sale_id) {
        json_response(['error' => 'Sale ID is required'], 400);
    }
    
    if (empty($reason)) {
        json_response(['error' => 'Void reason is required'], 400);
    }
    
    // Get sale
    $sale = db_fetch_one("SELECT * FROM pos_sales WHERE sale_id = ?", [$sale_id]);
    
    if (!$sale) {
        json_response(['error' => 'Sale not found'], 404);
    }
    
    if ($sale['transaction_type'] == 'void') {
        json_response(['error' => 'Sale already voided'], 400);
    }
    
    try {
        begin_transaction();
        
        // Update sale
        db_update('pos_sales', [
            'transaction_type' => 'void',
            'payment_status' => 'voided',
            'notes' => "VOIDED: $reason"
        ], 'sale_id = ?', [$sale_id]);
        
        // Get sale items
        $items = db_fetch_all("SELECT * FROM pos_sale_items WHERE sale_id = ?", [$sale_id]);
        
        // Restore stock
        foreach ($items as $item) {
            $product = db_fetch_one("SELECT stock_item FROM pos_products WHERE product_id = ?", [$item['product_id']]);
            if ($product && $product['stock_item']) {
                db_query("
                    UPDATE pos_products 
                    SET current_stock = current_stock + ? 
                    WHERE product_id = ?
                ", [$item['quantity'], $item['product_id']]);
                
                db_insert('stock_movements', [
                    'product_id' => $item['product_id'],
                    'movement_type' => 'return',
                    'quantity' => $item['quantity'],
                    'reference_type' => 'void',
                    'reference_id' => $sale_id,
                    'notes' => "Void transaction: $reason",
                    'created_by' => $current_user['user_id']
                ]);
            }
        }
        
        commit_transaction();
        
        json_response([
            'success' => true,
            'message' => 'Sale voided successfully'
        ]);
        
    } catch (Exception $e) {
        rollback_transaction();
        json_response(['error' => 'Failed to void sale: ' . $e->getMessage()], 500);
    }
}