<?php

class ProductController {

    // ─── GET /api/categories ──────────────────────────────────────────────────
    public static function categories(): void {
        $db     = getDb();
        // categories: id, category_name, description, created_at, status (enum active/inactive)
        $result = $db->query("SELECT id, category_name AS name, description FROM categories WHERE status = 'active' ORDER BY category_name ASC");
        $cats   = $result->fetch_all(MYSQLI_ASSOC);
        sendSuccess($cats);
    }

    // ─── GET /api/categories/{id} ─────────────────────────────────────────────
    public static function categoryById(string $id): void {
        $db   = getDb();
        $stmt = $db->prepare("SELECT id, category_name AS name, description FROM categories WHERE id = ? AND status = 'active' LIMIT 1");
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $category = $stmt->get_result()->fetch_assoc();
        $stmt->close();

        if (!$category) sendError('Category not found', 404);

        // Pagination
        $limit  = max(1, min(100, (int)($_GET['limit'] ?? 20)));
        $page   = max(1, (int)($_GET['page'] ?? 1));
        $offset = ($page - 1) * $limit;

        // Fetch products for this category
        $stmt = $db->prepare(
            "SELECT id, name, price, original_price, market_price, discount_percent, images, stock, slug
             FROM products
             WHERE category_id = ? AND status = 'active' AND (is_deleted = 0 OR is_deleted IS NULL)
             ORDER BY created_at DESC
             LIMIT ? OFFSET ?"
        );
        $stmt->bind_param('iii', $id, $limit, $offset);
        $stmt->execute();
        $products = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt->close();

        foreach ($products as &$p) {
            $p = self::formatProduct($p);
        }

        // Total count
        $stmt2 = $db->prepare("SELECT COUNT(*) FROM products WHERE category_id = ? AND status = 'active' AND (is_deleted = 0 OR is_deleted IS NULL)");
        $stmt2->bind_param('i', $id);
        $stmt2->execute();
        $stmt2->bind_result($total);
        $stmt2->fetch();
        $stmt2->close();

        $category['products']   = $products;
        $category['pagination'] = [
            'page'        => $page,
            'limit'       => $limit,
            'total'       => (int)$total,
            'total_pages' => (int)ceil($total / $limit),
        ];

        sendSuccess($category);
    }

    // ─── GET /api/products ────────────────────────────────────────────────────
    // Optional query params: category_id, search, min_price, max_price, sort, page, limit
    public static function products(): void {
        $db = getDb();

        // products: status enum('active','inactive','out_of_stock')
        $where  = ["p.status = 'active'", "(p.is_deleted = 0 OR p.is_deleted IS NULL)"];
        $params = [];
        $types  = '';

        // Category filter
        if (!empty($_GET['category_id'])) {
            $where[]  = 'p.category_id = ?';
            $params[] = (int)$_GET['category_id'];
            $types   .= 'i';
        }

        // Search
        if (!empty($_GET['search'])) {
            $search   = '%' . $_GET['search'] . '%';
            $where[]  = '(p.name LIKE ? OR p.description LIKE ?)';
            $params[] = $search;
            $params[] = $search;
            $types   .= 'ss';
        }

        // Price range
        if (!empty($_GET['min_price'])) {
            $where[]  = 'p.price >= ?';
            $params[] = (float)$_GET['min_price'];
            $types   .= 'd';
        }
        if (!empty($_GET['max_price'])) {
            $where[]  = 'p.price <= ?';
            $params[] = (float)$_GET['max_price'];
            $types   .= 'd';
        }

        // Sort (PHP 7 compatible)
        switch ($_GET['sort'] ?? '') {
            case 'price_asc':  $sort = 'p.price ASC';        break;
            case 'price_desc': $sort = 'p.price DESC';       break;
            case 'newest':     $sort = 'p.created_at DESC';  break;
            case 'name':       $sort = 'p.name ASC';         break;
            default:           $sort = 'p.created_at DESC';  break;
        }

        // Pagination
        $limit  = max(1, min(100, (int)($_GET['limit'] ?? 20)));
        $page   = max(1, (int)($_GET['page'] ?? 1));
        $offset = ($page - 1) * $limit;

        $whereStr = implode(' AND ', $where);

        $sql = "SELECT p.id, p.name, p.price, p.original_price, p.market_price, p.discount_percent,
                       p.security_deposit, p.images, p.description,
                       p.size, p.color, p.stock, p.slug,
                       p.brand, p.material, p.rental_days, p.rental_price,
                       p.category_id, c.category_name, p.video_path
                FROM products p
                LEFT JOIN categories c ON c.id = p.category_id
                WHERE {$whereStr}
                ORDER BY {$sort}
                LIMIT ? OFFSET ?";

        $params[] = $limit;
        $params[] = $offset;
        $types   .= 'ii';

        $stmt = $db->prepare($sql);
        if ($types) {
            $stmt->bind_param($types, ...$params);
        }
        $stmt->execute();
        $products = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt->close();

        foreach ($products as &$p) {
            $p = self::formatProduct($p);
        }

        // Total count
        $countSql    = "SELECT COUNT(*) FROM products p WHERE {$whereStr}";
        $countParams = array_slice($params, 0, -2);
        $countTypes  = substr($types, 0, -2);

        $stmt2 = $db->prepare($countSql);
        if ($countTypes) {
            $stmt2->bind_param($countTypes, ...$countParams);
        }
        $stmt2->execute();
        $stmt2->bind_result($total);
        $stmt2->fetch();
        $stmt2->close();

        sendSuccess([
            'products'   => $products,
            'pagination' => [
                'page'        => $page,
                'limit'       => $limit,
                'total'       => $total,
                'total_pages' => (int)ceil($total / $limit),
            ],
        ]);
    }

    // ─── GET /api/products/trending ──────────────────────────────────────────
    public static function trendingProducts(): void {
        $db = getDb();

        $sql = "SELECT p.id, p.name, p.price, p.original_price, p.market_price, p.discount_percent,
                       p.images, p.stock, p.slug, p.category_id, c.category_name
                FROM products p
                LEFT JOIN categories c ON c.id = p.category_id
                WHERE p.status = 'active' 
                  AND p.featured = 1 
                  AND p.stock > 0 
                  AND (p.is_deleted = 0 OR p.is_deleted IS NULL)
                ORDER BY p.discount_percent DESC, p.created_at DESC
                LIMIT 8";

        $result   = $db->query($sql);
        $products = $result->fetch_all(MYSQLI_ASSOC);

        foreach ($products as &$p) {
            $p = self::formatProduct($p);
        }

        sendSuccess(['products' => $products]);
    }

    // ─── GET /api/products/{id} ───────────────────────────────────────────────
    public static function productById(string $id): void {
        $db   = getDb();
        $stmt = $db->prepare(
            "SELECT p.id, p.name, p.price, p.original_price, p.market_price, p.discount_percent,
                    p.security_deposit, p.images, p.description,
                    p.size, p.color, p.stock, p.slug,
                    p.brand, p.material, p.rental_days, p.rental_price,
                    p.category_id, c.category_name, p.video_path
             FROM products p
             LEFT JOIN categories c ON c.id = p.category_id
             WHERE p.id = ? AND p.status = 'active' AND (p.is_deleted = 0 OR p.is_deleted IS NULL)
             LIMIT 1"
        );
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();

        if (!$row) sendError('Product not found', 404);

        sendSuccess(self::formatProduct($row));
    }

    // ─── GET /api/products/slug/{slug} ────────────────────────────────────────
    public static function productBySlug(string $slug): void {
        $db   = getDb();
        $stmt = $db->prepare(
            "SELECT p.id, p.name, p.price, p.original_price, p.market_price, p.discount_percent,
                    p.security_deposit, p.images, p.description,
                    p.size, p.color, p.stock, p.slug,
                    p.brand, p.material, p.rental_days, p.rental_price,
                    p.category_id, c.category_name, p.video_path
             FROM products p
             LEFT JOIN categories c ON c.id = p.category_id
             WHERE p.slug = ? AND p.status = 'active' AND (p.is_deleted = 0 OR p.is_deleted IS NULL)
             LIMIT 1"
        );
        $stmt->bind_param('s', $slug);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();

        if (!$row) sendError('Product not found', 404);

        sendSuccess(self::formatProduct($row));
    }

    // ─── Helpers ──────────────────────────────────────────────────────────────
    public static function formatProduct(array $product): array {
        // The 'price' column in DB is already the final discounted price saved by the admin panel
        $product['effective_price'] = (float)$product['price'];
        
        // Decode images JSON or handle old string
        $imgs = $product['images'] ?? '';
        $decoded = json_decode($imgs, true);
        $product['images'] = is_array($decoded) ? $decoded : (empty($imgs) ? [] : [$imgs]);
        
        return $product;
    }

    public static function effectivePrice($price, $discount = 0): float {
        return (float)$price;
    }
}
