<?php

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

use KeyLair\Auth;
use KeyLair\Csrf;
use KeyLair\Database;
use KeyLair\Helpers;
use KeyLair\Encryption;
use KeyLair\AuditLog;
use KeyLair\I18n;
use KeyLair\Settings;
use KeyLair\TwoFactor\TwoFactorManager;

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

$flash = null;
$pendingSetup = null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['form_action'] ?? '';

    // Deliberately exempt from requireOwnAccountEditAccess() below -- every
    // role except master_admin and demo can delete itself. Demo can't touch
    // its own account at all (see Auth::canEditOwnAccount()), including
    // deleting it -- a demo login is a stable fixture an admin hands out and
    // reclaims, not something the account itself should be able to remove;
    // only an admin/master admin deleting it from system_users.php can.
    if ($action === 'delete_own_account') {
        Csrf::requireValid();
        if ($admin['role'] === 'master_admin' || $admin['role'] === 'demo') {
            http_response_code(403);
            die('This account cannot self-delete.');
        }
        $password = $_POST['confirm_password'] ?? '';
        if (!password_verify($password, $admin['password_hash'])) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.password_incorrect')];
        } else {
            AuditLog::log($admin['id'], 'account_self_deleted', $admin['username']);
            $pdo->prepare('DELETE FROM admin_users WHERE id = :id')->execute(['id' => $admin['id']]);
            // Not Auth::logout() -- it would log a 'logout' audit entry
            // against this admin_user_id, which now violates the audit_log
            // FK since the row was just deleted. Clear the session directly.
            $_SESSION = [];
            session_regenerate_id(true);
            Helpers::redirect('login.php');
        }
    } elseif ($action === 'update_theme') {
        // Also exempt: a personal backend theme is a cosmetic display
        // preference, not a "login detail" -- there's no reason a demo
        // account (there just to click around and see the product) can't
        // pick Light or Steam like anyone else.
        Csrf::requireValid();
        $theme = $_POST['theme'] ?? '';
        if (!in_array($theme, Settings::BACKEND_THEMES, true)) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.theme_unknown')];
        } else {
            $pdo->prepare('UPDATE admin_users SET theme=:theme WHERE id=:id')
                ->execute(['theme' => $theme, 'id' => $admin['id']]);
            AuditLog::log($admin['id'], 'backend_theme_changed', $theme);
            $flash = ['type' => 'success', 'message' => I18n::t('account.flash.theme_updated')];
            $admin['theme'] = $theme;
        }
    } elseif ($action === 'update_language') {
        // Same cosmetic-preference exemption as update_theme above.
        Csrf::requireValid();
        $language = $_POST['language'] ?? '';
        if (!isset(I18n::AVAILABLE[$language])) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.language_unknown')];
        } else {
            $pdo->prepare('UPDATE admin_users SET language=:language WHERE id=:id')
                ->execute(['language' => $language, 'id' => $admin['id']]);
            AuditLog::log($admin['id'], 'backend_language_changed', $language);
            $admin['language'] = $language;
            I18n::setLocale($language);
            $flash = ['type' => 'success', 'message' => I18n::t('account.flash.language_updated')];
        }
    } else {

    Auth::requireOwnAccountEditAccess();
    Csrf::requireValid();

    if ($action === 'update_profile') {
        $username = trim($_POST['username'] ?? '');
        $email = trim($_POST['email'] ?? '');

        if (strlen($username) < 3 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.invalid_profile')];
        } else {
            $check = $pdo->prepare('SELECT id FROM admin_users WHERE (username = :u OR email = :e) AND id != :id');
            $check->execute(['u' => $username, 'e' => $email, 'id' => $admin['id']]);
            if ($check->fetch()) {
                $flash = ['type' => 'error', 'message' => I18n::t('account.flash.username_email_taken')];
            } else {
                $pdo->prepare('UPDATE admin_users SET username=:u, email=:e WHERE id=:id')
                    ->execute(['u' => $username, 'e' => $email, 'id' => $admin['id']]);
                AuditLog::log($admin['id'], 'profile_updated', null);
                $flash = ['type' => 'success', 'message' => I18n::t('account.flash.profile_updated')];
                $admin['username'] = $username;
                $admin['email'] = $email;
            }
        }
    } elseif ($action === 'update_password') {
        $current = $_POST['current_password'] ?? '';
        $new = $_POST['new_password'] ?? '';
        $confirm = $_POST['new_password_confirm'] ?? '';

        if (!password_verify($current, $admin['password_hash'])) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.current_password_incorrect')];
        } elseif (strlen($new) < 10) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.password_too_short')];
        } elseif ($new !== $confirm) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.passwords_dont_match')];
        } else {
            $pdo->prepare('UPDATE admin_users SET password_hash=:p WHERE id=:id')
                ->execute(['p' => password_hash($new, PASSWORD_DEFAULT), 'id' => $admin['id']]);
            AuditLog::log($admin['id'], 'password_changed', null);
            $flash = ['type' => 'success', 'message' => I18n::t('account.flash.password_updated')];
        }
    } elseif ($action === 'start_2fa_setup') {
        $provider = TwoFactorManager::get('totp');
        $setup = $provider->generateSetup($admin['username']);

        $pdo->prepare('DELETE FROM admin_two_factor_pending WHERE admin_user_id = :id')->execute(['id' => $admin['id']]);
        $pdo->prepare(
            'INSERT INTO admin_two_factor_pending (admin_user_id, method, secret, created_at) VALUES (:id, "totp", :secret, NOW())'
        )->execute(['id' => $admin['id'], 'secret' => $setup['secret']]);

        $pendingSetup = $setup;
    } elseif ($action === 'confirm_2fa_setup') {
        $code = trim($_POST['code'] ?? '');
        $stmt = $pdo->prepare('SELECT * FROM admin_two_factor_pending WHERE admin_user_id = :id');
        $stmt->execute(['id' => $admin['id']]);
        $pending = $stmt->fetch();

        if (!$pending) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.no_pending_setup')];
        } else {
            $provider = TwoFactorManager::get($pending['method']);
            if ($provider->verifyCode($pending['secret'], $code)) {
                $pdo->prepare(
                    'UPDATE admin_users SET two_factor_method=:m, two_factor_secret=:s, two_factor_enabled_at=NOW(), two_factor_disabled_at=NULL WHERE id=:id'
                )->execute(['m' => $pending['method'], 's' => Encryption::encrypt($pending['secret']), 'id' => $admin['id']]);
                $pdo->prepare('DELETE FROM admin_two_factor_pending WHERE admin_user_id = :id')->execute(['id' => $admin['id']]);
                AuditLog::log($admin['id'], 'two_factor_enabled', 'totp');
                $flash = ['type' => 'success', 'message' => I18n::t('account.flash.2fa_enabled')];
                $admin['two_factor_method'] = 'totp';
                unset($_SESSION['must_setup_2fa']);
            } else {
                $flash = ['type' => 'error', 'message' => I18n::t('account.flash.code_mismatch')];
                $stmt2 = $pdo->prepare('SELECT * FROM admin_two_factor_pending WHERE admin_user_id = :id');
                $stmt2->execute(['id' => $admin['id']]);
                $pending = $stmt2->fetch();
                if ($pending) {
                    $pendingSetup = [
                        'secret' => $pending['secret'],
                        'setup_data' => $provider->buildSetupData($pending['secret'], $admin['username']),
                    ];
                }
            }
        }
    } elseif ($action === 'disable_2fa') {
        $password = $_POST['confirm_password'] ?? '';
        if (!password_verify($password, $admin['password_hash'])) {
            $flash = ['type' => 'error', 'message' => I18n::t('account.flash.password_incorrect')];
        } else {
            $pdo->prepare('UPDATE admin_users SET two_factor_method="none", two_factor_secret=NULL, two_factor_enabled_at=NULL, two_factor_disabled_at=NULL WHERE id=:id')
                ->execute(['id' => $admin['id']]);
            AuditLog::log($admin['id'], 'two_factor_disabled', null);
            $flash = ['type' => 'success', 'message' => I18n::t('account.flash.2fa_disabled')];
            $admin['two_factor_method'] = 'none';
        }
    }

    } // end delete_own_account / else
}

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

<?php if (!empty($_SESSION['must_setup_2fa'])): ?>
  <div class="form-section" style="border-color:var(--key-gold); margin-bottom:16px;">
    <p style="color:var(--key-gold); font-size:13px; margin:0;"><?= Helpers::e(I18n::t('account.2fa_required_notice')) ?></p>
  </div>
<?php endif; ?>

<?php if ($flash): ?>
  <div class="form-section" style="border-color:<?= $flash['type'] === 'success' ? 'var(--signal-dim)' : 'var(--danger)' ?>; margin-bottom:16px;">
    <p style="color:<?= $flash['type'] === 'success' ? 'var(--signal)' : 'var(--danger)' ?>; font-size:13px; margin:0;"><?= Helpers::e($flash['message']) ?></p>
  </div>
<?php endif; ?>

<div class="form-shell">

<?php if (!Auth::canEditOwnAccount()): ?>
  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('account.profile_title')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('account.profile_demo_hint')) ?></p>
    <div class="field-row">
      <div class="field"><label><?= Helpers::e(I18n::t('account.username')) ?></label><p style="font-size:13.5px; margin:0;"><?= Helpers::e($admin['username']) ?></p></div>
    </div>
  </div>
<?php else: ?>
  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('account.profile_title')) ?></p>
    <form method="post">
      <?= Csrf::field() ?>
      <input type="hidden" name="form_action" value="update_profile">
      <div class="field-row">
        <div class="field"><label><?= Helpers::e(I18n::t('account.username')) ?></label><input type="text" name="username" value="<?= Helpers::e($admin['username']) ?>" required></div>
        <div class="field"><label><?= Helpers::e(I18n::t('account.email')) ?></label><input type="email" name="email" value="<?= Helpers::e($admin['email']) ?>" required></div>
      </div>
      <div class="form-actions" style="padding-bottom:0;"><button type="submit" class="btn btn-primary"><?= Helpers::e(I18n::t('account.save_profile')) ?></button></div>
    </form>
  </div>
<?php endif; ?>

  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('account.theme_title')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('account.theme_hint')) ?></p>
    <div style="display:flex; gap:10px; flex-wrap:wrap;">
      <?php $myTheme = $admin['theme'] ?? 'default'; if (!in_array($myTheme, Settings::BACKEND_THEMES, true)) { $myTheme = 'default'; } ?>
      <?php foreach (['default' => 'account.theme_default', 'light' => 'account.theme_light', 'steam' => 'account.theme_steam'] as $themeKey => $themeLabelKey): ?>
        <form method="post" class="theme-row-form" style="margin:0;">
          <?= Csrf::field() ?>
          <input type="hidden" name="form_action" value="update_theme">
          <input type="hidden" name="theme" value="<?= $themeKey ?>">
          <button type="submit" class="btn theme-select-btn <?= $myTheme === $themeKey ? 'btn-primary' : 'btn-ghost' ?>" <?= $myTheme === $themeKey ? 'disabled' : '' ?>><?= Helpers::e(I18n::t($themeLabelKey)) ?></button>
        </form>
      <?php endforeach; ?>
    </div>
  </div>

  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('account.language_title')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('account.language_hint')) ?></p>
    <div style="display:flex; gap:10px; flex-wrap:wrap;">
      <?php $myLanguage = $admin['language'] ?? I18n::DEFAULT_LOCALE; if (!isset(I18n::AVAILABLE[$myLanguage])) { $myLanguage = I18n::DEFAULT_LOCALE; } ?>
      <?php foreach (I18n::AVAILABLE as $langCode => $langAutonym): ?>
        <?php
          // Steam's convention: autonym first, translated name below it
          // (e.g. on a German UI, "Français" + "Französisch") -- readable
          // to the current viewer, but the autonym alone still lets
          // someone who can't read the current language spot their own.
          // Shown for every button, including the active one (even where
          // it repeats, e.g. "Deutsch" / "Deutsch"), so every button in
          // the row is the same two-line height.
          $langTranslated = I18n::t('lang.' . $langCode);
        ?>
        <form method="post" class="theme-row-form" style="margin:0;">
          <?= Csrf::field() ?>
          <input type="hidden" name="form_action" value="update_language">
          <input type="hidden" name="language" value="<?= Helpers::e($langCode) ?>">
          <button type="submit" class="btn theme-select-btn lang-select-btn <?= $myLanguage === $langCode ? 'btn-primary' : 'btn-ghost' ?>" <?= $myLanguage === $langCode ? 'disabled' : '' ?>>
            <span><?= Helpers::e($langAutonym) ?></span>
            <span class="lang-select-sub"><?= Helpers::e($langTranslated) ?></span>
          </button>
        </form>
      <?php endforeach; ?>
    </div>
  </div>
  <style>
    /* Shared by the Theme and Language button rows above (both carry
       .theme-select-btn) so every option -- "Standard" included -- lines
       up to the same minimum width. */
    .theme-select-btn{min-width:120px; box-sizing:border-box;}
    .lang-select-btn{flex-direction:column; gap:1px; padding:8px 14px; line-height:1.25;}
    .lang-select-btn .lang-select-sub{font-size:10.5px; font-weight:500; opacity:0.65;}
  </style>

<?php if (Auth::canEditOwnAccount()): ?>
  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('account.password_title')) ?></p>
    <form method="post">
      <?= Csrf::field() ?>
      <input type="hidden" name="form_action" value="update_password">
      <div class="field"><label><?= Helpers::e(I18n::t('account.current_password')) ?></label><input type="password" name="current_password" required></div>
      <div class="field-row">
        <div class="field"><label><?= Helpers::e(I18n::t('account.new_password')) ?></label><input type="password" name="new_password" minlength="10" required></div>
        <div class="field"><label><?= Helpers::e(I18n::t('account.confirm_new_password')) ?></label><input type="password" name="new_password_confirm" minlength="10" required></div>
      </div>
      <div class="form-actions" style="padding-bottom:0;"><button type="submit" class="btn btn-primary"><?= Helpers::e(I18n::t('account.update_password')) ?></button></div>
    </form>
  </div>

  <div class="form-section">
    <p class="form-section-title"><?= Helpers::e(I18n::t('account.2fa_title')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('account.2fa_hint')) ?></p>

    <?php
      $twoFactorMethod = $admin['two_factor_method'] ?? 'none';
      // An admin can suspend another account's 2FA from the Users page
      // without clearing what it had configured (see Auth::twoFactorActive())
      // -- the owner should see that distinctly from either "enabled" or
      // "never set up", since their path forward (set up fresh) is the same
      // as never having had it, but the reason is different.
      $twoFactorSuspended = $twoFactorMethod !== 'none' && !empty($admin['two_factor_disabled_at']);
    ?>
    <?php if ($twoFactorMethod !== 'none' && !$twoFactorSuspended): ?>
      <p style="color:var(--signal); font-size:13px; margin:0 0 14px;">✓ <?= Helpers::e(I18n::t('account.2fa_enabled_via')) ?> <?= Helpers::e(TwoFactorManager::available()[$twoFactorMethod] ?? $twoFactorMethod) ?></p>
      <form method="post" onsubmit="return confirm('Disable two-factor authentication?');">
        <?= Csrf::field() ?>
        <input type="hidden" name="form_action" value="disable_2fa">
        <div class="field"><label><?= Helpers::e(I18n::t('account.2fa_confirm_password_disable')) ?></label><input type="password" name="confirm_password" required></div>
        <div class="form-actions" style="padding-bottom:0;"><button type="submit" class="btn btn-ghost" style="color:var(--danger);"><?= Helpers::e(I18n::t('account.2fa_disable')) ?></button></div>
      </form>

    <?php elseif ($pendingSetup): ?>
      <p style="font-size:13px; color:var(--text-muted); margin:0 0 12px;"><?= Helpers::e(I18n::t('account.2fa_scan_hint')) ?></p>
      <div style="background:#fff; border-radius:8px; padding:14px; margin-bottom:14px; display:inline-block;">
        <div id="totp-qr"></div>
      </div>
      <script src="/assets/js/qrcode.js"></script>
      <script>
        new QRCode(document.getElementById('totp-qr'), {
          text: <?= json_encode($pendingSetup['setup_data']['otpauth_uri'], JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>,
          width: 176,
          height: 176
        });
      </script>
      <div style="background:var(--bg-void); border:1px dashed var(--key-gold); border-radius:8px; padding:14px; margin-bottom:14px;">
        <p style="font-size:11px; color:var(--text-faint); text-transform:uppercase; letter-spacing:0.06em; margin:0 0 6px;"><?= Helpers::e(I18n::t('account.2fa_manual_entry')) ?></p>
        <p style="font-family:var(--font-mono); color:var(--key-gold); font-size:15px; margin:0; word-break:break-all;"><?= Helpers::e($pendingSetup['setup_data']['manual_entry_key']) ?></p>
      </div>
      <form method="post">
        <?= Csrf::field() ?>
        <input type="hidden" name="form_action" value="confirm_2fa_setup">
        <div class="field"><label><?= Helpers::e(I18n::t('account.2fa_code_label')) ?></label><input type="text" name="code" inputmode="numeric" maxlength="6" style="font-family:var(--font-mono); letter-spacing:0.2em;" required autofocus></div>
        <div class="form-actions" style="padding-bottom:0;"><button type="submit" class="btn btn-primary"><?= Helpers::e(I18n::t('account.2fa_confirm_enable')) ?></button></div>
      </form>

    <?php else: ?>
      <?php if ($twoFactorSuspended): ?>
        <p style="color:var(--key-gold); font-size:13px; margin:0 0 14px;"><?= Helpers::e(I18n::t('account.2fa_suspended_notice')) ?></p>
      <?php endif; ?>
      <form method="post">
        <?= Csrf::field() ?>
        <input type="hidden" name="form_action" value="start_2fa_setup">
        <button type="submit" class="btn btn-primary"><?= Helpers::e(I18n::t('account.2fa_setup_button')) ?></button>
      </form>
    <?php endif; ?>
  </div>
<?php endif; ?>

<?php if ($admin['role'] !== 'master_admin' && $admin['role'] !== 'demo'): ?>
  <div class="form-section" style="border-color:var(--danger);">
    <p class="form-section-title" style="color:var(--danger);"><?= Helpers::e(I18n::t('account.delete_title')) ?></p>
    <p class="form-section-hint"><?= Helpers::e(I18n::t('account.delete_hint')) ?></p>
    <form method="post" onsubmit="return confirm(<?= json_encode(I18n::t('account.delete_confirm_js'), JSON_HEX_APOS | JSON_HEX_QUOT) ?>);">
      <?= Csrf::field() ?>
      <input type="hidden" name="form_action" value="delete_own_account">
      <div class="field"><label><?= Helpers::e(I18n::t('account.confirm_password')) ?></label><input type="password" name="confirm_password" required></div>
      <div class="form-actions" style="padding-bottom:0;"><button type="submit" class="btn btn-ghost" style="color:var(--danger);"><?= Helpers::e(I18n::t('account.delete_button')) ?></button></div>
    </form>
  </div>
<?php endif; ?>

</div>

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