<?php

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

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

Auth::requireEditAccess();
$admin = Auth::user();
$pdo = Database::connection();

$campaigns = $pdo->query('SELECT * FROM campaigns WHERE status = "active" ORDER BY name ASC')->fetchAll();
$creatorGroups = $pdo->query('SELECT * FROM creator_groups ORDER BY name ASC')->fetchAll();
$products = $pdo->query('SELECT * FROM products WHERE status = "active" ORDER BY name ASC')->fetchAll();

$created = [];
$failed = []; // creatorTag => error
$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    Csrf::requireValid();

    $campaignId = !empty($_POST['campaign_id']) ? (int) $_POST['campaign_id'] : null;
    $creatorGroupId = !empty($_POST['creator_group_id']) ? (int) $_POST['creator_group_id'] : null;
    $expiresAtRaw = trim($_POST['expires_at'] ?? '');
    $expiresAt = null;
    if ($expiresAtRaw !== '') {
        $parsedExpiry = DateTime::createFromFormat('Y-m-d', $expiresAtRaw);
        if (!$parsedExpiry || $parsedExpiry->format('Y-m-d') !== $expiresAtRaw) {
            $errors[] = I18n::t('claim_links_batch.error_invalid_expires');
        } else {
            $expiresAt = $expiresAtRaw . ' 23:59:59';
        }
    }

    $selectedProducts = $_POST['products'] ?? [];
    $overrides = $_POST['max_claims_override'] ?? [];
    if (empty($selectedProducts)) {
        $errors[] = I18n::t('claim_links_batch.error_no_products');
    }

    // Same paste-or-upload pattern as Import Keys -- one entry per line,
    // blank lines skipped. Unlike importing keys, a repeated entry isn't
    // treated as a duplicate to skip: the same creator legitimately
    // getting two separate links (e.g. two different campaigns run close
    // together) is a real use case, not a mistake.
    $tagsRaw = $_POST['creator_tags'] ?? '';
    $fileError = $_FILES['creator_tags_file']['error'] ?? UPLOAD_ERR_NO_FILE;
    $lines = [];
    if ($fileError === UPLOAD_ERR_OK) {
        $content = file_get_contents($_FILES['creator_tags_file']['tmp_name']);
        $lines = preg_split('/\r\n|\r|\n/', $content);
    } elseif ($fileError !== UPLOAD_ERR_NO_FILE) {
        $errors[] = I18n::t('claim_links_batch.error_file_upload_prefix') . ' ' . (
            in_array($fileError, [UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE], true)
                ? I18n::t('claim_links_batch.error_file_too_large')
                : I18n::t('claim_links_batch.error_file_upload_generic')
        );
    } elseif (trim($tagsRaw) !== '') {
        $lines = preg_split('/\r\n|\r|\n/', $tagsRaw);
    } else {
        $errors[] = I18n::t('claim_links_batch.error_no_input');
    }

    // Each line becomes one new user (never deduplicated -- see
    // UserFactory) and one claim link for them. Three shapes are
    // recognized, so a plain tag list, a bare email list, and a
    // "Name,Email" CSV export (e.g. from Sendy) all work in the same box
    // without a separate mode to pick -- same minimal-CSV tolerance as
    // Import Keys, not a full CSV parser, just enough to tell an email
    // column from a name column.
    $entries = [];
    foreach ($lines as $line) {
        $cols = array_values(array_filter(array_map('trim', explode(',', $line)), fn ($c) => $c !== ''));
        if (empty($cols)) {
            continue;
        }
        if (count($cols) >= 2 && filter_var($cols[1], FILTER_VALIDATE_EMAIL)) {
            $entries[] = ['label' => $cols[1], 'name' => $cols[0], 'email' => $cols[1]];
        } elseif (filter_var($cols[0], FILTER_VALIDATE_EMAIL)) {
            $entries[] = ['label' => $cols[0], 'name' => null, 'email' => $cols[0]];
        } else {
            $entries[] = ['label' => $cols[0], 'name' => $cols[0], 'email' => null];
        }
    }
    if (empty($entries) && empty($errors)) {
        $errors[] = I18n::t('claim_links_batch.error_no_entries_found');
    }

    if (empty($errors)) {
        $productOverrides = [];
        foreach ($selectedProducts as $productId => $checked) {
            $productId = (int) $productId;
            $overrideRaw = trim($overrides[$productId] ?? '');
            $productOverrides[$productId] = $overrideRaw === '' ? null : max(1, (int) $overrideRaw);
        }

        foreach ($entries as $entry) {
            $userId = UserFactory::create($entry['name'], $entry['email']);
            $result = ClaimLinkFactory::create($campaignId, $userId, $creatorGroupId, $expiresAt, $productOverrides);
            if ($result['ok']) {
                $created[] = ['tag' => $entry['label'], 'url' => Helpers::baseUrl() . '/claim/' . $result['token']];
            } else {
                $failed[$entry['label']] = $result['error'];
            }
        }

        if (!empty($created)) {
            AuditLog::log($admin['id'], 'claim_links_batch_created', 'created=' . count($created) . ' failed=' . count($failed));
        }
    }
}

$pageTitle = I18n::t('claim_links_batch.page_title');
$activeNav = 'claim_links';
$extraAdminCss = 'admin-product-editor';
require __DIR__ . '/includes/layout_header.php';
?>
<div class="topbar"><h1><?= Helpers::e(I18n::t('claim_links_batch.heading')) ?></h1></div>

<?php if (!empty($errors)): ?>
  <div class="form-section" style="border-color:var(--danger); margin-bottom:16px;">
    <?php foreach ($errors as $err): ?><p style="color:var(--danger); font-size:13px; margin:0;"><?= Helpers::e($err) ?></p><?php endforeach; ?>
  </div>
<?php endif; ?>

<?php if (!empty($created) || !empty($failed)): ?>
  <div class="form-section" style="border-color:var(--signal-dim); margin-bottom:16px;">
    <p style="color:var(--signal); font-size:14px; font-weight:600; margin:0 0 6px;"><?= Helpers::e(sprintf(I18n::t('claim_links_batch.summary_created'), count($created))) ?><?= !empty($failed) ? Helpers::e(sprintf(I18n::t('claim_links_batch.summary_failed_suffix'), count($failed))) : '' ?>.</p>
    <?php if (!empty($created)): ?>
      <div style="margin-top:10px; max-height:280px; overflow-y:auto;">
        <?php foreach ($created as $c): ?>
          <div style="display:flex; gap:8px; align-items:center; margin-bottom:8px;">
            <span style="font-size:12.5px; color:var(--text-muted); min-width:140px; flex-shrink:0;"><?= Helpers::e($c['tag']) ?></span>
            <input type="text" readonly value="<?= Helpers::e($c['url']) ?>" onclick="this.select();"
                   style="flex:1; min-width:0; background:var(--bg-void); border:1px solid var(--line); color:var(--text-primary); font-family:var(--font-mono); font-size:12px; padding:7px 10px; border-radius:8px;">
            <button type="button" class="btn btn-ghost" style="flex-shrink:0; padding:7px 12px; font-size:12px;" onclick="navigator.clipboard.writeText('<?= Helpers::e($c['url']) ?>'); this.textContent=<?= json_encode(I18n::t('claim_links_batch.copied_label'), JSON_HEX_APOS | JSON_HEX_QUOT) ?>;"><?= Helpers::e(I18n::t('claim_links_batch.copy_button')) ?></button>
          </div>
        <?php endforeach; ?>
      </div>
    <?php endif; ?>
    <?php if (!empty($failed)): ?>
      <details style="margin-top:8px;">
        <summary style="color:var(--danger); font-size:12.5px; cursor:pointer;"><?= Helpers::e(I18n::t('claim_links_batch.show_failed_summary')) ?></summary>
        <div style="margin-top:6px;">
          <?php foreach ($failed as $tag => $err): ?>
            <p style="font-size:12px; color:var(--text-muted); margin:2px 0;"><?= Helpers::e($tag) ?>: <span style="color:var(--danger);"><?= Helpers::e($err) ?></span></p>
          <?php endforeach; ?>
        </div>
      </details>
    <?php endif; ?>
    <p style="margin:12px 0 0;"><a href="claim_links.php" style="color:var(--signal); font-size:13px;"><?= Helpers::e(I18n::t('claim_links_batch.view_all_link')) ?></a> · <a href="claim_links_batch.php" style="color:var(--signal); font-size:13px;"><?= Helpers::e(I18n::t('claim_links_batch.batch_create_more_link')) ?></a></p>
  </div>
<?php endif; ?>

<?php if (empty($products)): ?>
  <div class="panel">
    <p style="color:var(--text-muted); font-size:13px;">
      <?= Helpers::e(I18n::t('claim_links_batch.no_products_notice')) ?>
      <a href="product_form.php" style="color:var(--signal);"><?= Helpers::e(I18n::t('claim_links_batch.create_product_link')) ?></a>
    </p>
  </div>
<?php else: ?>
<form method="post" enctype="multipart/form-data" class="form-shell">
  <?= Csrf::field() ?>

  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('claim_links_batch.section_shared_settings')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('claim_links_batch.shared_settings_hint')) ?></p>
    <div class="field-row">
      <div class="field">
        <label><?= Helpers::e(I18n::t('claim_links_batch.campaign_label')) ?> <span style="color:var(--text-faint); font-weight:400;"><?= Helpers::e(I18n::t('claim_links_batch.optional_suffix')) ?></span></label>
        <select name="campaign_id">
          <option value=""><?= Helpers::e(I18n::t('claim_links_batch.no_campaign')) ?></option>
          <?php foreach ($campaigns as $c): ?>
            <option value="<?= (int) $c['id'] ?>"><?= Helpers::e($c['name']) ?> <?= Helpers::e(sprintf(I18n::t('claim_links_batch.campaign_option_limit'), (int) $c['default_max_claims'])) ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <div class="field">
        <label><?= Helpers::e(I18n::t('claim_links_batch.creator_group_label')) ?> <span style="color:var(--text-faint); font-weight:400;"><?= Helpers::e(I18n::t('claim_links_batch.optional_suffix')) ?></span></label>
        <select name="creator_group_id">
          <option value=""><?= Helpers::e(I18n::t('claim_links_batch.creator_group_none')) ?></option>
          <?php foreach ($creatorGroups as $g): ?>
            <option value="<?= (int) $g['id'] ?>"><?= Helpers::e($g['name']) ?><?= $g['default_max_claims'] !== null ? ' ' . Helpers::e(sprintf(I18n::t('claim_links_batch.creator_group_option_limit'), (int) $g['default_max_claims'])) : '' ?></option>
          <?php endforeach; ?>
        </select>
      </div>
    </div>
    <div class="field">
      <label><?= Helpers::e(I18n::t('claim_links_batch.expires_label')) ?> <span style="color:var(--text-faint); font-weight:400;"><?= Helpers::e(I18n::t('claim_links_batch.optional_suffix')) ?></span></label>
      <div style="display:flex; gap:8px; align-items:center;">
        <input type="date" name="expires_at" id="expires-at-input" style="-webkit-appearance:none; appearance:none; height:41px !important; box-sizing:border-box; flex:1;">
        <button type="button" class="btn btn-ghost" style="flex-shrink:0; padding:10px 14px;" onclick="document.getElementById('expires-at-input').value='';"><?= Helpers::e(I18n::t('claim_links_batch.clear_button')) ?></button>
      </div>
    </div>
  </div>

  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('claim_links_batch.section_products')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('claim_links_batch.products_hint')) ?></p>
    <?php foreach ($products as $p): ?>
      <div style="display:flex; align-items:center; gap:12px; padding:10px 0; border-bottom:1px solid var(--line);">
        <label style="display:flex; align-items:center; gap:8px; flex:1; cursor:pointer; margin:0;">
          <input type="checkbox" name="products[<?= (int) $p['id'] ?>]" value="1" style="width:auto;">
          <span style="font-size:13.5px; color:var(--text-primary);"><?= Helpers::e($p['name']) ?></span>
        </label>
        <input type="number" name="max_claims_override[<?= (int) $p['id'] ?>]" min="1" placeholder="<?= Helpers::e(I18n::t('claim_links_batch.override_placeholder')) ?>" style="width:100px; margin:0;">
      </div>
    <?php endforeach; ?>
  </div>

  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('claim_links_batch.section_creators')) ?></p>
    <p class="form-section-hint">
      <?= I18n::t('claim_links_batch.creators_hint') ?>
    </p>
    <div class="field">
      <label><?= Helpers::e(I18n::t('claim_links_batch.paste_label')) ?></label>
      <textarea name="creator_tags" rows="8" style="width:100%; background:var(--bg-void); border:1px solid var(--line); color:var(--text-primary); font-family:var(--font-mono); font-size:12.5px; padding:10px 12px; border-radius:8px;" placeholder="<?= Helpers::e(I18n::t('claim_links_batch.paste_placeholder')) ?>"></textarea>
    </div>
    <div class="field">
      <label><?= Helpers::e(I18n::t('claim_links_batch.upload_label')) ?></label>
      <label class="btn btn-ghost file-choose-label" style="cursor:pointer; display:inline-flex; align-items:center; gap:8px;">
        <span><?= Helpers::e(I18n::t('claim_links_batch.choose_file_button')) ?></span>
        <span id="tags-file-name" style="color:var(--text-faint); font-weight:400;"><?= Helpers::e(I18n::t('claim_links_batch.no_file_chosen')) ?></span>
        <input type="file" name="creator_tags_file" accept=".csv,.txt,text/csv,text/plain" style="display:none;" onchange="document.getElementById('tags-file-name').textContent = this.files[0]?.name || <?= json_encode(I18n::t('claim_links_batch.no_file_chosen'), JSON_HEX_APOS | JSON_HEX_QUOT) ?>;">
      </label>
    </div>
  </div>

  <div class="form-actions">
    <a href="claim_links.php" class="btn btn-ghost" style="text-decoration:none;"><?= Helpers::e(I18n::t('claim_links_batch.cancel_button')) ?></a>
    <button type="submit" class="btn btn-primary"><?= Helpers::e(I18n::t('claim_links_batch.create_links_button')) ?></button>
  </div>
</form>
<?php endif; ?>

<?php require __DIR__ . '/includes/layout_footer.php'; ?>
