<?php

if (!function_exists('prd_e')) {
    function prd_e($value): string
    {
        return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('prd_redirect')) {
    function prd_redirect(string $url): void
    {
        header("Location: " . $url);
        exit;
    }
}

if (!function_exists('prd_clean_text')) {
    function prd_clean_text($value): string
    {
        return trim((string)$value);
    }
}

if (!function_exists('prd_slugify')) {
    function prd_slugify(string $text): string
    {
        $text = trim($text);
        $text = preg_replace('/\s+/u', '-', $text);
        $text = preg_replace('/[^\p{Arabic}\p{L}\p{N}\-_]+/u', '-', $text);
        $text = preg_replace('/-+/u', '-', $text);
        $text = trim($text, '-');

        return mb_strtolower($text, 'UTF-8');
    }
}

if (!function_exists('prd_build_name')) {
    function prd_build_name(string $brandPart, string $productPart): string
    {
        $brandPart = trim($brandPart);
        $productPart = trim($productPart);

        if ($brandPart !== '' && $productPart !== '') {
            return $brandPart . ' - ' . $productPart;
        }

        if ($brandPart !== '') {
            return $brandPart;
        }

        return $productPart;
    }
}

if (!function_exists('prd_upload_image')) {
    function prd_upload_image(?array $file, string $prefix = 'prd_'): ?string
    {
        if (
            !$file ||
            !isset($file['name'], $file['tmp_name'], $file['error']) ||
            $file['error'] === UPLOAD_ERR_NO_FILE ||
            empty($file['name'])
        ) {
            return null;
        }

        if ($file['error'] !== UPLOAD_ERR_OK) {
            throw new Exception('صار خطأ أثناء رفع الصورة: ' . $file['name']);
        }

        $allowed = [
            'image/jpeg' => 'jpg',
            'image/jpg'  => 'jpg',
            'image/png'  => 'png',
            'image/webp' => 'webp',
        ];

        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime  = finfo_file($finfo, $file['tmp_name']);
        finfo_close($finfo);

        if (!isset($allowed[$mime])) {
            throw new Exception('نوع الصورة غير مدعوم: ' . $file['name']);
        }

        $ext = $allowed[$mime];

        $uploadDir = dirname(__DIR__) . '/uploads/products/';
        if (!is_dir($uploadDir)) {
            if (!mkdir($uploadDir, 0775, true) && !is_dir($uploadDir)) {
                throw new Exception('تعذر إنشاء مجلد رفع الصور.');
            }
        }

        $newName = $prefix . uniqid('', true) . '.' . $ext;
        $target  = $uploadDir . $newName;

        if (!move_uploaded_file($file['tmp_name'], $target)) {
            throw new Exception('فشل نقل الصورة المرفوعة: ' . $file['name']);
        }

        return $newName;
    }
}

if (!function_exists('prd_delete_image')) {
    function prd_delete_image(string $fileName): void
    {
        $fileName = trim($fileName);
        if ($fileName === '') {
            return;
        }

        $fullPath = dirname(__DIR__) . '/uploads/products/' . $fileName;
        if (is_file($fullPath)) {
            @unlink($fullPath);
        }
    }
}

if (!function_exists('prd_set_success')) {
    function prd_set_success(string $message): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        $_SESSION['success_message'] = $message;
    }
}

if (!function_exists('prd_set_errors')) {
    function prd_set_errors(array $errors): void
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        $_SESSION['product_form_errors'] = array_values($errors);
    }
}

if (!function_exists('prd_take_success')) {
    function prd_take_success(): string
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        $message = $_SESSION['success_message'] ?? '';
        unset($_SESSION['success_message']);

        return $message;
    }
}

if (!function_exists('prd_take_errors')) {
    function prd_take_errors(): array
    {
        if (session_status() !== PHP_SESSION_ACTIVE) {
            session_start();
        }

        $errors = $_SESSION['product_form_errors'] ?? [];
        unset($_SESSION['product_form_errors']);

        return is_array($errors) ? $errors : [];
    }
}

if (!function_exists('prd_normalize_ids')) {
    function prd_normalize_ids($items): array
    {
        $result = [];

        if (!is_array($items)) {
            return $result;
        }

        foreach ($items as $item) {
            $id = (int)$item;
            if ($id > 0) {
                $result[] = $id;
            }
        }

        return array_values(array_unique($result));
    }
}

if (!function_exists('prd_get_categories')) {
    function prd_get_categories(mysqli $conn): array
    {
        $items = [];
        $res = $conn->query("SELECT id, name FROM categories WHERE status = 1 ORDER BY sort_order ASC, id DESC");

        if ($res) {
            while ($row = $res->fetch_assoc()) {
                $items[] = $row;
            }
        }

        return $items;
    }
}

if (!function_exists('prd_get_brands')) {
    function prd_get_brands(mysqli $conn): array
    {
        $items = [];
        $res = $conn->query("SELECT id, name FROM brands WHERE status = 1 ORDER BY sort_order ASC, name ASC");

        if ($res) {
            while ($row = $res->fetch_assoc()) {
                $items[] = $row;
            }
        }

        return $items;
    }
}

if (!function_exists('prd_get_product_types')) {
    function prd_get_product_types(mysqli $conn): array
    {
        $items = [];
        $res = $conn->query("SELECT id, category_id, name FROM product_types WHERE status = 1 ORDER BY sort_order ASC, id DESC");

        if ($res) {
            while ($row = $res->fetch_assoc()) {
                $items[] = $row;
            }
        }

        return $items;
    }
}

if (!function_exists('prd_get_product')) {
    function prd_get_product(mysqli $conn, int $productId): ?array
    {
        $stmt = $conn->prepare("
            SELECT p.*, c.name AS category_name
            FROM products p
            LEFT JOIN categories c ON c.id = p.category_id
            WHERE p.id = ?
            LIMIT 1
        ");
        $stmt->bind_param("i", $productId);
        $stmt->execute();
        $res = $stmt->get_result();
        $row = $res ? $res->fetch_assoc() : null;
        $stmt->close();

        return $row ?: null;
    }
}

if (!function_exists('prd_ensure_access_schema')) {
    function prd_ensure_access_schema(mysqli $conn): void
    {
        static $done = false;
        if ($done) {
            return;
        }
        $done = true;

        $productColumns = [
            // Barcode is now the customer-facing searchable code. Keep sku for legacy code compatibility.
            'barcode' => "ADD COLUMN barcode VARCHAR(160) DEFAULT NULL AFTER sku",
            'allow_preorder' => "ADD COLUMN allow_preorder TINYINT(1) NOT NULL DEFAULT 0 AFTER low_stock_alert",
            'access_mode' => "ADD COLUMN access_mode VARCHAR(30) NOT NULL DEFAULT 'all' AFTER allow_preorder",
            'access_scope' => "ADD COLUMN access_scope VARCHAR(30) NOT NULL DEFAULT 'always' AFTER access_mode",
            'access_min_subtotal' => "ADD COLUMN access_min_subtotal DECIMAL(12,2) NOT NULL DEFAULT 0 AFTER access_scope",
            'low_stock_gate_enabled' => "ADD COLUMN low_stock_gate_enabled TINYINT(1) NOT NULL DEFAULT 0 AFTER access_min_subtotal",
            'low_stock_gate_qty' => "ADD COLUMN low_stock_gate_qty INT NOT NULL DEFAULT 0 AFTER low_stock_gate_enabled",
        ];
        foreach ($productColumns as $column => $sql) {
            $check = $conn->query("SHOW COLUMNS FROM products LIKE '" . $conn->real_escape_string($column) . "'");
            $exists = $check instanceof mysqli_result && $check->num_rows > 0;
            if ($check instanceof mysqli_result) {
                $check->close();
            }
            if (!$exists) {
                @ $conn->query("ALTER TABLE products {$sql}");
            }
        }

        $variantBarcodeCheck = $conn->query("SHOW COLUMNS FROM product_variants LIKE 'barcode'");
        $variantBarcodeExists = $variantBarcodeCheck instanceof mysqli_result && $variantBarcodeCheck->num_rows > 0;
        if ($variantBarcodeCheck instanceof mysqli_result) {
            $variantBarcodeCheck->close();
        }
        if (!$variantBarcodeExists) {
            @ $conn->query("ALTER TABLE product_variants ADD COLUMN barcode VARCHAR(160) DEFAULT NULL AFTER sku");
        }

        @ $conn->query("UPDATE products SET barcode = sku WHERE (barcode IS NULL OR barcode = '') AND sku IS NOT NULL AND sku != ''");
        @ $conn->query("UPDATE product_variants SET barcode = sku WHERE (barcode IS NULL OR barcode = '') AND sku IS NOT NULL AND sku != ''");

        $productBarcodeIndex = $conn->query("SHOW INDEX FROM products WHERE Key_name = 'idx_products_barcode'");
        $hasProductBarcodeIndex = $productBarcodeIndex instanceof mysqli_result && $productBarcodeIndex->num_rows > 0;
        if ($productBarcodeIndex instanceof mysqli_result) {
            $productBarcodeIndex->close();
        }
        if (!$hasProductBarcodeIndex) {
            @ $conn->query("ALTER TABLE products ADD INDEX idx_products_barcode (barcode)");
        }

        $variantBarcodeIndex = $conn->query("SHOW INDEX FROM product_variants WHERE Key_name = 'idx_product_variants_barcode'");
        $hasVariantBarcodeIndex = $variantBarcodeIndex instanceof mysqli_result && $variantBarcodeIndex->num_rows > 0;
        if ($variantBarcodeIndex instanceof mysqli_result) {
            $variantBarcodeIndex->close();
        }
        if (!$hasVariantBarcodeIndex) {
            @ $conn->query("ALTER TABLE product_variants ADD INDEX idx_product_variants_barcode (barcode)");
        }

        @ $conn->query("CREATE TABLE IF NOT EXISTS product_access_tiers (
            id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
            product_id INT UNSIGNED NOT NULL,
            tier_id INT UNSIGNED NOT NULL,
            created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
            UNIQUE KEY uq_product_tier (product_id, tier_id),
            KEY idx_product_access_product (product_id),
            KEY idx_product_access_tier (tier_id)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
    }
}

if (!function_exists('prd_access_modes')) {
    function prd_access_modes(): array
    {
        return [
            'all' => 'متاح للجميع',
            'tiers' => 'مستويات محددة فقط',
            'subtotal' => 'حد أدنى للسلة فقط',
            'tiers_or_subtotal' => 'مستويات محددة أو حد أدنى للسلة',
            'tiers_and_subtotal' => 'مستويات محددة وحد أدنى للسلة',
        ];
    }
}

if (!function_exists('prd_access_scopes')) {
    function prd_access_scopes(): array
    {
        return [
            'always' => 'يُطبق دائمًا',
            'low_stock_only' => 'فقط عند انخفاض الكمية',
        ];
    }
}

if (!function_exists('prd_normalize_access_mode')) {
    function prd_normalize_access_mode(string $value): string
    {
        $value = strtolower(trim($value));
        return array_key_exists($value, prd_access_modes()) ? $value : 'all';
    }
}

if (!function_exists('prd_normalize_access_scope')) {
    function prd_normalize_access_scope(string $value): string
    {
        $value = strtolower(trim($value));
        return array_key_exists($value, prd_access_scopes()) ? $value : 'always';
    }
}

if (!function_exists('prd_get_customer_tiers')) {
    function prd_get_customer_tiers(mysqli $conn): array
    {
        $rows = [];
        if (!$conn->query("SHOW TABLES LIKE 'customer_tiers'")?->num_rows) {
            return $rows;
        }
        $res = $conn->query("SELECT id, title, slug, color_hex FROM customer_tiers WHERE is_active = 1 ORDER BY sort_order ASC, id ASC");
        if ($res instanceof mysqli_result) {
            while ($row = $res->fetch_assoc()) {
                $rows[] = $row;
            }
            $res->close();
        }
        return $rows;
    }
}

if (!function_exists('prd_get_product_access_tier_ids')) {
    function prd_get_product_access_tier_ids(mysqli $conn, int $productId): array
    {
        prd_ensure_access_schema($conn);
        if ($productId <= 0) {
            return [];
        }
        $stmt = $conn->prepare('SELECT tier_id FROM product_access_tiers WHERE product_id = ? ORDER BY tier_id ASC');
        if (!$stmt) {
            return [];
        }
        $stmt->bind_param('i', $productId);
        $stmt->execute();
        $res = $stmt->get_result();
        $ids = [];
        while ($row = $res->fetch_assoc()) {
            $tierId = (int)($row['tier_id'] ?? 0);
            if ($tierId > 0) {
                $ids[] = $tierId;
            }
        }
        $stmt->close();
        return array_values(array_unique($ids));
    }
}

if (!function_exists('prd_save_product_access_tiers')) {
    function prd_save_product_access_tiers(mysqli $conn, int $productId, array $tierIds): void
    {
        prd_ensure_access_schema($conn);
        $stmt = $conn->prepare('DELETE FROM product_access_tiers WHERE product_id = ?');
        if ($stmt) {
            $stmt->bind_param('i', $productId);
            $stmt->execute();
            $stmt->close();
        }
        if ($productId <= 0 || !$tierIds) {
            return;
        }
        $insert = $conn->prepare('INSERT INTO product_access_tiers (product_id, tier_id) VALUES (?, ?)');
        if (!$insert) {
            return;
        }
        foreach (array_values(array_unique(array_filter(array_map('intval', $tierIds)))) as $tierId) {
            if ($tierId <= 0) {
                continue;
            }
            $insert->bind_param('ii', $productId, $tierId);
            $insert->execute();
        }
        $insert->close();
    }
}

if (!function_exists('prd_get_product_type_ids')) {
    function prd_get_product_type_ids(mysqli $conn, int $productId): array
    {
        $ids = [];
        $stmt = $conn->prepare("SELECT product_type_id FROM product_type_links WHERE product_id = ?");
        $stmt->bind_param("i", $productId);
        $stmt->execute();
        $res = $stmt->get_result();

        if ($res) {
            while ($row = $res->fetch_assoc()) {
                $ids[] = (int)$row['product_type_id'];
            }
        }

        $stmt->close();
        return $ids;
    }
}

if (!function_exists('prd_get_variants')) {
    function prd_get_variants(mysqli $conn, int $productId): array
    {
        $items = [];
        $stmt = $conn->prepare("
            SELECT *
            FROM product_variants
            WHERE product_id = ?
            ORDER BY sort_order ASC, id ASC
        ");
        $stmt->bind_param("i", $productId);
        $stmt->execute();
        $res = $stmt->get_result();

        if ($res) {
            while ($row = $res->fetch_assoc()) {
                $items[] = $row;
            }
        }

        $stmt->close();
        return $items;
    }
}

if (!function_exists('prd_product_exists_by_slug_or_sku')) {
    function prd_product_exists_by_slug_or_sku(mysqli $conn, string $slug, string $sku, int $excludeId = 0): bool
    {
        if ($excludeId > 0) {
            $stmt = $conn->prepare("
                SELECT id
                FROM products
                WHERE (slug = ? OR sku = ?) AND id != ?
                LIMIT 1
            ");
            $stmt->bind_param("ssi", $slug, $sku, $excludeId);
        } else {
            $stmt = $conn->prepare("
                SELECT id
                FROM products
                WHERE slug = ? OR sku = ?
                LIMIT 1
            ");
            $stmt->bind_param("ss", $slug, $sku);
        }

        $stmt->execute();
        $res = $stmt->get_result();
        $exists = $res && $res->num_rows > 0;
        $stmt->close();

        return $exists;
    }
}

if (!function_exists('prd_variant_sku_exists')) {
    function prd_variant_sku_exists(mysqli $conn, string $sku, int $excludeId = 0): bool
    {
        if ($excludeId > 0) {
            $stmt = $conn->prepare("
                SELECT id
                FROM product_variants
                WHERE sku = ? AND id != ?
                LIMIT 1
            ");
            $stmt->bind_param("si", $sku, $excludeId);
        } else {
            $stmt = $conn->prepare("
                SELECT id
                FROM product_variants
                WHERE sku = ?
                LIMIT 1
            ");
            $stmt->bind_param("s", $sku);
        }

        $stmt->execute();
        $res = $stmt->get_result();
        $exists = $res && $res->num_rows > 0;
        $stmt->close();

        return $exists;
    }
}