<?php
/**
 * ไฟล์ประมวลผลการจองสินค้า (Backend Pre-order Processor)
 * รองรับการอัปโหลดรูปสลิป, ตรวจสอบช่วงเวลาเปิดจอง และประมวลผลสต็อก (Made-to-Order & Limit Stock)
 */
session_start();
require_once 'db.php';

// 1. ตรวจสอบสิทธิ์และ CSRF Token
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header("Location: index.php");
    exit;
}

if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
    $_SESSION['error_msg'] = "เซสชันหมดอายุหรือคำขอไม่ถูกต้อง (CSRF Token invalid)";
    header("Location: index.php");
    exit;
}

// 2. รับและทำความสะอาดข้อมูลฟอร์ม
$customer_name   = isset($_POST['customer_name']) ? trim(htmlspecialchars($_POST['customer_name'])) : '';
$customer_phone  = isset($_POST['customer_phone']) ? trim(htmlspecialchars($_POST['customer_phone'])) : '';
$payment_method  = isset($_POST['payment_method']) ? trim(htmlspecialchars($_POST['payment_method'])) : 'Bank Transfer';

$cart_items_json = isset($_POST['cart_items']) ? $_POST['cart_items'] : '';
$cart_items      = [];

if (!empty($cart_items_json)) {
    $cart_items = json_decode($cart_items_json, true);
    if (!is_array($cart_items)) {
        $cart_items = [];
    }
}

// ถ้าไม่มี cart_items ส่งมา ให้ลองดึงข้อมูลจาก single product (เพื่อรองรับการทำงานแบบเดิม หรือ Buy Now)
if (empty($cart_items)) {
    $product_id = isset($_POST['product_id']) ? (int)$_POST['product_id'] : 0;
    $variant_id = isset($_POST['variant_id']) ? (int)$_POST['variant_id'] : 0;
    $quantity   = isset($_POST['quantity']) ? (int)$_POST['quantity'] : 0;

    if ($product_id > 0 && $variant_id > 0 && $quantity > 0) {
        $cart_items[] = [
            'product_id' => $product_id,
            'variant_id' => $variant_id,
            'quantity'   => $quantity
        ];
    }
}

// 3. ตรวจสอบข้อมูลเบื้องต้น
if (empty($customer_name) || empty($customer_phone) || empty($cart_items)) {
    $_SESSION['error_msg'] = "กรุณากรอกข้อมูลที่จำเป็นและเลือกสินค้าลงในรถเข็นก่อนทำรายการ";
    header("Location: index.php");
    exit;
}

if (!preg_match("/^[0-9]{9,10}$/", $customer_phone)) {
    $_SESSION['error_msg'] = "รูปแบบเบอร์โทรศัพท์ไม่ถูกต้อง กรุณากรอกเฉพาะตัวเลข 9-10 หลัก";
    header("Location: index.php");
    exit;
}

// 4. ตรวจสอบการอัปโหลดรูปภาพสลิปโอนเงิน
if (!isset($_FILES['slip_image']) || $_FILES['slip_image']['error'] !== UPLOAD_ERR_OK) {
    $_SESSION['error_msg'] = "กรุณาแนบรูปภาพสลิปหลักฐานการโอนเงิน";
    header("Location: index.php");
    exit;
}

$file = $_FILES['slip_image'];
$allowed_exts = ['jpg', 'jpeg', 'png', 'webp', 'gif'];
$file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));

// ตรวจสอบนามสกุลไฟล์
if (!in_array($file_ext, $allowed_exts)) {
    $_SESSION['error_msg'] = "ประเภทไฟล์ไม่ถูกต้อง อนุญาตเฉพาะสลิปที่เป็นไฟล์รูปภาพ JPG, PNG, WEBP เท่านั้น";
    header("Location: index.php");
    exit;
}

// ตรวจสอบ mime type ถ้าฟังก์ชัน mime_content_type มีให้ใช้งาน
if (function_exists('mime_content_type')) {
    $file_type = @mime_content_type($file['tmp_name']);
    $allowed_mimes = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif', 'application/octet-stream'];
    if ($file_type && !in_array($file_type, $allowed_mimes) && strpos($file_type, 'image/') !== 0) {
        $_SESSION['error_msg'] = "ประเภทไฟล์รูปภาพไม่ถูกต้อง";
        header("Location: index.php");
        exit;
    }
}

// จำกัดขนาดไฟล์ที่ 10MB
$max_size = 10 * 1024 * 1024;
if ($file['size'] > $max_size) {
    $_SESSION['error_msg'] = "ขนาดไฟล์ใหญ่เกินไป จำกัดขนาดไม่เกิน 10MB";
    header("Location: index.php");
    exit;
}

// สร้างโฟลเดอร์สำหรับเก็บรูปสลิป
$upload_dir = __DIR__ . '/uploads/slips/';
if (!is_dir($upload_dir)) {
    @mkdir($upload_dir, 0777, true);
    @chmod($upload_dir, 0777);
}

// สุ่มชื่อไฟล์ใหม่เพื่อป้องกันชื่อซ้ำและเรื่องความปลอดภัย
$file_name = 'slip_' . uniqid() . '_' . time() . '.' . $file_ext;
$target_file = $upload_dir . $file_name;

if (!move_uploaded_file($file['tmp_name'], $target_file)) {
    $_SESSION['error_msg'] = "ไม่สามารถบันทึกไฟล์สลิปได้ (โปรดตรวจสอบ Permission โฟลเดอร์ uploads/slips/)";
    header("Location: index.php");
    exit;
}

$slip_image_url = 'uploads/slips/' . $file_name;

// 5. เข้าสู่ขั้นตอนการประมวลผลการจอง (Transaction + FOR UPDATE)
try {
    $pdo->beginTransaction();

    $grand_total = 0;
    $booking_details = [];

    foreach ($cart_items as $item) {
        $p_id = isset($item['product_id']) ? (int)$item['product_id'] : 0;
        $v_id = isset($item['variant_id']) ? (int)$item['variant_id'] : 0;
        $qty  = isset($item['quantity']) ? (int)$item['quantity'] : 0;

        if ($p_id <= 0 || $v_id <= 0 || $qty <= 0) {
            throw new Exception("ข้อมูลสินค้าในรถเข็นไม่ถูกต้อง");
        }

        // ดึงข้อมูลตัวเลือกและเวลาจองของสินค้า เพื่อเช็กช่วงเวลาเปิดจอง
        $sql = "SELECT pv.id, pv.product_id, pv.variant_name, pv.stock, pv.is_unlimited, 
                       p.name AS product_name, p.price, p.start_time, p.end_time 
                FROM product_variants pv 
                INNER JOIN products p ON pv.product_id = p.id 
                WHERE pv.id = :variant_id AND pv.product_id = :product_id 
                FOR UPDATE";
                
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            'variant_id' => $v_id,
            'product_id' => $p_id
        ]);
        
        $variant = $stmt->fetch();

        if (!$variant) {
            throw new Exception("ไม่พบข้อมูลสินค้าหรือตัวเลือกที่ระบุ");
        }

        // A. ตรวจสอบความถูกต้องของช่วงเวลาเปิดรับจองสินค้า
        $now = new DateTime();
        $start_time = !empty($variant['start_time']) ? new DateTime($variant['start_time']) : null;
        $end_time = !empty($variant['end_time']) ? new DateTime($variant['end_time']) : null;

        if ($start_time && $now < $start_time) {
            throw new Exception("สินค้า '{$variant['product_name']}' ยังไม่เริ่มเปิดรับจอง (จะเปิดในวันที่ " . $start_time->format('d/m/Y H:i') . ")");
        }
        if ($end_time && $now > $end_time) {
            throw new Exception("ขออภัย สินค้า '{$variant['product_name']}' ปิดรับจองล่วงหน้าไปแล้วเมื่อวันที่ " . $end_time->format('d/m/Y H:i'));
        }

        // B. ตรวจสอบและประมวลผลสต็อกสินค้า
        $is_unlimited = (int)$variant['is_unlimited'] === 1;
        $current_stock = (int)$variant['stock'];

        if (!$is_unlimited) {
            // หากไม่ใช่สินค้าแบบ Made-to-Order ต้องเช็กและตัดสต็อก
            if ($current_stock < $qty) {
                throw new Exception("ขออภัย สินค้า '{$variant['product_name']}' ตัวเลือก '{$variant['variant_name']}' มีจำนวนไม่เพียงพอ (เหลืออยู่ {$current_stock} ชิ้น)");
            }
            
            $new_stock = $current_stock - $qty;
            
            // อัปเดตหักสต็อก
            $update_stmt = $pdo->prepare("UPDATE product_variants SET stock = :new_stock WHERE id = :variant_id");
            $update_stmt->execute([
                'new_stock'  => $new_stock,
                'variant_id' => $v_id
            ]);
        }

        // C. คำนวณราคารวมและบันทึกการจอง
        $item_total_price = (float)$variant['price'] * $qty;
        $grand_total += $item_total_price;

        // บันทึกการจอง
        $user_id = isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null;

        $insert_sql = "INSERT INTO bookings (user_id, customer_name, customer_phone, product_id, variant_id, quantity, total_price, slip_image_url, payment_method, payment_status, status) 
                       VALUES (:user_id, :customer_name, :customer_phone, :product_id, :variant_id, :quantity, :total_price, :slip_image_url, :payment_method, 'Pending', 'Pending')";
        $insert_stmt = $pdo->prepare($insert_sql);
        $insert_stmt->execute([
            'user_id'        => $user_id,
            'customer_name'  => $customer_name,
            'customer_phone' => $customer_phone,
            'product_id'     => $p_id,
            'variant_id'     => $v_id,
            'quantity'       => $qty,
            'total_price'    => $item_total_price,
            'slip_image_url' => $slip_image_url,
            'payment_method' => $payment_method
        ]);

        $booking_details[] = "{$variant['product_name']} [{$variant['variant_name']}] (x{$qty})";
    }

    $pdo->commit();

    $_SESSION['success_msg'] = "ส่งคำสั่งจองเรียบร้อย! เจ้าหน้าที่จะตรวจสอบสลิปการโอนเงินของคุณโดยเร็วที่สุด ข้อมูลการจอง: " . implode(', ', $booking_details) . " ราคารวมทั้งหมด ฿" . number_format($grand_total, 2);
    header("Location: index.php");
    exit;

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    // หากจองล้มเหลว ให้ลบไฟล์รูปภาพสลิปที่เพิ่งอัปโหลดเพื่อไม่ให้ขยะรกเซิร์ฟเวอร์
    if (file_exists($target_file)) {
        unlink($target_file);
    }

    $_SESSION['error_msg'] = "ไม่สามารถทำรายการจองได้: " . $e->getMessage();
    header("Location: index.php");
    exit;
}
