<?php
session_start();
require_once '../assets/db_connect.php';

header('Content-Type: application/json');

// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Log function
function logError($message) {
    $log_file = __DIR__ . '/pos_debug.log';
    file_put_contents($log_file, date('Y-m-d H:i:s') . ' - ' . $message . PHP_EOL, FILE_APPEND);
}

logError("=== STARTING SALE SAVE PROCESS ===");

try {
    // Get raw input
    $raw_input = file_get_contents('php://input');
    
    if (empty($raw_input)) {
        logError("ERROR: No input received");
        throw new Exception('No data received from client');
    }
    
    logError("Raw input received (first 500 chars): " . substr($raw_input, 0, 500));
    
    // Check if it's valid JSON
    $data = json_decode($raw_input, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        logError("JSON decode error: " . json_last_error_msg());
        logError("Raw input that failed: " . $raw_input);
        throw new Exception('Invalid JSON data received: ' . json_last_error_msg());
    }
    
    if (!$data) {
        logError("ERROR: Data is null after decode");
        throw new Exception('Data is null after JSON decode');
    }
    
    logError("Data decoded successfully");
    logError("Invoice: " . ($data['invoice_no'] ?? 'N/A'));
    logError("Shop ID: " . ($data['shop_id'] ?? 'N/A'));
    logError("Item count: " . (isset($data['items']) ? count($data['items']) : 0));
    
    // Validate required fields
    $required = ['invoice_no', 'shop_id', 'created_by', 'total', 'items'];
    $missing = [];
    foreach ($required as $field) {
        if (!isset($data[$field])) {
            $missing[] = $field;
        }
    }
    
    if (!empty($missing)) {
        $error = "Missing required fields: " . implode(', ', $missing);
        logError("ERROR: " . $error);
        throw new Exception($error);
    }
    
    logError("All required fields present");
    
    // Start transaction
    $pdo->beginTransaction();
    logError("Transaction started");

    // Handle customer
    $customer_id = null;
    if (!empty($data['customer_id']) && $data['customer_id'] !== 'null') {
        $customer_id = (int)$data['customer_id'];
        logError("Using existing customer ID: " . $customer_id);
    } elseif (!empty($data['customer_name'])) {
        logError("Processing customer name: " . $data['customer_name']);
        
        // Check if customer exists with this name
        $check_customer_sql = "SELECT id FROM customers WHERE name = ? AND shop_id = ? LIMIT 1";
        $check_stmt = $pdo->prepare($check_customer_sql);
        $check_stmt->execute([$data['customer_name'], $data['shop_id']]);
        $existing_customer = $check_stmt->fetch(PDO::FETCH_ASSOC);
        
        if ($existing_customer && !empty($existing_customer['id'])) {
            $customer_id = $existing_customer['id'];
            logError("Found existing customer ID: " . $customer_id);
        } else {
            // Create a new customer entry
            $new_customer_sql = "INSERT INTO customers (name, shop_id, created_at) VALUES (?, ?, NOW())";
            $new_customer_stmt = $pdo->prepare($new_customer_sql);
            if ($new_customer_stmt->execute([$data['customer_name'], $data['shop_id']])) {
                $customer_id = $pdo->lastInsertId();
                logError("Created new customer with ID: " . $customer_id);
            } else {
                $errorInfo = $new_customer_stmt->errorInfo();
                logError("Failed to create new customer: " . json_encode($errorInfo));
                throw new Exception("Failed to create customer record: " . $errorInfo[2]);
            }
        }
    } else {
        logError("No customer information provided - using NULL");
    }

    // 1. Create sale record
    $sale_sql = "INSERT INTO sales 
                (invoice_no, sale_date, customer_id, total, paid, status, 
                 created_by, shop_id) 
                VALUES (?, NOW(), ?, ?, ?, ?, ?, ?)";
    
    logError("Preparing sale SQL");
    
    $sale_stmt = $pdo->prepare($sale_sql);
    $sale_params = [
        $data['invoice_no'],
        $customer_id,
        (float)$data['total'],
        (float)($data['paid'] ?? 0),
        $data['status'] ?? 'open',
        (int)$data['created_by'],
        (int)$data['shop_id']
    ];
    
    logError("Sale params: " . json_encode($sale_params));
    
    if ($sale_stmt->execute($sale_params)) {
        $sale_id = $pdo->lastInsertId();
        logError("Sale created successfully with ID: " . $sale_id);
    } else {
        $errorInfo = $sale_stmt->errorInfo();
        logError("Failed to create sale: " . json_encode($errorInfo));
        throw new Exception("Failed to create sale record: " . $errorInfo[2]);
    }
    
    // 2. Create sale lines and inventory movements
    $item_count = count($data['items']);
    logError("Processing " . $item_count . " items");
    
    foreach ($data['items'] as $index => $item) {
        logError("Processing item " . ($index + 1) . ": Product=" . $item['product_id'] . ", Batch=" . $item['batch_id'] . ", Qty=" . $item['qty']);
        
        // Validate item data
        if (empty($item['product_id']) || empty($item['batch_id']) || empty($item['qty'])) {
            logError("ERROR: Item data incomplete: " . json_encode($item));
            throw new Exception("Incomplete item data at index " . $index);
        }
        
        // Create sale line
        $line_sql = "INSERT INTO sale_lines 
                    (sale_id, product_id, batch_id, qty, unit_price, line_total, shop_id)
                    VALUES (?, ?, ?, ?, ?, ?, ?)";
        
        $line_stmt = $pdo->prepare($line_sql);
        $line_params = [
            $sale_id,
            (int)$item['product_id'],
            (int)$item['batch_id'],
            (int)$item['qty'],
            (float)$item['unit_price'],
            (float)$item['line_total'],
            (int)$data['shop_id']
        ];
        
        logError("Line params: " . json_encode($line_params));
        
        if ($line_stmt->execute($line_params)) {
            logError("Sale line created successfully");
        } else {
            $errorInfo = $line_stmt->errorInfo();
            logError("Failed to create sale line: " . json_encode($errorInfo));
            throw new Exception("Failed to create sale line: " . $errorInfo[2]);
        }

        // Create inventory movement
        $movement_sql = "INSERT INTO inventory_movements 
                        (product_id, batch_id, change_qty, movement_type, 
                         reference_id, created_by, shop_id)
                        VALUES (?, ?, ?, 'SALE', ?, ?, ?)";
        
        $movement_stmt = $pdo->prepare($movement_sql);
        $movement_params = [
            (int)$item['product_id'],
            (int)$item['batch_id'],
            (int)$item['qty'],
            $sale_id,
            (int)$data['created_by'],
            (int)$data['shop_id']
        ];
        
        logError("Movement params: " . json_encode($movement_params));
        
        if ($movement_stmt->execute($movement_params)) {
            logError("Inventory movement created successfully");
        } else {
            $errorInfo = $movement_stmt->errorInfo();
            logError("Failed to create inventory movement: " . json_encode($errorInfo));
            throw new Exception("Failed to create inventory movement: " . $errorInfo[2]);
        }
    }

    // 3. Create payment record if paid amount > 0
    $paid_amount = (float)($data['paid'] ?? 0);
    if ($paid_amount > 0) {
        logError("Creating payment record for amount: " . $paid_amount);
        
        $payment_sql = "INSERT INTO payments 
                       (sale_id, amount, method, created_by, shop_id, paid_at)
                       VALUES (?, ?, ?, ?, ?, NOW())";
        
        $payment_stmt = $pdo->prepare($payment_sql);
        $payment_params = [
            $sale_id,
            $paid_amount,
            $data['payment_method'] ?? 'CASH',
            (int)$data['created_by'],
            (int)$data['shop_id']
        ];
        
        logError("Payment params: " . json_encode($payment_params));
        
        if ($payment_stmt->execute($payment_params)) {
            logError("Payment record created successfully");
        } else {
            $errorInfo = $payment_stmt->errorInfo();
            logError("Failed to create payment record: " . json_encode($errorInfo));
            throw new Exception("Failed to create payment record: " . $errorInfo[2]);
        }
    } else {
        logError("No payment record needed (paid amount: 0)");
    }

    // Commit transaction
    $pdo->commit();
    logError("Transaction committed successfully");

    $response = [
        'status' => 'success',
        'message' => 'Sale saved successfully',
        'sale_id' => $sale_id,
        'invoice_no' => $data['invoice_no'],
        'customer_id' => $customer_id
    ];
    
    logError("Sending success response");
    logError("Response: " . json_encode($response));
    logError("=== SALE SAVE PROCESS COMPLETED ===");
    
    echo json_encode($response);

} catch (Exception $e) {
    logError("EXCEPTION CAUGHT: " . $e->getMessage());
    logError("Exception trace: " . $e->getTraceAsString());
    
    if (isset($pdo) && $pdo->inTransaction()) {
        $pdo->rollBack();
        logError("Transaction rolled back");
    }
    
    $error_response = [
        'status' => 'error',
        'message' => 'Failed to save sale: ' . $e->getMessage(),
        'trace' => $e->getTraceAsString()
    ];
    
    logError("Sending error response: " . json_encode($error_response));
    logError("=== SALE SAVE PROCESS FAILED ===");
    
    echo json_encode($error_response);
}