<?php

require __DIR__ . '/../bootstrap.php';

use KeyLair\Auth;
use KeyLair\AuditLog;
use KeyLair\Csrf;
use KeyLair\Database;
use KeyLair\Helpers;
use KeyLair\I18n;

// A claim link's own URL is a bearer credential -- whoever has it can claim
// real keys -- so this gets the same access level as keys_export.php rather
// than the plain requireLogin() the rest of Claim Links uses.
Auth::requireEditAccess();
$admin = Auth::user();
$pdo = Database::connection();

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    die('This page only accepts POST requests.');
}
Csrf::requireValid();

// A single id exports just that one link (the per-row "Export" action);
// no id exports every link (the topbar "Export CSV" action).
$id = (int) ($_POST['id'] ?? 0);

$where = $id > 0 ? 'WHERE l.id = :id' : '';
$stmt = $pdo->prepare(
    "SELECT l.*, c.name AS campaign_name, u.name AS user_name, u.email AS user_email
     FROM claim_links l
     LEFT JOIN campaigns c ON c.id = l.campaign_id
     LEFT JOIN users u ON u.id = l.user_id
     {$where}
     ORDER BY l.created_at DESC"
);
$id > 0 ? $stmt->execute(['id' => $id]) : $stmt->execute();
$links = $stmt->fetchAll();

if ($id > 0 && empty($links)) {
    http_response_code(404);
    die('Claim link not found.');
}

$productsByLink = [];
$productRows = $pdo->query(
    'SELECT clp.claim_link_id, p.name, p.slug, clp.max_claims, clp.claims_used
     FROM claim_link_products clp
     JOIN products p ON p.id = clp.product_id
     ORDER BY clp.id'
)->fetchAll();
foreach ($productRows as $pr) {
    $productsByLink[$pr['claim_link_id']][] = $pr;
}

// Same formula-injection guard as keys_export.php's own CSV -- a user's
// name/email or a campaign name is free text an admin typed, so it's just
// as capable of starting with =/+/-/@ as anything else exported from here.
function kv_csv_safe(?string $value): string
{
    $value = (string) $value;
    return preg_match('/^[=+\-@]/', $value) ? "'" . $value : $value;
}

$baseUrl = Helpers::baseUrl();
$filename = $id > 0 ? "claim-link-{$id}.csv" : ('claim-links-' . date('Y-m-d') . '.csv');

AuditLog::log($admin['id'], 'claim_links_exported', $id > 0 ? "id={$id}" : 'all id=0 count=' . count($links));

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');

$out = fopen('php://output', 'w');
fputcsv($out, [
    I18n::t('claim_links_export.csv_header_user'),
    I18n::t('claim_links_export.csv_header_email'),
    I18n::t('claim_links_export.csv_header_campaign'),
    I18n::t('claim_links_export.csv_header_status'),
    I18n::t('claim_links_export.csv_header_created_at'),
    I18n::t('claim_links_export.csv_header_expires_at'),
    I18n::t('claim_links_export.csv_header_overview_url'),
    I18n::t('claim_links_export.csv_header_products'),
]);
foreach ($links as $l) {
    $overviewUrl = $baseUrl . '/claim/' . $l['token'];
    $productParts = [];
    foreach ($productsByLink[$l['id']] ?? [] as $pr) {
        $productUrl = $overviewUrl . '/' . $pr['slug'];
        $productParts[] = kv_csv_safe($pr['name']) . ': ' . (int) $pr['claims_used'] . '/' . (int) $pr['max_claims'] . ': ' . $productUrl;
    }
    $statusLabel = $l['status'] === 'active' ? I18n::t('claim_links_export.status_active') : I18n::t('claim_links_export.status_disabled');
    fputcsv($out, [
        kv_csv_safe($l['user_name'] ?? sprintf(I18n::t('claim_links_export.user_placeholder'), (int) $l['user_id'])),
        kv_csv_safe($l['user_email'] ?? ''),
        kv_csv_safe($l['campaign_name']),
        $statusLabel,
        $l['created_at'],
        $l['expires_at'] ?? '',
        $overviewUrl,
        implode(' | ', $productParts),
    ]);
}
fclose($out);
