<?php

if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
    die('No direct script access allowed');
}

function calculateCurrentPrice(array $product): array {
    $now = date('Y-m-d H:i:s');
    $price = $product['price'] ?? '0.00';
    $base_price = $price;
    $on_sale = false;

    $discount_price_val = $product['discount_price'] ?? null;
    $discount_type = $product['discount_type'] ?? null;
    $discount_start = $product['discount_start_date'] ?? null;
    $discount_end = $product['discount_end_date'] ?? null;

    if ($discount_price_val !== null &&
        ($discount_start === null || $discount_start <= $now) &&
        ($discount_end === null || $discount_end >= $now)) {

        if ($discount_type === 'fixed_amount' && bccomp((string)$discount_price_val, '0', BC_SCALE) > 0) {
            $price = bcsub($price, (string)$discount_price_val, BC_SCALE);
            $on_sale = true;
        } elseif ($discount_type === 'percentage' && bccomp((string)$discount_price_val, '0', BC_SCALE) > 0 && bccomp((string)$discount_price_val, '100', BC_SCALE) <= 0) {
            $discount_multiplier = bcdiv((string)$discount_price_val, '100', 4);
            $discount_amount = bcmul($discount_multiplier, $base_price, BC_SCALE);
            $price = bcsub($base_price, $discount_amount, BC_SCALE);
            $on_sale = true;
        }
    }

    if (bccomp($price, '0', BC_SCALE) < 0) {
        $price = '0.00';
    }

    return ['price' => $price, 'on_sale' => $on_sale, 'base_price' => $base_price];
}


function createProduct(string $name, string $description, string $price, string $unit, ?string $stock, ?int $category_id, ?string $image_path, string $type = 'simple', ?string $weight = null, ?string $weight_unit = null): int {
    try {
        $stmt = pdo()->prepare("INSERT INTO products (name, description, price, unit, stock, category_id, image_path, type, weight, weight_unit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        $stmt->execute([$name, $description, $price, $unit, $stock, $category_id, $image_path, $type, $weight, $weight_unit]);
        return (int)pdo()->lastInsertId();
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error creating product: " . $e->getMessage() . "\n", FILE_APPEND);
        return 0;
    }
}

function getProduct(int $product_id): ?array {
    try {
        $stmt = pdo()->prepare("SELECT * FROM products WHERE id = ? AND is_active = TRUE");
        $stmt->execute([$product_id]);
        $product = $stmt->fetch();
        if ($product) {
            $product['pricing'] = calculateCurrentPrice($product);
            $product['platform_photo_id'] = $product['image_path'] ? (rtrim(PRODUCT_IMAGE_PUBLIC_URL_BASE, '/') . '/' . ltrim($product['image_path'], '/')) : null;
        }
        return $product ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting product {$product_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}

function getActiveProducts(?int $category_id = null, int $limit = 5, int $offset = 0): array {
    try {
        $sql = "SELECT * FROM products WHERE is_active = TRUE";
        $params = [];
        if ($category_id !== null) {
            $sql .= " AND category_id = :category_id";
            $params[':category_id'] = $category_id;
        }
        $sql .= " ORDER BY id DESC LIMIT :limit OFFSET :offset";
        $stmt = pdo()->prepare($sql);
        if ($category_id !== null) {
            $stmt->bindValue(':category_id', $category_id, PDO::PARAM_INT);
        }
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();
        $products = $stmt->fetchAll();

        foreach ($products as &$product) {
            $product['pricing'] = calculateCurrentPrice($product);
            $product['platform_photo_id'] = $product['image_path'] ? (rtrim(PRODUCT_IMAGE_PUBLIC_URL_BASE, '/') . '/' . ltrim($product['image_path'], '/')) : null;
        }
        unset($product);

        return $products;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting active products: " . $e->getMessage() . "\n", FILE_APPEND);
        return [];
    }
}

function countActiveProducts(?int $category_id = null): int {
    try {
        $sql = "SELECT COUNT(*) FROM products WHERE is_active = TRUE";
        if ($category_id !== null) {
            $sql .= " AND category_id = :category_id";
            $stmt = pdo()->prepare($sql);
            $stmt->execute([':category_id' => $category_id]);
        } else {
            $stmt = pdo()->query($sql);
        }
        return (int)$stmt->fetchColumn();
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error counting active products: " . $e->getMessage() . "\n", FILE_APPEND);
        return 0;
    }
}

function searchActiveProducts(string $searchTerm, int $limit = 5, int $offset = 0): array {
    try {
        $searchTermLike = '%' . $searchTerm . '%';
        $sql = "SELECT * FROM products WHERE is_active = TRUE AND name LIKE :searchTerm ORDER BY id DESC LIMIT :limit OFFSET :offset";
        $stmt = pdo()->prepare($sql);
         $stmt->bindValue(':searchTerm', $searchTermLike, PDO::PARAM_STR);
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();
        $products = $stmt->fetchAll();

        foreach ($products as &$product) {
            $product['pricing'] = calculateCurrentPrice($product);
            $product['platform_photo_id'] = $product['image_path'] ? (rtrim(PRODUCT_IMAGE_PUBLIC_URL_BASE, '/') . '/' . ltrim($product['image_path'], '/')) : null;
        }
        unset($product);

        return $products;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error searching products: " . $e->getMessage() . "\n", FILE_APPEND);
         return [];
    }
}

function countSearchedProducts(string $searchTerm): int {
    try {
        $searchTermLike = '%' . $searchTerm . '%';
        $sql = "SELECT COUNT(*) FROM products WHERE is_active = TRUE AND name LIKE :searchTerm";
        $stmt = pdo()->prepare($sql);
        $stmt->execute([':searchTerm' => $searchTermLike]);
        return (int)$stmt->fetchColumn();
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error counting search results: " . $e->getMessage() . "\n", FILE_APPEND);
        return 0;
    }
}

function deleteProduct(int $product_id): bool {
    try {
        $stmt = pdo()->prepare("UPDATE products SET is_active = FALSE WHERE id = ?");
        return $stmt->execute([$product_id]);
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error deleting product {$product_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return false;
    }
}

function updateProductField(int $product_id, string $field, $value): bool {
    $allowed_fields = [
        'name', 'description', 'price', 'unit', 'stock', 'category_id', 'type',
        'discount_price', 'discount_type', 'discount_start_date', 'discount_end_date',
        'image_path', 'is_active', 'weight', 'weight_unit'
    ];
    if (!in_array($field, $allowed_fields)) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - Security Warning: Invalid field '{$field}' in updateProductField for product {$product_id}.\n", FILE_APPEND);
        return false;
    }

    if (in_array($field, ['stock', 'category_id', 'discount_price', 'discount_type', 'discount_start_date', 'discount_end_date', 'image_path', 'weight', 'weight_unit']) && $value === null) {
        $sql = "UPDATE products SET `{$field}` = NULL WHERE id = ?";
         $params = [$product_id];
    } else {
        $sql = "UPDATE products SET `{$field}` = ? WHERE id = ?";
        $params = [$value, $product_id];
    }

    try {
        $stmt = pdo()->prepare($sql);
        return $stmt->execute($params);
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error updating product field ($field) for product {$product_id}: " . $e->getMessage() . "\n", FILE_APPEND);
        return false;
    }
}


function getPartnerProductSetting(int $partner_user_id, int $product_id): ?array {
    try {
        $stmt = pdo()->prepare("SELECT * FROM partner_products WHERE partner_user_id = ? AND product_id = ?");
        $stmt->execute([$partner_user_id, $product_id]);
        return $stmt->fetch() ?: null;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting partner product setting: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}


function updatePartnerProductSetting(int $partner_user_id, int $product_id, string $extra_price, bool $is_active): bool {
    try {
        $sql = "INSERT INTO partner_products (partner_user_id, product_id, extra_price, is_active, updated_at) 
                VALUES (?, ?, ?, ?, NOW())
                ON DUPLICATE KEY UPDATE 
                extra_price = VALUES(extra_price), is_active = VALUES(is_active), updated_at = NOW()";
        $stmt = pdo()->prepare($sql);
        return $stmt->execute([$partner_user_id, $product_id, $extra_price, $is_active]);
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error updating partner product setting: " . $e->getMessage() . "\n", FILE_APPEND);
        return false;
     }
}


function getPartnerActiveProductsPaginated(int $partner_user_id, ?int $category_id, int $limit, int $offset): array {
    try {
        $sql = "SELECT p.*, pp.extra_price
                 FROM products p
                JOIN partner_products pp ON p.id = pp.product_id
                WHERE p.is_active = TRUE 
                  AND pp.partner_user_id = :partner_user_id 
                  AND pp.is_active = TRUE";
        
        $params = [':partner_user_id' => $partner_user_id];

         if ($category_id !== null) {
            $sql .= " AND p.category_id = :category_id";
            $params[':category_id'] = $category_id;
        }

        $sql .= " ORDER BY p.id DESC LIMIT :limit OFFSET :offset";
        
        $stmt = pdo()->prepare($sql);
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        foreach ($params as $key => $value) {
            $stmt->bindValue($key, $value);
      }
        
        $stmt->execute();
        $products = $stmt->fetchAll();

        foreach ($products as &$product) {
            $product['pricing'] = calculateCurrentPrice($product);
            $product['platform_photo_id'] = $product['image_path'] ? (rtrim(PRODUCT_IMAGE_PUBLIC_URL_BASE, '/') . '/' . ltrim($product['image_path'], '/')) : null;
        }
        unset($product);

        return $products;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting partner active products: " . $e->getMessage() . "\n", FILE_APPEND);
        return [];
    }
}


function countPartnerActiveProducts(int $partner_user_id, ?int $category_id): int {
    try {
        $sql = "SELECT COUNT(p.id)
                FROM products p
                JOIN partner_products pp ON p.id = pp.product_id
                WHERE p.is_active = TRUE 
                  AND pp.partner_user_id = :partner_user_id 
                  AND pp.is_active = TRUE";
        
        $params = [':partner_user_id' => $partner_user_id];

        if ($category_id !== null) {
            $sql .= " AND p.category_id = :category_id";
            $params[':category_id'] = $category_id;
        }
        
        $stmt = pdo()->prepare($sql);
        $stmt->execute($params);
        return (int)$stmt->fetchColumn();
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error counting partner active products: " . $e->getMessage() . "\n", FILE_APPEND);
         return 0;
    }
}


function searchPartnerActiveProductsPaginated(int $partner_user_id, string $searchTerm, int $limit, int $offset): array {
    try {
        $searchTermLike = '%' . $searchTerm . '%';

        $sql = "SELECT p.*, pp.extra_price
                FROM products p
                JOIN partner_products pp ON p.id = pp.product_id
                WHERE p.is_active = TRUE 
                  AND pp.partner_user_id = :partner_user_id 
                  AND pp.is_active = TRUE
                  AND p.name LIKE :searchTerm";
        
        $sql .= " ORDER BY p.id DESC LIMIT :limit OFFSET :offset";
        
        $stmt = pdo()->prepare($sql);
        $stmt->bindValue(':partner_user_id', $partner_user_id, PDO::PARAM_INT);
        $stmt->bindValue(':searchTerm', $searchTermLike, PDO::PARAM_STR);
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
        
        $stmt->execute();
        $products = $stmt->fetchAll();

        foreach ($products as &$product) {
             $product['pricing'] = calculateCurrentPrice($product);
            $product['platform_photo_id'] = $product['image_path'] ? (rtrim(PRODUCT_IMAGE_PUBLIC_URL_BASE, '/') . '/' . ltrim($product['image_path'], '/')) : null;
        }
        unset($product);

        return $products;
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error searching partner active products: " . $e->getMessage() . "\n", FILE_APPEND);
        return [];
    }
}


function countSearchPartnerActiveProducts(int $partner_user_id, string $searchTerm): int {
    try {
        $searchTermLike = '%' . $searchTerm . '%';

        $sql = "SELECT COUNT(p.id)
                FROM products p
                JOIN partner_products pp ON p.id = pp.product_id
                WHERE p.is_active = TRUE 
                  AND pp.partner_user_id = :partner_user_id 
                  AND pp.is_active = TRUE
                  AND p.name LIKE :searchTerm";
        
        $stmt = pdo()->prepare($sql);
        $stmt->bindValue(':partner_user_id', $partner_user_id, PDO::PARAM_INT);
        $stmt->bindValue(':searchTerm', $searchTermLike, PDO::PARAM_STR);
        
        $stmt->execute();
        return (int)$stmt->fetchColumn();
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error counting search partner active products: " . $e->getMessage() . "\n", FILE_APPEND);
        return 0;
    }
}


function getPartnerProductForManagement(int $partner_user_id, int $product_id): ?array {
    try {
        $sql = "SELECT p.*, pp.extra_price, pp.is_active as partner_is_active
                FROM products p
                LEFT JOIN partner_products pp ON p.id = pp.product_id AND pp.partner_user_id = :partner_user_id
                WHERE p.id = :product_id AND p.is_active = TRUE";
        
        $stmt = pdo()->prepare($sql);
        $stmt->bindValue(':partner_user_id', $partner_user_id, PDO::PARAM_INT);
        $stmt->bindValue(':product_id', $product_id, PDO::PARAM_INT);
        
        $stmt->execute();
        $product = $stmt->fetch();
        
        if ($product) {
            $product['pricing'] = calculateCurrentPrice($product);
            $product['platform_photo_id'] = $product['image_path'] ? (rtrim(PRODUCT_IMAGE_PUBLIC_URL_BASE, '/') . '/' . ltrim($product['image_path'], '/')) : null;
      }
        
        return $product ?: null;
        
    } catch (PDOException $e) {
        file_put_contents(ERROR_LOG_PATH, date('Y-m-d H:i:s') . " - DB Error getting product for partner management: " . $e->getMessage() . "\n", FILE_APPEND);
        return null;
    }
}

?>