<?php
$config = require __DIR__ . '/../lib/config.php';
require __DIR__ . '/../lib/db.php';
require __DIR__ . '/../lib/helpers.php';

/** Prevent cached copies of this page */
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

$isDemo = !empty($config['demo_mode']);

/**
 * 1) Resolve a default base URL
 *    - config['base_url'] as canonical fallback
 *    - BUT prefer the current host so CNAMEs / custom domains work
 */
$defaultBase = rtrim($config['base_url'] ?? '', '/');

$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
  ? 'https://'
  : 'http://';

$host = $_SERVER['HTTP_HOST'] ?? '';
// If we’re being accessed via a custom domain/CNAME, use that.
// Otherwise fall back to the configured base_url.
$base = $host
  ? rtrim($scheme . $host, '/')
  : $defaultBase;

/**
 * Global default brand (overridden per company/org once request is known)
 */
$brandConfig = [
  'name'          => 'Towlens',
  'sub'           => 'Vehicle Imaging Portal',
  'color'         => '#0f6fff',
  'logo_url'      => null,
  'support_email' => null,
];

$GLOBALS['brandConfig'] = $brandConfig;
$GLOBALS['isDemo']      = $isDemo;
$GLOBALS['base']        = $base;
$GLOBALS['defaultBase'] = $defaultBase;

/**
 * Best-guess client IP.
 */
if (!function_exists('client_ip')) {
  function client_ip(): string {
    $candidates = [
      'HTTP_CF_CONNECTING_IP',
      'HTTP_X_FORWARDED_FOR',
      'HTTP_CLIENT_IP',
      'REMOTE_ADDR',
    ];
    foreach ($candidates as $key) {
      if (empty($_SERVER[$key])) continue;
      $raw = $_SERVER[$key];

      if ($key === 'HTTP_X_FORWARDED_FOR') {
        $parts = array_map('trim', explode(',', $raw));
        foreach ($parts as $part) {
          if (filter_var($part, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
            return $part;
          }
        }
        continue;
      }

      if (filter_var($raw, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6)) {
        return $raw;
      }
    }
    return 'unknown';
  }
}

/**
 * Branded message page (used for invalid/expired/closed/etc).
 * Uses $GLOBALS['brandConfig'] so it reflects company branding when available.
 */
function render_message(int $code, string $title, string $lead, string $detail = ''): void {
  http_response_code($code);

  $isDemo = !empty($GLOBALS['isDemo']);
  $brand  = $GLOBALS['brandConfig'] ?? [];
  $bName  = $brand['name']        ?? 'Towlens';
  $bSub   = $brand['sub']         ?? 'Vehicle Imaging Portal';
  $bColor = $brand['color']       ?? '#0f6fff';
  $bLogo  = $brand['logo_url']    ?? null;

  $initials = mb_strtoupper(
    mb_substr(preg_replace('/[^A-Za-z]/u','', $bName) ?: 'TL', 0, 2)
  );
  ?>
  <!doctype html>
  <html lang="en" class="h-full">
  <head>
    <meta charset="utf-8">
    <title><?= esc($title) ?><?= $isDemo ? ' — Demo Mode' : '' ?></title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="color-scheme" content="light dark">
    <style>
      :root{
        --brand: <?= esc($bColor) ?>;
        --ink:#0b1220; --muted:#5b6478; --bg:#f6f7fb; --card:#ffffff; --ring:#d6d9e2;
      }
      @media (prefers-color-scheme: dark){
        :root{
          --ink:#eef3ff; --muted:#a9b3c7; --bg:#0b0f1a; --card:#12192a; --ring:#27314a;
        }
      }
      *{box-sizing:border-box} html,body{height:100%}
      body{
        margin:0; font:16px/1.5 system-ui,Segoe UI,Roboto,Arial,Helvetica,sans-serif; color:var(--ink);
        background:
          radial-gradient(1200px 600px at 10% -10%, rgba(15,111,255,.16), transparent 60%),
          radial-gradient(900px 500px at 110% 0%,   rgba(15,111,255,.10), transparent 60%),
          var(--bg);
        display:grid; place-items:center; padding:24px;
      }
      .card{
        width:min(720px, 92vw);
        background:var(--card); border:1px solid var(--ring); border-radius:20px;
        box-shadow:0 18px 40px rgba(15,17,23,.08);
        overflow:hidden; position:relative; animation:pop .35s ease-out;
      }
      @keyframes pop{from{transform:translateY(8px) scale(.98);opacity:0}to{transform:none;opacity:1}}
      .hdr{
        display:flex;gap:12px;align-items:center;
        padding:18px 20px;
        background:linear-gradient(180deg, rgba(15,111,255,.12), transparent 70%);
        border-bottom:1px solid var(--ring);
      }
      .logo{
        width:40px;height:40px;border-radius:12px;background:var(--brand);color:#fff;
        display:grid;place-items:center;font-weight:800;letter-spacing:.5px;
        box-shadow:inset 0 0 0 2px rgba(255,255,255,.25);
        overflow:hidden;
      }
      .logo img{width:100%;height:100%;object-fit:contain;border-radius:12px}
      .title-wrap{display:flex;flex-direction:column;gap:2px}
      .brand-name{font-size:13px;color:var(--muted);margin:0}
      .title{margin:0;font-size:18px}
      .sub{margin:0;font-size:12px;color:var(--muted)}
      .body{padding:20px}
      .lead{font-size:17px;margin:0 0 8px}
      .muted{color:var(--muted);margin:0 0 16px}
      footer{
        text-align:center;padding:12px;font-size:12px;
        color:var(--muted);border-top:1px solid var(--ring)
      }
      footer a{color:var(--brand);text-decoration:none}
      footer a:hover{text-decoration:underline}
      .demo-badge{
        position:absolute;right:12px;top:12px;
        background:#f8d7da;color:#842029;border:1px solid #f5c2c7;
        border-radius:999px;padding:4px 8px;font-size:11px;
        box-shadow:0 2px 8px rgba(0,0,0,.08)
      }
    </style>
  </head>
  <body>
    <main class="card" role="main" aria-labelledby="msg-title">
      <?php if ($isDemo): ?><div class="demo-badge">DEMO</div><?php endif; ?>
      <header class="hdr">
        <div class="logo">
          <?php if ($bLogo): ?>
            <img src="<?= esc($bLogo) ?>" alt="<?= esc($bName) ?>">
          <?php else: ?>
            <?= esc($initials) ?>
          <?php endif; ?>
        </div>
        <div class="title-wrap">
          <p class="brand-name"><?= esc($bName) ?></p>
          <h1 id="msg-title" class="title"><?= esc($title) ?></h1>
          <p class="sub"><?= esc($bSub) ?></p>
        </div>
      </header>
      <section class="body">
        <p class="lead"><?= esc($lead) ?></p>
        <?php if ($detail !== ''): ?><p class="muted"><?= esc($detail) ?></p><?php endif; ?>
      </section>
      <footer>
        Powered by
        <a href="https://mpmg.co.uk/software" target="_blank" rel="noopener">Mount Pleasant Motoring Services Ltd</a>
      </footer>
    </main>
  </body>
  </html>
  <?php
  exit;
}

// ------- Load request via token -------
$token = $_GET['token'] ?? '';
if (!preg_match('/^[a-f0-9-]{36}$/i', $token)) {
  render_message(400, 'Invalid link', 'The upload link is not valid.', 'Please check the link you were sent and try again.');
}

$stmt = $pdo->prepare("SELECT * FROM requests WHERE token = ?");
$stmt->execute([$token]);
$req = $stmt->fetch();

if (!$req) {
  render_message(404, 'Request not found', 'We could not find this upload request.', 'It may have been removed or the link is incorrect.');
}

try {
  $ip = client_ip();
  $note = "Page viewed from IP: {$ip}";
  $logStmt = $pdo->prepare("INSERT INTO request_notes (request_id, notes) VALUES (?, ?)");
  $logStmt->execute([$req['id'], $note]);
} catch (Throwable $e) {
  // Do not block the page if logging fails.
}

/** Log a note for every valid page load, including IP (multi-tenant aware) */
if (!function_exists('mpms_table_has_column')) {
    function mpms_table_has_column(PDO $pdo, string $table, string $column): bool
    {
        static $cache = [];
        $key = $table . '.' . $column;
        if (isset($cache[$key])) {
            return $cache[$key];
        }

        try {
            $sql  = "SHOW COLUMNS FROM `{$table}` LIKE " . $pdo->quote($column);
            $stmt = $pdo->query($sql);
            $cache[$key] = $stmt !== false && (bool)$stmt->fetch();
        } catch (Throwable $e) {
            // If detection fails, treat as "no such column"
            $cache[$key] = false;
        }

        return $cache[$key];
    }
}

try {
    $ip       = client_ip();
    $noteText = "Page viewed from IP: {$ip}";

    // Tenancy from the request row if present
    $orgId = array_key_exists('organisation_id', $req) ? (int)$req['organisation_id'] : null;

    if (array_key_exists('company_id', $req)) {
        $companyId = $req['company_id'] !== null ? (int)$req['company_id'] : null;
    } elseif (array_key_exists('company', $req)) {
        $companyId = $req['company'] !== null ? (int)$req['company'] : null;
    } else {
        $companyId = null;
    }

    $cols   = ['request_id'];
    $params = [(int)$req['id']];

    if (mpms_table_has_column($pdo, 'request_notes', 'organisation_id')) {
        $cols[]   = 'organisation_id';
        $params[] = $orgId;
    }
    if (mpms_table_has_column($pdo, 'request_notes', 'company_id')) {
        $cols[]   = 'company_id';
        $params[] = $companyId;
    } elseif (mpms_table_has_column($pdo, 'request_notes', 'company')) {
        $cols[]   = 'company';
        $params[] = $companyId;
    }

    $cols[]   = 'notes';
    $params[] = $noteText;

    $placeholders = implode(',', array_fill(0, count($cols), '?'));
    $sql = "INSERT INTO request_notes (" . implode(',', $cols) . ") VALUES ($placeholders)";

    $logStmt = $pdo->prepare($sql);
    $logStmt->execute($params);
} catch (Throwable $e) {
    // Don’t block the page if logging fails.
    if (($config['env'] ?? 'prod') === 'dev') {
        error_log('View-log insert failed: ' . $e->getMessage());
    }
}

$orgId     = (int)($req['organisation_id'] ?? 0);
$companyId = (int)($req['company_id'] ?? 0);

// ------- Company-first branding -------

$brandName   = $brandConfig['name'];
$brandSub    = $brandConfig['sub'];
$brandColor  = $brandConfig['color'];
$brandLogo   = $brandConfig['logo_url'];
$brandSubSet = false;

// Start from whatever base we decided earlier
$base        = $GLOBALS['base']        ?? ($GLOBALS['defaultBase'] ?? '');
$defaultBase = $GLOBALS['defaultBase'] ?? $base;

// Prefer company branding if company_id present
if ($companyId > 0) {
  try {
    $cs = $pdo->prepare("
      SELECT
        name,
        brand_name,
        brand_subtitle,
        brand_color,
        logo_url,
        support_email,
        public_base_url
      FROM companies
      WHERE id = ?
      LIMIT 1
    ");
    $cs->execute([$companyId]);
    if ($c = $cs->fetch(PDO::FETCH_ASSOC)) {
      $brandName  = $c['brand_name'] ?: $c['name'];
      if (!empty($c['brand_subtitle'])) {
        $brandSub    = $c['brand_subtitle'];
        $brandSubSet = true;
      }
      if (!empty($c['brand_color'])) {
        $brandColor = $c['brand_color'];
      }
      if (!empty($c['logo_url'])) {
        $brandLogo = $c['logo_url'];
      }
      if (!empty($c['support_email'])) {
        $brandConfig['support_email'] = $c['support_email'];
      }

      // NEW: override base URL if the company has its own public/embeddable domain
      if (!empty($c['public_base_url'])) {
        $base = rtrim($c['public_base_url'], '/');
      }
    }
  } catch (Throwable $e) {
    // ignore and fallback
  }
}

// If no company branding (or no company_id) and you want a soft fallback to org:
if ($companyId <= 0 && $orgId > 0) {
  try {
    $os = $pdo->prepare("SELECT name FROM organisations WHERE id = ? LIMIT 1");
    $os->execute([$orgId]);
    if ($o = $os->fetch(PDO::FETCH_ASSOC)) {
      // Only if brand isn't already set by company
      if (!$brandSubSet) {
        $brandSub = 'Photo upload for ' . $o['name'];
      }
    }
  } catch (Throwable $e) {
    // ignore
  }
}

// Push resolved brand for all further rendering (including errors below this point)
$brandConfig = [
  'name'          => $brandName,
  'sub'           => $brandSub,
  'color'         => $brandColor,
  'logo_url'      => $brandLogo,
  'support_email' => $brandConfig['support_email'] ?? null,
];
$GLOBALS['brandConfig'] = $brandConfig;
$GLOBALS['base']        = $base;

// ------- Log a request_notes entry for page view (scoped to company) -------

try {
  $ip = client_ip();
  $note = "Page viewed from IP: {$ip}";
  $logStmt = $pdo->prepare("
    INSERT INTO request_notes (request_id, organisation_id, company_id, notes)
    VALUES (?, ?, ?, ?)
  ");
  $logStmt->execute([
    $req['id'],
    $orgId ?: null,
    $companyId ?: null,
    $note
  ]);
} catch (Throwable $e) {
  // don't block UX
}

/** Status + expiry */
$status  = strtolower(trim((string)$req['status']));
$expired = is_request_expired($req['expires_at'] ?? null);

if (($config['env'] ?? 'prod') === 'dev') {
  header('X-MPMS-Status: ' . $status);
  header('X-MPMS-Expires-At: ' . ($req['expires_at'] ?? 'NULL'));
  header('X-MPMS-Org-Id: ' . $orgId);
  header('X-MPMS-Company-Id: ' . $companyId);
}

// Expired?
if ($status === 'expired' || $expired) {
  if ($status !== 'expired') {
    $pdo->prepare("UPDATE requests SET status='expired' WHERE id=?")->execute([$req['id']]);
  }
  render_message(410, 'Link expired', 'This upload link has expired.', 'Please contact your coordinator for a new link.');
}

// Closed?
if ($status === 'closed') {
  render_message(403, 'Request closed', 'This request is closed and can’t accept more uploads.', 'If you still need to add files, please contact your coordinator.');
}

/* ------------------------------------------------------------------
 *  Load template (if assigned)
 *  - expects requests.template_id (nullable)
 *  - uses towlens_templates + towlens_template_steps
 * ------------------------------------------------------------------ */
$template       = null;
$templateSteps  = [];
$templateId     = isset($req['template_id']) ? (int)$req['template_id'] : 0;

if ($templateId > 0) {
    try {
        $ts = $pdo->prepare("SELECT * FROM towlens_templates WHERE id = ? AND is_active = 1");
        $ts->execute([$templateId]);
        $template = $ts->fetch(PDO::FETCH_ASSOC);

        if ($template) {
            $ss = $pdo->prepare("
              SELECT id, template_id, step_order, code, label, is_required, created_at
              FROM towlens_template_steps
              WHERE template_id = ?
              ORDER BY step_order ASC, id ASC
            ");
            $ss->execute([$templateId]);
            $templateSteps = $ss->fetchAll(PDO::FETCH_ASSOC);
        }
    } catch (Throwable $e) {
        if (($config['env'] ?? 'prod') === 'dev') {
            error_log('TowLens template load failed: ' . $e->getMessage());
        }
        $template      = null;
        $templateSteps = [];
    }
}

$hasTemplate = !empty($template) && !empty($templateSteps);

// --- Active: render upload UI ---

$max_each     = (int)$config['max_files_each'];
$max_mb       = (int)$config['max_file_mb'];
$allowed_exts = ['jpg','jpeg','png','heic','heif','webp','gif','mp4'];

$initials = mb_strtoupper(
  mb_substr(preg_replace('/[^A-Za-z]/u', '', $brandName) ?: 'TL', 0, 2)
);
?>
<!doctype html>
<html lang="en" class="h-full">
<head>
<meta charset="utf-8">
<title><?= esc($brandName) ?> — Upload Photos — <?= esc($req['reg_mark']) ?><?= $isDemo ? ' (Demo Mode)' : '' ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<style>
  :root{
    --brand: <?= esc($brandColor) ?>;
    --bg:#f6f7fb; --ink:#0b1220; --muted:#5b6478;
    --card:#ffffff; --ring:#d6d9e2; --dash:#c7cfe0;
  }
  @media (prefers-color-scheme: dark){
    :root{
      --bg:#0b0f1a; --ink:#eef3ff; --muted:#a9b3c7;
      --card:#12192a; --ring:#27314a; --dash:#324064;
    }
  }
  *{box-sizing:border-box} html,body{height:100%}
  body{
    margin:0; font:16px/1.45 system-ui,Segoe UI,Roboto,Arial,Helvetica,sans-serif; color:var(--ink);
    background:
      radial-gradient(1200px 600px at 10% -10%, rgba(15,111,255,.16), transparent 60%),
      radial-gradient(900px 500px at 110% 0%,   rgba(15,111,255,.10), transparent 60%),
      var(--bg);
  }
  .shell{max-width:980px;margin:0 auto;padding:20px}
  .card{
    background:var(--card); border:1px solid var(--ring); border-radius:18px;
    box-shadow:0 12px 30px rgba(15,17,23,.06); overflow:hidden; position:relative;
  }
  .hdr{
    padding:16px 20px;
    background:linear-gradient(180deg, rgba(15,111,255,.10), transparent 65%);
    border-bottom:1px solid var(--ring);
    display:flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:space-between;
  }
  .brand-wrap{display:flex;align-items:center;gap:10px}
  .logo-block{
    width:40px;height:40px;border-radius:12px;background:var(--brand);color:#fff;
    display:grid;place-items:center;font-weight:800;letter-spacing:.5px;
    box-shadow:inset 0 0 0 2px rgba(255,255,255,.25);overflow:hidden;
  }
  .logo-block img{width:100%;height:100%;object-fit:contain;border-radius:12px}
  .brand-title{margin:0;font-size:15px;font-weight:600}
  .brand-sub{margin:0;font-size:12px;color:var(--muted)}
  .title-wrap{display:flex;flex-direction:column;gap:4px;align-items:flex-end}
  .page-title{margin:0;font-size:16px;font-weight:600}
  .regtag{
    display:inline-flex;align-items:center;justify-content:center;
    padding:7px 14px;
    min-width:160px;
    background:#ffeb3b;
    color:#111;
    border:2px solid #111;
    border-radius:6px;
    font-weight:800;
    letter-spacing:2px;
    text-transform:uppercase;
    line-height:1;
    box-shadow:
      inset 0 0 0 2px rgba(255,255,255,.35),
      0 2px 10px rgba(0,0,0,.06);
    font-family: system-ui, Segoe UI, Roboto, Arial, Helvetica, sans-serif;
  }
  .body{padding:18px 20px}
  .grid{display:grid;grid-template-columns:1fr;gap:14px}
  @media(min-width:860px){.grid{grid-template-columns:1fr 1fr}}
  .zone{
    border:2px dashed var(--dash);border-radius:16px;
    padding:12px;min-height:200px;
    display:flex;flex-direction:column;gap:8px;
  }
  .zone.dragover{border-color:var(--brand);box-shadow:0 0 0 4px rgba(15,111,255,.12) inset}
  .zone h3{margin:0 0 2px;font-size:15px}
  .hint{color:var(--muted);font-size:13px}
  .inputs{display:flex;gap:8px;flex-wrap:wrap}
  .btn{
    background:var(--brand);color:#fff;border:0;border-radius:10px;
    padding:8px 13px;cursor:pointer;font-weight:600;font-size:14px;
  }
  .btn.secondary{background:transparent;color:var(--brand);border:1px solid var(--brand)}
  .btn:disabled{opacity:.6;cursor:not-allowed}
  .btn-sm{padding:6px 10px;font-size:13px}
  .chips{display:flex;flex-wrap:wrap;gap:6px}
  .chip{
    border:1px solid var(--ring);background:rgba(15,17,23,.02);
    padding:6px 8px;border-radius:9px;
    display:flex;gap:6px;align-items:center;min-width:0;
  }
  .chip .name{
    font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:200px
  }
  .chip .meta{font-size:11px;color:var(--muted)}
  .chip button{
    border:0;background:transparent;color:#b5470a;cursor:pointer;font-size:11px
  }
  .notes textarea{
    width:100%;min-height:110px;padding:10px 12px;
    border-radius:12px;border:1px solid var(--ring);
    background:var(--card);color:inherit;resize:vertical;font-size:14px;
  }
  .footer{
    display:flex;flex-wrap:wrap;gap:10px;align-items:center;
    justify-content:space-between;margin-top:10px
  }
  .lim{font-size:12px;color:var(--muted)}
  .sending{
    display:none;gap:8px;align-items:center;color:var(--muted);font-size:13px
  }
  .sending.on{display:flex}
  .spinner{
    width:16px;height:16px;border:3px solid var(--ring);
    border-top-color:var(--brand);border-radius:50%;animation:spin 1s linear infinite
  }
  @keyframes spin{to{transform:rotate(360deg)}}
  footer{
    text-align:center;padding:10px;font-size:12px;
    color:var(--muted);border-top:1px solid var(--ring)
  }
  footer a{color:var(--brand);text-decoration:none}
  footer a:hover{text-decoration:underline}
  .demo-badge{
    position:absolute;right:12px;top:12px;
    background:#f8d7da;color:#842029;border:1px solid #f5c2c7;
    border-radius:999px;padding:4px 8px;font-size:11px;
    box-shadow:0 2px 8px rgba(0,0,0,.08)
  }

  /* Checklist (template mode) */
  .checklist{display:flex;flex-direction:column;gap:10px;margin-top:10px}
  .checklist-item{
    border:1px dashed var(--dash);
    border-radius:14px;
    padding:10px 12px;
    display:flex;
    flex-direction:column;
    gap:6px;
  }
  .checklist-head{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
  .step-index{font-size:13px;font-weight:600}
  .step-label{font-size:14px}
  .badge-required{
    font-size:11px;
    border-radius:999px;
    padding:2px 6px;
    background:rgba(215,38,61,.08);
    color:#d7263d;
    border:1px solid rgba(215,38,61,.3);
  }
  .checklist-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
  .status-pill{
    font-size:12px;
    border-radius:999px;
    padding:4px 8px;
    border:1px solid var(--ring);
    color:var(--muted);
  }
  .checklist-item.has-file .status-pill{
    border-color:#0b9564;
    color:#0b9564;
    background:rgba(11,149,100,.06);
  }
</style>
</head>
<body>
  <div class="shell">
    <form
      id="uploadForm"
      class="card"
      action="<?= esc($base) ?>/public/submit"
      method="post"
      enctype="multipart/form-data"
      novalidate
    >
      <?php if ($isDemo): ?><div class="demo-badge">DEMO</div><?php endif; ?>

      <div class="hdr">
        <div class="brand-wrap">
          <div class="logo-block">
            <?php if ($brandLogo): ?>
              <img src="<?= esc($brandLogo) ?>" alt="<?= esc($brandName) ?>">
            <?php else: ?>
              <?= esc($initials) ?>
            <?php endif; ?>
          </div>
          <div>
            <p class="brand-title"><?= esc($brandName) ?></p>
            <p class="brand-sub">
              <?php if ($hasTemplate): ?>
                <?= esc($brandSub) ?> · Checklist: <?= esc($template['name']) ?>
              <?php else: ?>
                <?= esc($brandSub) ?>
              <?php endif; ?>
            </p>
          </div>
        </div>
        <div class="title-wrap">
          <p class="page-title">Upload photos</p>
          <div class="regtag"><?= esc($req['reg_mark']) ?></div>
        </div>
        <input type="hidden" name="token" value="<?= esc($token) ?>">
      </div>

      <?php if (($config['env'] ?? 'prod') === 'dev'): ?>
        <div style="padding:6px 20px 0;font-size:11px;color:#888">
          DEBUG:
          status=<?= esc($status) ?> ·
          expires_at=<?= esc($req['expires_at'] ?? 'NULL') ?> ·
          org_id=<?= (int)$orgId ?> ·
          company_id=<?= (int)$companyId ?> ·
          template_id=<?= (int)$templateId ?>
        </div>
      <?php endif; ?>

      <?php if ($hasTemplate): ?>
        <!-- ======================= TEMPLATE / CHECKLIST MODE ======================= -->
        <div class="body">
          <p class="hint" style="margin-top:0">
            Please follow the checklist below and add one clear photo for each step.
            Items marked <strong>Required</strong> must be completed before you can send.
          </p>

          <section class="checklist">
            <?php foreach ($templateSteps as $step): ?>
              <?php
                $stepId   = (int)$step['id'];
                $order    = (int)$step['step_order'];
                $code     = (string)$step['code'];
                $label    = $step['label'] ?: $code;
                $required = (int)$step['is_required'] === 1;
              ?>
              <div
                class="checklist-item"
                data-step-id="<?= $stepId ?>"
                data-required="<?= $required ? '1' : '0' ?>"
              >
                <div class="checklist-head">
                  <span class="step-index"><?= $order ?>.</span>
                  <span class="step-label"><?= esc($label) ?></span>
                  <?php if ($required): ?>
                    <span class="badge-required">Required</span>
                  <?php endif; ?>
                </div>
                <div class="checklist-actions">
                  <button
                    type="button"
                    class="btn btn-sm js-step-upload"
                    data-input-id="file-step-<?= $stepId ?>"
                  >Capture / upload</button>

                  <input
                    id="file-step-<?= $stepId ?>"
                    class="js-step-input"
                    type="file"
                    name="template_files[<?= $stepId ?>]"
                    accept="image/*,video/mp4,image/heic,image/heif,image/webp"
                    capture="environment"
                    hidden
                  >

                  <span class="status-pill js-step-status">Not captured</span>
                </div>
              </div>
            <?php endforeach; ?>
          </section>

          <section class="notes" style="margin-top:16px">
            <h3 style="margin:0 0 6px">Notes (optional)</h3>
            <textarea
              name="notes"
              maxlength="4000"
              placeholder="Any extra information about the vehicle or damage…"
            ></textarea>
            <p class="hint" style="margin-top:6px">
              Please avoid including sensitive personal information.
            </p>
          </section>

          <div class="footer">
            <div class="lim">
              Max file size <?= $max_mb ?>MB • Types: JPG/JPEG/PNG/HEIC/WEBP/GIF/MP4

            </div>
            <div style="display:flex;gap:10px;align-items:center">
              <div class="sending" id="sending">
                <div class="spinner"></div> Sending your files…
              </div>
              <button id="submitBtn" class="btn" type="submit">Send</button>
            </div>
          </div>

          <p class="hint" style="margin-top:10px">
            Trouble uploading? Send what you can; you can then reply to your contact by email with extra photos.
          </p>
        </div>
      <?php else: ?>
        <!-- ========================= ORIGINAL / NORMAL MODE ======================== -->
        <div class="body">
          <p class="hint" style="margin-top:0">
            Please upload clear photos of the vehicle and surroundings, plus any notes that help our team locate or access it.
          </p>

          <div class="grid">
            <!-- VEHICLE -->
            <section class="zone" id="zone-vehicle" data-kind="vehicle">
              <div>
                <h3>Vehicle photos</h3>
                <p class="hint">
                  Up to <?= $max_each ?> images • Max <?= $max_mb ?>MB each • JPG/JPEG/PNG/HEIC/WEBP/GIF/MP4

                </p>
              </div>
              <div class="inputs">
                <input id="input-vehicle-camera"  type="file"
                       accept="image/*,video/mp4,image/heic,image/heif,image/webp"

                       capture="environment" multiple hidden>
                <input id="input-vehicle-gallery" type="file"
                       accept="image/*,video/mp4,image/heic,image/heif,image/webp"

                       multiple hidden>
                <button type="button" class="btn" data-pick-gallery="vehicle">Upload</button>
                <button type="button" class="btn secondary" data-drophelp="vehicle">
                  Or drag &amp; drop here
                </button>
              </div>
              <div class="chips" id="list-vehicle"></div>
            </section>

            <!-- SCENE -->
            <section class="zone" id="zone-scene" data-kind="scene">
              <div>
                <h3>Scene photos</h3>
                <p class="hint">
                  Up to <?= $max_each ?> images • Max <?= $max_mb ?>MB each • JPG/JPEG/PNG/HEIC/WEBP/GIF
                </p>
              </div>
              <div class="inputs">
                <input id="input-scene-camera"  type="file"
                       accept="image/*,video/mp4,image/heic,image/heif,image/webp"

                       capture="environment" multiple hidden>
                <input id="input-scene-gallery" type="file"
                       accept="image/*,video/mp4,image/heic,image/heif,image/webp"

                       multiple hidden>
                <button type="button" class="btn" data-pick-gallery="scene">Upload</button>
                <button type="button" class="btn secondary" data-drophelp="scene">
                  Or drag &amp; drop here
                </button>
              </div>
              <div class="chips" id="list-scene"></div>
            </section>
          </div>

          <section class="notes" style="margin-top:16px">
            <h3 style="margin:0 0 6px">Notes (optional)</h3>
            <textarea
              name="notes"
              maxlength="4000"
              placeholder="e.g., vehicle tight to a wall near red gate; keys with security…"
            ></textarea>
            <p class="hint" style="margin-top:6px">
              Please avoid including sensitive personal information.
            </p>
          </section>

          <div class="footer">
            <div class="lim" id="limitsText">
              You can still add files. Vehicle: 0/<?= $max_each ?> • Scene: 0/<?= $max_each ?>
            </div>
            <div style="display:flex;gap:10px;align-items:center">
              <div class="sending" id="sending">
                <div class="spinner"></div> Sending your files…
              </div>
              <button id="submitBtn" class="btn" type="submit">Send</button>
            </div>
          </div>

          <p class="hint" style="margin-top:10px">
            Trouble uploading? Send what you can; you can then reply to your contact by email with extra photos.
          </p>
        </div>

        <!-- Real fields posted -->
        <input id="real-vehicle" name="vehicle[]" type="file" multiple hidden>
        <input id="real-scene"   name="scene[]"   type="file" multiple hidden>
      <?php endif; ?>

      <footer>
        Powered by
        <a href="https://mpmg.co.uk/software" target="_blank" rel="noopener">
          Mount Pleasant Motoring Services Ltd
        </a>
      </footer>
    </form>
  </div>

<?php if ($hasTemplate): ?>
<script>
(() => {
  const MAX_MB   = <?= (int)$max_mb ?>;
  const ALLOWED_EXTS = <?= json_encode($allowed_exts) ?>;

  const form      = document.getElementById('uploadForm');
  const submitBtn = document.getElementById('submitBtn');
  const sending   = document.getElementById('sending');

  function extOf(name){
    const m = name.toLowerCase().match(/\.([a-z0-9]+)$/);
    return m ? m[1] : '';
  }

  // Wire buttons -> file inputs
  document.querySelectorAll('.js-step-upload').forEach(btn => {
    btn.addEventListener('click', () => {
      const inputId = btn.dataset.inputId;
      const input = document.getElementById(inputId);
      if (input) input.click();
    });
  });

  // Validate file selection and update status
  document.querySelectorAll('.js-step-input').forEach(input => {
    input.addEventListener('change', () => {
      const item   = input.closest('.checklist-item');
      const status = item ? item.querySelector('.js-step-status') : null;
      const file   = input.files[0] || null;

      if (!file) {
        if (status) status.textContent = 'Not captured';
        if (item) item.classList.remove('has-file');
        return;
      }

      const ext = extOf(file.name);
      if (!ALLOWED_EXTS.includes(ext)) {
        alert(`Unsupported file type: ${file.name}`);
        input.value = '';
        if (status) status.textContent = 'Not captured';
        if (item) item.classList.remove('has-file');
        return;
      }
      if (file.size > MAX_MB * 1024 * 1024) {
        alert(`"${file.name}" is larger than <?= (int)$max_mb ?>MB.`);
        input.value = '';
        if (status) status.textContent = 'Not captured';
        if (item) item.classList.remove('has-file');
        return;
      }

      if (status) status.textContent = 'Captured';
      if (item) item.classList.add('has-file');
    });
  });

  form.addEventListener('submit', e => {
    const items = Array.from(document.querySelectorAll('.checklist-item'));
    const missing = [];
    let anyFile = false;

    items.forEach(item => {
      const required = item.dataset.required === '1';
      const input    = item.querySelector('.js-step-input');
      const labelEl  = item.querySelector('.step-label');
      const label    = labelEl ? labelEl.textContent.trim() : 'Step';

      if (input && input.files && input.files.length > 0) {
        anyFile = true;
      } else if (required) {
        missing.push(label);
      }
    });

    const notes = (form.querySelector('textarea[name="notes"]')?.value || '').trim();

    if (missing.length > 0) {
      e.preventDefault();
      alert('Please add a photo for all required steps:\n\n- ' + missing.join('\n- '));
      return;
    }

    if (!anyFile && notes.length === 0) {
      e.preventDefault();
      alert('Please add at least one photo or some notes before sending.');
      return;
    }

    submitBtn.disabled = true;
    sending.classList.add('on');
  });
})();
</script>
<?php else: ?>
<script>
(() => {
  const MAX_EACH = <?= (int)$max_each ?>;
  const MAX_MB   = <?= (int)$max_mb ?>;
  const ALLOWED_EXTS = <?= json_encode($allowed_exts) ?>;

  const state = {
    vehicle: new DataTransfer(),
    scene:   new DataTransfer()
  };

  const els = {
    vehicle: {
      zone:  document.getElementById('zone-vehicle'),
      inputCam: document.getElementById('input-vehicle-camera'),
      inputGal: document.getElementById('input-vehicle-gallery'),
      list:  document.getElementById('list-vehicle'),
      real:  document.getElementById('real-vehicle')
    },
    scene: {
      zone:  document.getElementById('zone-scene'),
      inputCam: document.getElementById('input-scene-camera'),
      inputGal: document.getElementById('input-scene-gallery'),
      list:  document.getElementById('list-scene'),
      real:  document.getElementById('real-scene')
    },
    limitsText: document.getElementById('limitsText'),
    form:       document.getElementById('uploadForm'),
    submitBtn:  document.getElementById('submitBtn'),
    sending:    document.getElementById('sending')
  };

  function extOf(name){
    const m = name.toLowerCase().match(/\.([a-z0-9]+)$/);
    return m ? m[1] : "";
  }

  function prettyBytes(n){
    if (n < 1024) return n + ' B';
    const u = ['KB','MB','GB'];
    let i = -1;
    do { n /= 1024; i++; } while (n >= 1024 && i < u.length - 1);
    return n.toFixed(n < 10 ? 1 : 0) + ' ' + u[i];
  }

  function updateLimits(){
    const v = state.vehicle.files.length;
    const s = state.scene.files.length;
    els.limitsText.textContent =
      `You can still add files. Vehicle: ${v}/${MAX_EACH} • Scene: ${s}/${MAX_EACH}`;
  }

  function renderList(kind){
    const list = els[kind].list;
    list.innerHTML = '';
    Array.from(state[kind].files).forEach((file, idx) => {
      const chip = document.createElement('div');
      chip.className = 'chip';
      const name = document.createElement('span');
      name.className = 'name';
      name.textContent = file.name;
      const meta = document.createElement('span');
      meta.className = 'meta';
      meta.textContent = prettyBytes(file.size);
      const btn = document.createElement('button');
      btn.type = 'button';
      btn.textContent = 'Remove';
      btn.addEventListener('click', () => removeAt(kind, idx));
      chip.append(name, meta, btn);
      list.appendChild(chip);
    });
    updateLimits();
  }

  function syncReal(kind){
    els[kind].real.files = state[kind].files;
  }

  function addFiles(kind, files){
    const current = state[kind].files.length;
    if (current + files.length > MAX_EACH) {
      alert(`Too many ${kind} files. Max ${MAX_EACH}.`);
      return;
    }
    const dt = state[kind];
    for (const f of files) {
      const ext = extOf(f.name);
      if (!ALLOWED_EXTS.includes(ext)) {
        alert(`Unsupported file type: ${f.name}`);
        continue;
      }
      if (f.size > MAX_MB * 1024 * 1024) {
        alert(`"${f.name}" is larger than ${MAX_MB}MB.`);
        continue;
      }
      dt.items.add(f);
    }
    renderList(kind);
    syncReal(kind);
  }

  function removeAt(kind, idx){
    const dt = new DataTransfer();
    Array.from(state[kind].files).forEach((f, i) => {
      if (i !== idx) dt.items.add(f);
    });
    state[kind] = dt;
    renderList(kind);
    syncReal(kind);
  }

  function wireInput(kind, inputEl){
    if (!inputEl) return;
    inputEl.addEventListener('change', e => {
      if (e.target.files && e.target.files.length) {
        addFiles(kind, e.target.files);
      }
      e.target.value = '';
    });
  }

  wireInput('vehicle', els.vehicle.inputCam);
  wireInput('vehicle', els.vehicle.inputGal);
  wireInput('scene',   els.scene.inputCam);
  wireInput('scene',   els.scene.inputGal);

  document.querySelectorAll('[data-pick-gallery]').forEach(btn => {
    const kind = btn.getAttribute('data-pick-gallery');
    btn.addEventListener('click', () => {
      els[kind].inputGal.click();
    });
  });

  ['vehicle','scene'].forEach(kind => {
    const z = els[kind].zone;
    ['dragenter','dragover'].forEach(evt => z.addEventListener(evt, e => {
      e.preventDefault();
      z.classList.add('dragover');
    }));
    ['dragleave','drop'].forEach(evt => z.addEventListener(evt, e => {
      e.preventDefault();
      z.classList.remove('dragover');
    }));
    z.addEventListener('drop', e => {
      const f = e.dataTransfer.files;
      if (f && f.length) addFiles(kind, f);
    });
  });

  els.form.addEventListener('submit', e => {
    const totalFiles = state.vehicle.files.length + state.scene.files.length;
    const notes = (els.form.querySelector('textarea[name="notes"]')?.value || '').trim();

    if (totalFiles === 0 && notes.length === 0) {
      e.preventDefault();
      alert('Please add at least one photo or some notes before sending.');
      return;
    }
    els.submitBtn.disabled = true;
    els.sending.classList.add('on');
  });

  updateLimits();
})();
</script>
<?php endif; ?>

</body>
</html>
