PDO::ERRMODE_EXCEPTION]); $pdo->exec("CREATE TABLE IF NOT EXISTS admin.rotation_domains (id SERIAL PRIMARY KEY, domain VARCHAR(255) UNIQUE, pool VARCHAR(100) DEFAULT 'default', sends_today INTEGER DEFAULT 0, sends_total INTEGER DEFAULT 0, last_used TIMESTAMP, reputation INTEGER DEFAULT 100, status VARCHAR(50) DEFAULT 'active')"); $pdo->exec("CREATE TABLE IF NOT EXISTS admin.rotation_config (id SERIAL PRIMARY KEY, pool VARCHAR(100) UNIQUE, max_per_day INTEGER DEFAULT 1000, cooldown_hours INTEGER DEFAULT 24, min_reputation INTEGER DEFAULT 50)"); $action = $_POST['action'] ?? $_GET['action'] ?? ''; switch ($action) { case 'add': $stmt = $pdo->prepare("INSERT INTO admin.rotation_domains (domain, pool) VALUES (?, ?) ON CONFLICT (domain) DO NOTHING"); $stmt->execute([$_POST['domain'], $_POST['pool'] ?? 'default']); echo json_encode(['success' => true]); break; case 'bulk_add': $domains = explode("\n", $_POST['domains']); $pool = $_POST['pool'] ?? 'default'; $count = 0; foreach ($domains as $d) { $d = trim($d); if ($d) { $pdo->prepare("INSERT INTO admin.rotation_domains (domain, pool) VALUES (?, ?) ON CONFLICT DO NOTHING")->execute([$d, $pool]); $count++; } } echo json_encode(['success' => true, 'added' => $count]); break; case 'list': $pool = $_GET['pool'] ?? null; $where = $pool ? "WHERE pool = " . $pdo->quote($pool) : ""; $domains = $pdo->query("SELECT * FROM admin.rotation_domains $where ORDER BY last_used NULLS FIRST, sends_today ASC")->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['domains' => $domains]); break; case 'get_next': $pool = $_POST['pool'] ?? 'default'; $config = $pdo->query("SELECT * FROM admin.rotation_config WHERE pool = " . $pdo->quote($pool))->fetch(PDO::FETCH_ASSOC); $maxPerDay = $config['max_per_day'] ?? 1000; $minRep = $config['min_reputation'] ?? 50; $domain = $pdo->query("SELECT * FROM admin.rotation_domains WHERE pool = " . $pdo->quote($pool) . " AND status = 'active' AND sends_today < $maxPerDay AND reputation >= $minRep ORDER BY last_used NULLS FIRST, sends_today ASC LIMIT 1")->fetch(PDO::FETCH_ASSOC); if ($domain) { $pdo->exec("UPDATE admin.rotation_domains SET sends_today = sends_today + 1, sends_total = sends_total + 1, last_used = NOW() WHERE id = {$domain['id']}"); echo json_encode(['success' => true, 'domain' => $domain['domain']]); } else { echo json_encode(['success' => false, 'error' => 'No available domains']); } break; case 'update_reputation': $pdo->prepare("UPDATE admin.rotation_domains SET reputation = ? WHERE domain = ?")->execute([$_POST['reputation'], $_POST['domain']]); echo json_encode(['success' => true]); break; case 'reset_daily': $pdo->exec("UPDATE admin.rotation_domains SET sends_today = 0"); echo json_encode(['success' => true]); break; case 'pools': $pools = $pdo->query("SELECT pool, COUNT(*) as domains, SUM(sends_today) as sends_today, SUM(sends_total) as sends_total FROM admin.rotation_domains GROUP BY pool")->fetchAll(PDO::FETCH_ASSOC); echo json_encode(['pools' => $pools]); break; case 'set_config': $pdo->prepare("INSERT INTO admin.rotation_config (pool, max_per_day, cooldown_hours, min_reputation) VALUES (?, ?, ?, ?) ON CONFLICT (pool) DO UPDATE SET max_per_day = ?, cooldown_hours = ?, min_reputation = ?") ->execute([$_POST['pool'], $_POST['max_per_day'], $_POST['cooldown_hours'], $_POST['min_reputation'], $_POST['max_per_day'], $_POST['cooldown_hours'], $_POST['min_reputation']]); echo json_encode(['success' => true]); break; default: echo json_encode(['actions' => ['add','bulk_add','list','get_next','update_reputation','reset_daily','pools','set_config']]); }