<?php
// /admin/forgot.php
// Multi-tenant, subdomain/slug-aware:
// If an email exists in multiple (org,company), send ONE mail with distinct reset links.

session_start();

$config = require __DIR__ . '/../lib/config.php';
require __DIR__ . '/../lib/db.php';
require_once __DIR__ . '/../lib/mailer.php';

$base         = rtrim($config['base_url'] ?? '', '/');
$isDemo       = !empty($config['demo_mode']);
$authCfg      = $config['auth'] ?? [];
$expiryMin    = (int)($authCfg['reset_expiry_minutes'] ?? 30);
$allowEntraPw = (bool)($authCfg['allow_fallback_for_entra'] ?? false);

$orgFromHost = null;
$orgLogoUrl  = '';
$pageTitle   = 'Forgot password — Admin';

if ($pdo instanceof PDO) {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // Detect organisation from subdomain: {slug}.towlens.net, {slug}.yourdomain, etc.
    $host = $_SERVER['HTTP_HOST'] ?? '';
    $hostSlug = '';

    if ($host) {
        $parts = explode('.', $host);
        if (count($parts) >= 3) {
            // first label as org slug: client.towlens.net -> client
            $hostSlug = strtolower($parts[0]);
        }
    }

    if ($hostSlug !== '') {
        $stmt = $pdo->prepare("
          SELECT id, name, slug, logo_url
          FROM organisations
          WHERE slug = ?
          LIMIT 1
        ");
        $stmt->execute([$hostSlug]);
        $orgFromHost = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;

        if ($orgFromHost) {
            $orgLogoUrl = trim((string)($orgFromHost['logo_url'] ?? ''));
            $pageTitle  = $orgFromHost['name'] . ' — Forgot password';
        }
    }

    /* Ensure/upgrade password_resets */
    $pdo->exec("
      CREATE TABLE IF NOT EXISTS password_resets (
        id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
        user_id INT UNSIGNED NOT NULL,
        organisation_id INT UNSIGNED DEFAULT NULL,
        company_id INT UNSIGNED DEFAULT NULL,
        token_hash CHAR(64) NOT NULL,
        expires_at DATETIME NOT NULL,
        used_at DATETIME DEFAULT NULL,
        created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        INDEX ix_token_hash (token_hash),
        INDEX ix_pw_org (organisation_id),
        INDEX ix_pw_company (company_id),
        CONSTRAINT fk_pw_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    ");

    try {
        $pdo->exec("ALTER TABLE password_resets
          ADD CONSTRAINT fk_pwreset_org FOREIGN KEY (organisation_id) REFERENCES organisations(id) ON DELETE RESTRICT
        ");
    } catch (Throwable $e) {
        // ignore if already exists
    }
    try {
        $pdo->exec("ALTER TABLE password_resets
          ADD CONSTRAINT fk_pwreset_company FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE RESTRICT
        ");
    } catch (Throwable $e) {
        // ignore if already exists
    }
}

function csrf_token(): string {
    if (empty($_SESSION['csrf_forgot'])) {
        $_SESSION['csrf_forgot'] = bin2hex(random_bytes(16));
    }
    return $_SESSION['csrf_forgot'];
}
function csrf_ok(): bool {
    return !empty($_POST['csrf']) && hash_equals($_SESSION['csrf_forgot'] ?? '', $_POST['csrf']);
}

$notice = '';
$error  = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!csrf_ok()) {
        $error = 'Your session expired. Please try again.';
    } else {
        $email = trim(strtolower($_POST['email'] ?? ''));
        $notice = 'If that email exists, a reset link has been sent. Please check your inbox.';

        if ($email !== '') {
            try {
                // --- DEBUG/LOG helper (uses same dir as mail log) ---
                $logFile = __DIR__ . '/../logs/mail.log';
                @mkdir(dirname($logFile), 0775, true);
                $log = static function (string $msg) use ($logFile) {
                    @file_put_contents($logFile, '[' . date('c') . "] FORGOT $msg\n", FILE_APPEND);
                };

                // Fetch all matching accounts (email may exist in multiple companies)
                $stmt = $pdo->prepare("
                  SELECT u.id, u.email, u.provider, u.organisation_id, u.company_id,
                         o.name AS org_name, c.name AS company_name
                  FROM users u
                  JOIN organisations o ON o.id = u.organisation_id
                  JOIN companies      c ON c.id = u.company_id
                  WHERE LOWER(u.email)=LOWER(?)
                ");
                $stmt->execute([$email]);
                $users = $stmt->fetchAll(PDO::FETCH_ASSOC);

                if (!$users) {
                    $log("No users found for email={$email}");
                } else {
                    $log("Found " . count($users) . " user(s) for email={$email}");
                }

                $links = [];
                if ($users) {
                    $expiresAt = (new DateTimeImmutable("+{$expiryMin} minutes"))->format('Y-m-d H:i:s');

                    foreach ($users as $u) {
                        // Treat NULL/'' as local (common case)
                        $provRaw = $u['provider'] ?? 'local';
                        $prov = strtolower($provRaw === '' ? 'local' : $provRaw);

                        if (!($prov === 'local' || ($prov === 'entra' && $allowEntraPw))) {
                            $log("Skip user_id={$u['id']} provider={$provRaw}");
                            continue;
                        }

                        $token = bin2hex(random_bytes(32));
                        $hash  = hash('sha256', $token);

                        $orgIdRow = isset($u['organisation_id']) && $u['organisation_id'] !== ''
                            ? (int)$u['organisation_id']
                            : null;
                        $cmpIdRow = isset($u['company_id']) && $u['company_id'] !== ''
                            ? (int)$u['company_id']
                            : null;

                        $ins = $pdo->prepare("
                          INSERT INTO password_resets
                            (user_id, organisation_id, company_id, token_hash, expires_at)
                          VALUES (?,?,?,?,?)
                        ");
                        $ins->execute([
                            (int)$u['id'],
                            $orgIdRow,
                            $cmpIdRow,
                            $hash,
                            $expiresAt,
                        ]);

                        $log("Inserted password_resets for user_id={$u['id']} org_id={$orgIdRow} company_id={$cmpIdRow}");

                        $links[] = [
                            'label'  => $u['org_name'] . ' — ' . $u['company_name'],
                            'href'   => $base . '/admin/reset.php?token=' . urlencode($token),
                            'org_id' => $orgIdRow,
                        ];
                    }
                }

                if (!empty($links)) {
                    // Build email HTML
                    if (count($links) === 1) {
                        $html = '<p>Hello,</p>'
                              . '<p>We received a request to reset your password. Click the button below to set a new password. '
                              . 'This link expires in ' . (int)$expiryMin . ' minutes.</p>'
                              . '<p><a href="' . htmlspecialchars($links[0]['href']) . '" '
                              . 'style="display:inline-block;padding:10px 14px;border-radius:4px;'
                              . 'background:#2f6db2;color:#fff;text-decoration:none;">Reset Password</a></p>'
                              . '<p>If you did not request this, you can safely ignore this email.</p>';
                    } else {
                        $html = '<p>Hello,</p>'
                              . '<p>We found more than one account using this email. Choose the organisation/company to reset:</p><ul>';
                        foreach ($links as $lnk) {
                            $html .= '<li><a href="' . htmlspecialchars($lnk['href']) . '">'
                                   . htmlspecialchars($lnk['label']) . '</a></li>';
                        }
                        $html .= '</ul><p>Each link expires in ' . (int)$expiryMin . ' minutes.</p>';
                    }

                    // Pick which org's SMTP to use:
                    // 1) org from subdomain if present
                    // 2) else org_id of the first link
                    $mailOrgId = null;
                    if (!empty($orgFromHost['id'])) {
                        $mailOrgId = (int)$orgFromHost['id'];
                    } elseif (!empty($links[0]['org_id'])) {
                        $mailOrgId = (int)$links[0]['org_id'];
                    }

                    $ok = false;
                    $errSend = null;

                    if ($mailOrgId) {
                        [$ok, $errSend] = mpms_mail_send_for_org($pdo, $mailOrgId, $email, 'Reset your password', $html, null, $config);
                        $log("mpms_mail_send_for_org(org_id={$mailOrgId}) ok=" . ($ok ? '1' : '0') . " err=" . ($errSend ?? ''));
                    } else {
                        [$ok, $errSend] = mpms_mail_send($config, $email, 'Reset your password', $html);
                        $log("mpms_mail_send(global) ok=" . ($ok ? '1' : '0') . " err=" . ($errSend ?? ''));
                    }

                    if (!$ok && $errSend) {
                        error_log('Reset email failed: ' . $errSend);
                    }
                } else {
                    $log("No eligible links generated for email={$email} (no matching users or all skipped).");
                }
            } catch (Throwable $e) {
                error_log('Forgot password error: ' . $e->getMessage());
                $error = 'Something went wrong while processing your request. Please try again later.';
                $notice = '';
            }
        }
    }
}

?>
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title><?= htmlspecialchars($pageTitle) ?><?= $isDemo ? ' (Demo Mode)' : '' ?></title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    /* (styles unchanged) */
    :root{
      --bg:#e5e9f0;
      --bg-accent:#f3f6fb;
      --win:#ffffff;
      --ink:#1f2933;
      --muted:#6b7280;
      --line:#cfd6de;
      --brand:#2f6db2;
      --brand-soft:#e0ecfb;
      --danger-bg:#fae7e7;
      --danger-border:#e3b1b1;
      --danger-text:#7f2020;
      --success-bg:#e6f4ea;
      --success-border:#b7e1c0;
      --success-text:#1e6b35;
      --radius:6px;
      --shadow-soft:0 6px 14px rgba(15,23,42,.08);
      --hdr:linear-gradient(#f9fafb,#e8edf3);
    }
    *{box-sizing:border-box;margin:0;padding:0}
    html,body{height:100%}
    body{
      margin:0;
      font:13px/1.45 "Segoe UI",Tahoma,Arial,sans-serif;
      color:var(--ink);
      background:
        radial-gradient(circle at top left,rgba(47,109,178,0.12),transparent),
        radial-gradient(circle at bottom right,rgba(148,163,253,0.1),transparent),
        var(--bg);
      -webkit-user-select:none;
      -moz-user-select:none;
      -ms-user-select:none;
      user-select:none;
    }
    .shell{
      min-height:100vh;
      display:flex;
      align-items:center;
      justify-content:center;
      padding:24px;
    }
    .window{
      width:min(720px,92vw);
      background:var(--win);
      border:1px solid var(--line);
      border-radius:var(--radius);
      box-shadow:var(--shadow-soft);
      overflow:hidden;
    }
    .ribbon{
      background:var(--hdr);
      border-bottom:1px solid var(--line);
      padding:10px 16px;
      display:flex;
      align-items:center;
      justify-content:space-between;
      gap:12px;
    }
    .ribbon-left{
      display:flex;
      align-items:center;
      gap:10px;
    }
    .org-logo{
      height:56px;
      max-width:220px;
      object-fit:contain;
      display:block;
      -webkit-user-drag:none;
      user-select:none;
      pointer-events:none;
    }
    @media (max-width:480px){
      .org-logo{
        height:42px;
        max-width:180px;
      }
    }
    .ribbon-icon{
      width:16px;
      height:16px;
      border-radius:3px;
      background:linear-gradient(145deg,var(--brand),#4f8ad1);
      box-shadow:0 1px 2px rgba(0,0,0,.18) inset;
      position:relative;
    }
    .ribbon-icon::before,
    .ribbon-icon::after{
      content:"";
      position:absolute;
      inset:4px 3px;
      border-radius:2px;
      border:1px solid rgba(255,255,255,.7);
    }
    .ribbon-title{
      display:flex;
      flex-direction:column;
    }
    .ribbon-title h1{
      font-size:16px;
      font-weight:600;
      margin:0;
      color:#111827;
    }
    .ribbon-sub{
      font-size:11px;
      color:var(--muted);
    }
    .chip{
      background:#eff6ff;
      border:1px solid #bfdbfe;
      color:#1d4ed8;
      border-radius:999px;
      padding:2px 9px;
      font-size:10px;
      font-weight:600;
      text-transform:uppercase;
      letter-spacing:.06em;
    }
    .body{
      padding:16px 18px 18px;
    }
    .muted{
      color:var(--muted);
      margin-bottom:8px;
    }
    .alert{
      padding:9px 10px;
      border-radius:4px;
      background:var(--danger-bg);
      border:1px solid var(--danger-border);
      color:var(--danger-text);
      margin:0 0 8px;
      font-size:12px;
    }
    .note{
      padding:9px 10px;
      border-radius:4px;
      background:var(--success-bg);
      border:1px solid var(--success-border);
      color:var(--success-text);
      margin:0 0 8px;
      font-size:12px;
    }
    .stack{
      display:flex;
      flex-direction:column;
      gap:4px;
      margin:8px 0 6px;
    }
    label{
      font-size:11px;
      color:var(--muted);
      display:block;
    }
    input[type=email]{
      padding:8px 9px;
      border:1px solid #cfd6de;
      border-radius:4px;
      width:100%;
      font-size:13px;
      background:#f9fafb;
      transition:border-color .18s,box-shadow .18s,background-color .18s;
      -webkit-user-select:text;
      -moz-user-select:text;
      -ms-user-select:text;
      user-select:text;
    }
    input[type=email]:focus{
      outline:none;
      border-color:var(--brand);
      background:#ffffff;
      box-shadow:0 0 0 1px var(--brand-soft),0 0 0 3px rgba(47,109,178,0.14);
    }
    .btn{
      appearance:none;
      border:1px solid #bfc8d2;
      background:linear-gradient(#f9fafb,#e6ecf2);
      padding:8px 12px;
      border-radius:4px;
      cursor:pointer;
      font-weight:600;
      font-size:13px;
      display:inline-flex;
      align-items:center;
      justify-content:center;
      gap:6px;
      transition:all .16s ease-out;
      -webkit-user-select:none;
      -moz-user-select:none;
      -ms-user-select:none;
      user-select:none;
      text-decoration:none;
      color:var(--ink);
    }
    .btn:hover{
      background:linear-gradient(#ffffff,#e2e8f0);
      box-shadow:0 1px 3px rgba(15,23,42,.12);
    }
    .btn:active{
      transform:translateY(1px);
      box-shadow:none;
    }
    .btn.primary{
      border-color:#2a5f9c;
      color:#ffffff;
      background:linear-gradient(#3b79c1,#255b94);
      box-shadow:0 2px 4px rgba(37,91,148,.35);
    }
    .btn.primary:hover{
      background:linear-gradient(#4b82c7,#24558b);
    }
    .actions{
      display:flex;
      flex-wrap:wrap;
      gap:8px;
      margin-top:8px;
    }
    .meta{
      margin-top:8px;
      font-size:10px;
      color:var(--muted);
    }
    @media (max-width:480px){
      .body{padding:14px 12px 14px}
      .ribbon{padding:8px 10px}
    }
    button, input, select, textarea, a{
      -webkit-user-select:auto;
      -moz-user-select:auto;
      -ms-user-select:auto;
      user-select:auto;
    }
  </style>
</head>
<body>
  <div class="shell">
    <main class="window">
      <div class="ribbon">
        <div class="ribbon-left">
          <?php if ($orgLogoUrl): ?>
            <img src="<?= htmlspecialchars($orgLogoUrl) ?>"
                 alt="<?= htmlspecialchars($orgFromHost['name'] ?? 'Logo') ?>"
                 class="org-logo"
                 draggable="false">
          <?php else: ?>
            <div class="ribbon-icon" aria-hidden="true"></div>
          <?php endif; ?>
          <div class="ribbon-title">
            <h1><?= htmlspecialchars($orgFromHost['name'] ?? 'Forgot password') ?></h1>
            <div class="ribbon-sub">Request a secure reset link</div>
          </div>
        </div>
        <div class="chip">ADMIN PORTAL</div>
      </div>

      <div class="body">
        <p class="muted">
          Enter your email address and, if it matches an account, we’ll email a reset link.
          For shared emails, you’ll receive one link per organisation/company.
        </p>

        <?php if (!empty($error)): ?>
          <div class="alert"><?= htmlspecialchars($error) ?></div>
        <?php endif; ?>

        <?php if (!empty($notice)): ?>
          <div class="note"><?= htmlspecialchars($notice) ?></div>
        <?php endif; ?>

        <form method="post" action="" autocomplete="off" novalidate>
          <input type="hidden" name="csrf" value="<?= htmlspecialchars(csrf_token()) ?>">

          <div class="stack">
            <label for="email">Work email</label>
            <input type="email" id="email" name="email" placeholder="you@company.com" required autocomplete="email">
          </div>

          <div class="actions">
            <button class="btn primary" type="submit">
              <span>Send reset link</span>
            </button>
            <button class="btn" type="button" data-href="<?= htmlspecialchars($base) ?>/admin/login.php">
              <span>Back to sign in</span>
            </button>
          </div>

          <div class="meta">
            Links typically expire in <?= (int)$expiryMin ?> minutes for security.
            <?php if ($isDemo): ?>
              <br>Demo mode: emails may be simulated only.
            <?php endif; ?>
          </div>
        </form>
      </div>
    </main>
  </div>

  <script>
    // JS navigation for buttons so URL isn't shown on hover
    document.addEventListener('click', function(e){
      var btn = e.target.closest('button[data-href]');
      if (!btn) return;
      e.preventDefault();
      var url = btn.getAttribute('data-href');
      if (url) window.location.assign(url);
    });

    // Block right-click
    window.addEventListener('contextmenu', function(e){
      e.preventDefault();
    }, {capture:true});

    // Prevent text selection drag outside interactive elements
    window.addEventListener('mousedown', function(e){
      var t = e.target;
      if (
        t.tagName === 'INPUT' ||
        t.tagName === 'BUTTON' ||
        t.tagName === 'SELECT' ||
        t.tagName === 'TEXTAREA' ||
        t.tagName === 'A'
      ) {
        return;
      }
      if (window.getSelection) {
        var sel = window.getSelection();
        if (sel && sel.removeAllRanges) sel.removeAllRanges();
      }
    });
  </script>
</body>
</html>