<?php
/**
 * AURA FARMING — Diamantes — Parte 03
 * Funções administrativas para Pacotes de Diamantes.
 */

if (!defined('AURA_DIAMONDS_PART03_VERSION')) {
    define('AURA_DIAMONDS_PART03_VERSION', '3.0.0');
}

require_once __DIR__ . '/diamond_functions.php';

function afDiamondsAdminSlug(string $value): string
{
    $value = trim($value);
    $ascii = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $value);
    if ($ascii !== false) $value = $ascii;
    $value = strtolower($value);
    $value = preg_replace('/[^a-z0-9]+/', '_', $value) ?: 'pacote';
    $value = trim($value, '_');
    $value = substr($value ?: 'pacote', 0, 42);
    return $value ?: 'pacote';
}

function afDiamondsAdminParsePrice(string|float|int $value): float
{
    $raw = trim((string)$value);
    if ($raw === '') return 0.0;
    $raw = str_replace(['R$', ' ', "\xc2\xa0"], '', $raw);
    if (str_contains($raw, ',') && str_contains($raw, '.')) {
        $raw = str_replace('.', '', $raw);
        $raw = str_replace(',', '.', $raw);
    } elseif (str_contains($raw, ',')) {
        $raw = str_replace(',', '.', $raw);
    }
    return round((float)$raw, 2);
}

function afDiamondsAdminUniqueCode(PDO $pdo, string $name, int $ignoreId = 0, ?string $preferred = null): string
{
    $base = afDiamondsAdminSlug($preferred ?: $name);
    if (!str_starts_with($base, 'pack_')) $base = 'pack_' . $base;
    $base = substr($base, 0, 52);
    $candidate = $base;
    for ($i = 0; $i < 50; $i++) {
        $sql = 'SELECT id FROM af_diamond_packages WHERE code = ?';
        $params = [$candidate];
        if ($ignoreId > 0) {
            $sql .= ' AND id <> ?';
            $params[] = $ignoreId;
        }
        $sql .= ' LIMIT 1';
        $st = $pdo->prepare($sql);
        $st->execute($params);
        if (!$st->fetchColumn()) return $candidate;
        $suffix = '_' . random_int(100, 9999);
        $candidate = substr($base, 0, 60 - strlen($suffix)) . $suffix;
    }
    return substr($base, 0, 48) . '_' . bin2hex(random_bytes(4));
}

function afDiamondsAdminValidatePackage(array $data): array
{
    $name = function_exists('sanitize') ? sanitize($data['name'] ?? '') : trim(strip_tags((string)($data['name'] ?? '')));
    $description = function_exists('sanitize') ? sanitize($data['description'] ?? '') : trim(strip_tags((string)($data['description'] ?? '')));
    $mpTitle = function_exists('sanitize') ? sanitize($data['mercado_pago_title'] ?? '') : trim(strip_tags((string)($data['mercado_pago_title'] ?? '')));
    $code = function_exists('sanitize') ? sanitize($data['code'] ?? '') : trim(strip_tags((string)($data['code'] ?? '')));

    if (mb_strlen($name) < 3 || mb_strlen($name) > 120) {
        throw new RuntimeException('Informe um nome de pacote com 3 a 120 caracteres.');
    }

    $diamonds = (int)($data['diamonds'] ?? 0);
    $bonus = (int)($data['bonus_diamonds'] ?? 0);
    $price = afDiamondsAdminParsePrice($data['price'] ?? '0');
    $sort = max(0, (int)($data['sort_order'] ?? 0));
    $active = !empty($data['active']) ? 1 : 0;

    if ($diamonds <= 0 || $diamonds > 1000000) {
        throw new RuntimeException('A quantidade de Diamantes deve ser maior que zero.');
    }
    if ($bonus < 0 || $bonus > 1000000) {
        throw new RuntimeException('O bônus de Diamantes não pode ser negativo.');
    }
    if ($price <= 0 || $price > 999999.99) {
        throw new RuntimeException('Informe um preço válido maior que zero.');
    }

    $code = afDiamondsAdminSlug($code ?: $name);
    if (!str_starts_with($code, 'pack_')) $code = 'pack_' . $code;

    return [
        'code' => substr($code, 0, 60),
        'name' => $name,
        'description' => $description !== '' ? substr($description, 0, 255) : null,
        'diamonds' => $diamonds,
        'bonus_diamonds' => $bonus,
        'price' => $price,
        'currency' => 'BRL',
        'active' => $active,
        'sort_order' => $sort,
        'mercado_pago_title' => $mpTitle !== '' ? substr($mpTitle, 0, 150) : 'Aura Farming - ' . $diamonds . ' Diamantes',
    ];
}

function afDiamondsAdminListPackages(PDO $pdo, string $status = 'all'): array
{
    afDiamondsAssertInstalled($pdo);
    $where = '';
    if ($status === 'active') $where = 'WHERE active = 1';
    if ($status === 'inactive') $where = 'WHERE active = 0';
    $st = $pdo->query("SELECT * FROM af_diamond_packages {$where} ORDER BY sort_order ASC, active DESC, diamonds ASC, id ASC");
    return $st->fetchAll() ?: [];
}

function afDiamondsAdminGetPackage(PDO $pdo, int $id): ?array
{
    afDiamondsAssertInstalled($pdo);
    if ($id <= 0) return null;
    $st = $pdo->prepare('SELECT * FROM af_diamond_packages WHERE id = ? LIMIT 1');
    $st->execute([$id]);
    $row = $st->fetch();
    return $row ?: null;
}

function afDiamondsAdminSavePackage(PDO $pdo, array $data, ?int $adminId = null): int
{
    afDiamondsAssertInstalled($pdo);
    $id = (int)($data['id'] ?? 0);
    $payload = afDiamondsAdminValidatePackage($data);
    $payload['code'] = afDiamondsAdminUniqueCode($pdo, $payload['name'], $id, $payload['code']);

    $before = $id > 0 ? afDiamondsAdminGetPackage($pdo, $id) : null;
    if ($id > 0 && !$before) throw new RuntimeException('Pacote de Diamantes não encontrado.');

    if ($id > 0) {
        $st = $pdo->prepare('UPDATE af_diamond_packages SET code=?, name=?, description=?, diamonds=?, bonus_diamonds=?, price=?, currency=?, active=?, sort_order=?, mercado_pago_title=?, updated_at=NOW() WHERE id=?');
        $st->execute([
            $payload['code'], $payload['name'], $payload['description'], $payload['diamonds'], $payload['bonus_diamonds'],
            $payload['price'], $payload['currency'], $payload['active'], $payload['sort_order'], $payload['mercado_pago_title'], $id,
        ]);
        $action = 'diamond_package_updated';
    } else {
        $st = $pdo->prepare('INSERT INTO af_diamond_packages (code, name, description, diamonds, bonus_diamonds, price, currency, active, sort_order, mercado_pago_title, metadata_json, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,NOW(),NOW())');
        $st->execute([
            $payload['code'], $payload['name'], $payload['description'], $payload['diamonds'], $payload['bonus_diamonds'],
            $payload['price'], $payload['currency'], $payload['active'], $payload['sort_order'], $payload['mercado_pago_title'],
            afDiamondsJson(['created_by' => $adminId, 'parte' => '03']),
        ]);
        $id = (int)$pdo->lastInsertId();
        $action = 'diamond_package_created';
    }

    $after = afDiamondsAdminGetPackage($pdo, $id) ?: [];
    if (function_exists('afAdminLog')) {
        afAdminLog($pdo, $action, 'diamond_package', $id, ['antes' => $before, 'depois' => $after]);
    } else {
        afDiamondsAudit($pdo, $action, 'diamond_package', $id, $before ?: [], $after, ['actor_admin_id' => $adminId, 'source' => 'admin_diamond_packages']);
    }
    return $id;
}

function afDiamondsAdminTogglePackage(PDO $pdo, int $id, int $active, ?int $adminId = null): void
{
    afDiamondsAssertInstalled($pdo);
    $pkg = afDiamondsAdminGetPackage($pdo, $id);
    if (!$pkg) throw new RuntimeException('Pacote de Diamantes não encontrado.');
    $active = $active ? 1 : 0;
    $pdo->prepare('UPDATE af_diamond_packages SET active = ?, updated_at = NOW() WHERE id = ?')->execute([$active, $id]);
    $after = afDiamondsAdminGetPackage($pdo, $id) ?: [];
    if (function_exists('afAdminLog')) {
        afAdminLog($pdo, $active ? 'diamond_package_activated' : 'diamond_package_deactivated', 'diamond_package', $id, ['antes' => $pkg, 'depois' => $after]);
    } else {
        afDiamondsAudit($pdo, $active ? 'diamond_package_activated' : 'diamond_package_deactivated', 'diamond_package', $id, $pkg, $after, ['actor_admin_id' => $adminId, 'source' => 'admin_diamond_packages']);
    }
}

function afDiamondsAdminPackageStats(PDO $pdo): array
{
    afDiamondsAssertInstalled($pdo);
    $stats = ['total' => 0, 'active' => 0, 'inactive' => 0, 'min_price' => 0, 'max_price' => 0];
    $row = $pdo->query('SELECT COUNT(*) total, SUM(active=1) active, SUM(active=0) inactive, MIN(price) min_price, MAX(price) max_price FROM af_diamond_packages')->fetch() ?: [];
    foreach ($stats as $k => $v) {
        if (array_key_exists($k, $row)) $stats[$k] = $row[$k] !== null ? (float)$row[$k] : 0;
    }
    return $stats;
}
