<?php
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/db.php';

// ==================== AUTH ====================
function isLoggedIn() {
    return isset($_SESSION['user_id']);
}

function isAdmin() {
    return isset($_SESSION['is_admin']) && $_SESSION['is_admin'] == 1;
}

function requireAuth() {
    if (!isLoggedIn()) {
        $_SESSION['error'] = 'Please log in to continue.';
        header('Location: ' . BASE_PATH . '/login.php');
        exit;
    }
}

function requireAdmin() {
    requireAuth();
    if (!isAdmin()) {
        $_SESSION['error'] = 'Access denied. Admin only.';
        header('Location: ' . BASE_PATH . '/index.php');
        exit;
    }
}

function getCurrentUser() {
    if (!isLoggedIn()) return null;
    $db = db();
    $stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$_SESSION['user_id']]);
    return $stmt->fetch();
}

// ==================== FLASH MESSAGES ====================
function flash($key, $message = null) {
    if ($message !== null) {
        $_SESSION['flash_' . $key] = $message;
    } else {
        $msg = isset($_SESSION['flash_' . $key]) ? $_SESSION['flash_' . $key] : '';
        unset($_SESSION['flash_' . $key]);
        return $msg;
    }
}

function hasFlash($key) {
    return isset($_SESSION['flash_' . $key]);
}

// ==================== CART ====================
function getCartId() {
    $db = db();
    if (isLoggedIn()) {
        $cart = $db->prepare("SELECT id FROM carts WHERE user_id = ?");
        $cart->execute([$_SESSION['user_id']]);
        $row = $cart->fetch();
        if ($row) return $row['id'];
        
        $db->prepare("INSERT INTO carts (user_id) VALUES (?)")->execute([$_SESSION['user_id']]);
        return $db->lastInsertId();
    } else {
        if (!isset($_SESSION['cart_id'])) {
            $sid = session_id();
            $db->prepare("INSERT INTO carts (session_id) VALUES (?)")->execute([$sid]);
            $_SESSION['cart_id'] = $db->lastInsertId();
        }
        return $_SESSION['cart_id'];
    }
}

function getCartCount() {
    $db = db();
    $cartId = getCartId();
    $stmt = $db->prepare("SELECT SUM(quantity) FROM cart_items WHERE cart_id = ?");
    $stmt->execute([$cartId]);
    return (int)$stmt->fetchColumn();
}

function getCartItems() {
    $db = db();
    $cartId = getCartId();
    $stmt = $db->prepare("
        SELECT ci.*, p.name, p.slug, p.price, p.stock_quantity, p.category_id,
               COALESCE(c.tax_rate, 0) as tax_rate,
               (SELECT image_path FROM product_images WHERE product_id = p.id AND is_primary = 1 LIMIT 1) as image,
               pv.type as variant_type, pv.value as variant_value, pv.image_path as variant_image
        FROM cart_items ci
        JOIN products p ON ci.product_id = p.id
        LEFT JOIN categories c ON p.category_id = c.id
        LEFT JOIN product_variants pv ON ci.variant_id = pv.id
        WHERE ci.cart_id = ?
    ");
    $stmt->execute([$cartId]);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

function getCartTotal() {
    $items = getCartItems();
    $subtotal = 0;
    foreach ($items as $item) {
        $subtotal += $item['unit_price'] * $item['quantity'];
    }
    return $subtotal;
}

function getAppliedCoupon() {
    $db = db();
    $cartId = getCartId();
    $stmt = $db->prepare("SELECT coupon_id FROM carts WHERE id = ?");
    $stmt->execute([$cartId]);
    $cart = $stmt->fetch();
    if ($cart && $cart['coupon_id']) {
        $stmt = $db->prepare("SELECT * FROM coupons WHERE id = ?");
        $stmt->execute([$cart['coupon_id']]);
        return $stmt->fetch();
    }
    return null;
}

// ==================== SETTINGS HELPERS ====================
function getSetting($key, $default = null) {
    static $cache = [];
    if (!isset($cache[$key])) {
        try {
            $db = db();
            $stmt = $db->prepare("SELECT `value` FROM settings WHERE `key` = ?");
            $stmt->execute([$key]);
            $val = $stmt->fetchColumn();
            $cache[$key] = $val !== false ? $val : $default;
        } catch (Exception $e) {
            $cache[$key] = $default;
        }
    }
    return $cache[$key];
}

function getShippingFreeMin() {
    return (float)(getSetting('shipping_free_min_amount') ?: SHIPPING_FREE_MIN_AMOUNT);
}

function getStoreState() {
    return getSetting('store_state') ?: STORE_STATE;
}

function getInStateRate() {
    return (float)(getSetting('shipping_in_state_rate') ?: SHIPPING_IN_STATE_RATE);
}

function getOutStateRate() {
    return (float)(getSetting('shipping_out_state_rate') ?: SHIPPING_OUT_STATE_RATE);
}

// ==================== ORDER CALCULATIONS ====================
function calculateTotals($subtotal, $coupon = null, $items = null, $shippingState = null) {
    $discount = 0;
    if ($coupon && $coupon['is_active']) {
        $now = date('Y-m-d H:i:s');
        if ($coupon['starts_at'] && $coupon['starts_at'] > $now) $coupon = null;
        if ($coupon && $coupon['expires_at'] && $coupon['expires_at'] < $now) $coupon = null;
        if ($coupon && $coupon['max_uses'] && $coupon['used_count'] >= $coupon['max_uses']) $coupon = null;
        if ($coupon && $coupon['min_order_amount'] && $subtotal < $coupon['min_order_amount']) $coupon = null;
        
        if ($coupon) {
            if ($coupon['type'] === 'fixed') {
                $discount = $coupon['value'];
            } else {
                $discount = $subtotal * ($coupon['value'] / 100);
                if ($coupon['max_discount_amount'] && $discount > $coupon['max_discount_amount']) {
                    $discount = $coupon['max_discount_amount'];
                }
            }
            $discount = min($discount, $subtotal);
        }
    }
    
    $afterDiscount = $subtotal - $discount;
    
    $taxRates = [];
    if ($items) {
        $taxAmount = 0;
        foreach ($items as $item) {
            $itemTotal = $item['unit_price'] * $item['quantity'];
            $rate = (float)($item['tax_rate'] ?? 0);
            if ($rate > 0) {
                $taxAmount += round($itemTotal * ($rate / 100), 2);
                $taxRates[] = $rate;
            }
        }
        $taxRates = array_unique($taxRates);
    } else {
        $taxAmount = round($afterDiscount * (TAX_RATE / 100), 2);
        if (TAX_RATE > 0) $taxRates[] = TAX_RATE;
    }
    
    $freeMin = getShippingFreeMin();
    $storeState = getStoreState();
    $inRate = getInStateRate();
    $outRate = getOutStateRate();

    if ($subtotal >= $freeMin) {
        $shippingAmount = 0;
        $shippingLabel = 'Shipping (Free)';
    } elseif ($shippingState && strcasecmp(trim($shippingState), $storeState) === 0) {
        $shippingAmount = $inRate;
        $shippingLabel = 'Shipping (In-State)';
    } else {
        $shippingAmount = $outRate;
        $shippingLabel = 'Shipping (Out-of-State)';
    }
    $total = round($afterDiscount + $taxAmount + $shippingAmount, 2);
    $taxLabel = $taxRates ? 'Tax (' . implode('%, ', $taxRates) . '%)' : 'Tax';
    
    return [
        'subtotal' => $subtotal,
        'discount' => $discount,
        'tax' => $taxAmount,
        'tax_label' => $taxLabel,
        'shipping' => $shippingAmount,
        'shipping_label' => $shippingLabel,
        'total' => $total,
    ];
}

// ==================== PRODUCT HELPERS ====================
function getProductImage($productId) {
    $db = db();
    $stmt = $db->prepare("SELECT image_path FROM product_images WHERE product_id = ? AND is_primary = 1 LIMIT 1");
    $stmt->execute([$productId]);
    $row = $stmt->fetch();
    return $row ? $row['image_path'] : null;
}

function getProductRating($productId) {
    $db = db();
    $stmt = $db->prepare("SELECT ROUND(AVG(rating), 1) as avg_rating, COUNT(*) as count FROM reviews WHERE product_id = ? AND is_approved = 1");
    $stmt->execute([$productId]);
    return $stmt->fetch();
}

function slugify($text) {
    $text = preg_replace('~[^\pL\d]+~u', '-', $text);
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
    $text = preg_replace('~[^-\w]+~', '', $text);
    $text = trim($text, '-');
    $text = preg_replace('~-+~', '-', $text);
    $text = strtolower($text);
    return $text ?: 'n-a';
}

function generateOrderNumber() {
    return 'ORD-' . date('Ymd') . '-' . strtoupper(substr(uniqid(), -6));
}

function formatPrice($amount) {
    return CURRENCY_SYMBOL . number_format($amount, 2);
}

function h($str) {
    return htmlspecialchars($str ?? '', ENT_QUOTES, 'UTF-8');
}

function timeAgo($datetime) {
    $timestamp = strtotime($datetime);
    $diff = time() - $timestamp;
    if ($diff < 60) return 'Just now';
    if ($diff < 3600) return floor($diff / 60) . ' min ago';
    if ($diff < 86400) return floor($diff / 3600) . ' hours ago';
    if ($diff < 604800) return floor($diff / 86400) . ' days ago';
    return date('d M Y', $timestamp);
}

function getStatusBadge($status) {
    $map = [
        'pending' => 'bg-yellow-100 text-yellow-700',
        'confirmed' => 'bg-blue-100 text-blue-700',
        'processing' => 'bg-yellow-100 text-yellow-700',
        'shipped' => 'bg-indigo-100 text-indigo-700',
        'delivered' => 'bg-green-100 text-green-700',
        'cancelled' => 'bg-red-100 text-red-700',
        'refunded' => 'bg-purple-100 text-purple-700',
        'paid' => 'bg-green-100 text-green-700',
        'failed' => 'bg-red-100 text-red-700',
    ];
    $class = isset($map[$status]) ? $map[$status] : 'bg-gray-100 text-gray-700';
    return '<span class="px-2 py-0.5 rounded-full text-xs font-medium ' . $class . '">' . ucfirst($status) . '</span>';
}
