// UES Auth Overlay Controller
class AuthUI {
  constructor() {
    this.overlay = document.getElementById('auth-overlay');
    this.msgEl = document.getElementById('auth-msg');
    this.email = '';           // context email for verify / 2fa / reset
    this.titles = {
      login:  ['Welcome back', 'Sign in to your account to continue.'],
      signup: ['Create your account', 'Join Ultimate Enrollment Suite in seconds.'],
      verify: ['Check your inbox', ''],
      twofa:  ['Verify it\'s you', ''],
      forgot: ['Reset password', 'We\'ll email you a code to reset it.'],
      reset:  ['Set a new password', 'Enter the code and your new password.'],
    };
    this._wire();
  }

  _wire() {
    // View switch links
    this.overlay.querySelectorAll('[data-goto]').forEach(el => {
      el.addEventListener('click', () => this.show(el.getAttribute('data-goto')));
    });
    document.getElementById('btn-login').addEventListener('click', () => this._login());
    document.getElementById('btn-signup').addEventListener('click', () => this._signup());
    document.getElementById('btn-verify').addEventListener('click', () => this._verify());
    document.getElementById('btn-resend').addEventListener('click', () => this._resend());
    document.getElementById('btn-twofa').addEventListener('click', () => this._twofa());
    document.getElementById('btn-forgot').addEventListener('click', () => this._forgot());
    document.getElementById('btn-reset').addEventListener('click', () => this._reset());

    this._wireOtp();

    // Enter key submits the visible view
    this.overlay.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') {
        const active = this.overlay.querySelector('.auth-view.active');
        const btn = active && active.querySelector('.auth-btn');
        if (btn) btn.click();
      }
    });
  }

  open(view = 'login') {
    const alreadyOpen = this.overlay.classList.contains('show');
    this.overlay.classList.add('show');
    // Only set the initial view the first time the modal opens. The app polls
    // get_initial_state every second and re-calls open('login') while signed out —
    // without this guard it would yank the user back to Sign In a second after they
    // switch to Create Account / Verify / Forgot.
    if (!alreadyOpen) this.show(view);
  }
  close() { this.overlay.classList.remove('show'); }

  show(view) {
    this.overlay.querySelectorAll('.auth-view').forEach(v => {
      v.classList.toggle('active', v.getAttribute('data-view') === view);
    });
    const [t, s] = this.titles[view] || this.titles.login;
    document.getElementById('auth-title').innerText = t;
    document.getElementById('auth-sub').innerText = s;
    document.getElementById('auth-sub').style.display = s ? '' : 'none';
    this._clearMsg();
    if (this.email && view === 'login')  document.getElementById('login-email').value = this.email;
    if (this.email && view === 'forgot') document.getElementById('forgot-email').value = this.email;

    // OTP screens: fill the "sent to" label, clear boxes, focus first box, timer
    if (view === 'verify') {
      const lbl = document.getElementById('verify-email-label');
      if (lbl) lbl.textContent = this.email || 'your email';
      this._clearOtp('verify');
      this._startResendTimer();
      this._focusFirstOtp('verify');
      return;
    }
    if (view === 'twofa') {
      const lbl = document.getElementById('twofa-email-label');
      if (lbl) lbl.textContent = this.email ? ('Enter the login code sent to ' + this.email) : 'Enter the login code sent to your email';
      this._clearOtp('twofa');
      this._focusFirstOtp('twofa');
      return;
    }

    const focus = this.overlay.querySelector('.auth-view.active .auth-input');
    if (focus) setTimeout(() => focus.focus(), 60);
  }

  // ---------- OTP segmented input ----------
  _wireOtp() {
    document.querySelectorAll('.otp-group').forEach(group => {
      const boxes = Array.from(group.querySelectorAll('.otp-box'));
      const targetId = group.getAttribute('data-target');
      const viewName = group.closest('.auth-view')?.getAttribute('data-view');
      const sync = (autoSubmit) => {
        const code = boxes.map(b => b.value).join('');
        const hidden = document.getElementById(targetId);
        if (hidden) hidden.value = code;
        boxes.forEach(b => b.classList.toggle('filled', !!b.value));
        if (autoSubmit && code.length === 6) {
          if (viewName === 'verify') this._verify();
          else if (viewName === 'twofa') this._twofa();
        }
      };
      boxes.forEach((box, i) => {
        box.addEventListener('input', () => {
          box.value = box.value.replace(/\D/g, '').slice(0, 1);
          if (box.value && i < boxes.length - 1) boxes[i + 1].focus();
          sync(true);
        });
        box.addEventListener('keydown', (e) => {
          if (e.key === 'Backspace' && !box.value && i > 0) {
            boxes[i - 1].focus(); boxes[i - 1].value = ''; sync(false); e.preventDefault();
          } else if (e.key === 'ArrowLeft' && i > 0) { boxes[i - 1].focus(); e.preventDefault(); }
          else if (e.key === 'ArrowRight' && i < boxes.length - 1) { boxes[i + 1].focus(); e.preventDefault(); }
        });
        box.addEventListener('paste', (e) => {
          e.preventDefault();
          const digits = ((e.clipboardData || window.clipboardData).getData('text') || '').replace(/\D/g, '').slice(0, 6).split('');
          boxes.forEach((b, idx) => { b.value = digits[idx] || ''; });
          (boxes[Math.min(digits.length, boxes.length - 1)] || box).focus();
          sync(true);
        });
      });
    });
  }

  _clearOtp(view) {
    const group = document.querySelector(`.otp-group[data-target="${view}-code"]`);
    if (group) group.querySelectorAll('.otp-box').forEach(b => { b.value = ''; b.classList.remove('filled'); });
    const hidden = document.getElementById(view + '-code');
    if (hidden) hidden.value = '';
  }

  _focusFirstOtp(view) {
    const first = document.querySelector(`.otp-group[data-target="${view}-code"] .otp-box`);
    if (first) setTimeout(() => first.focus(), 80);
  }

  _startResendTimer(seconds = 30) {
    const timerEl = document.getElementById('verify-timer');
    const link = document.getElementById('btn-resend');
    if (!timerEl || !link) return;
    clearInterval(this._resendInt);
    let s = seconds;
    link.style.pointerEvents = 'none';
    link.style.opacity = '0.45';
    const tick = () => {
      if (s <= 0) {
        clearInterval(this._resendInt);
        timerEl.textContent = '';
        link.style.pointerEvents = '';
        link.style.opacity = '';
        return;
      }
      timerEl.textContent = ` (${s}s)`;
      s--;
    };
    tick();
    this._resendInt = setInterval(tick, 1000);
  }

  setHwid(hwid) {
    const el = document.getElementById('auth-hwid');
    if (el && hwid) el.innerText = 'Device: ' + hwid;
  }

  _msg(text, kind = 'info') { this.msgEl.className = 'auth-msg ' + kind; this.msgEl.innerText = text; }
  _clearMsg() { this.msgEl.className = 'auth-msg'; this.msgEl.innerText = ''; }

  async _run(btn, fn) {
    const original = btn.innerHTML;
    btn.disabled = true;
    btn.innerHTML = '<span class="auth-spinner"></span>Please wait...';
    try { return await fn(); }
    finally { btn.disabled = false; btn.innerHTML = original; }
  }

  _fail(res) { this._msg((res && (res.message || res.error)) || 'Something went wrong.', 'err'); }

  async _signup() {
    const username = document.getElementById('signup-username').value.trim();
    const email = document.getElementById('signup-email').value.trim();
    const password = document.getElementById('signup-password').value;
    if (!username || !email || !password) return this._msg('Please fill in all fields.', 'err');
    const res = await this._run(document.getElementById('btn-signup'),
      () => window.bridge.call('auth_register', username, email, password));
    if (res && res.success) {
      this.email = email;
      if (res.needs_verification) {
        // A code was actually emailed — ask for it.
        this.show('verify');
        this._msg('Account created! Check your email for the 6-digit code.', 'ok');
      } else {
        // Auto-verified (email not configured) — go straight to sign in.
        this.show('login');
        const le = document.getElementById('login-email');
        if (le) le.value = email;
        const lp = document.getElementById('login-password');
        if (lp) lp.focus();
        this._msg('Account created! Please sign in with your new password.', 'ok');
      }
    } else this._fail(res);
  }

  async _verify() {
    if (this._otpBusy) return;
    const code = document.getElementById('verify-code').value.trim();
    if (code.length !== 6) return this._msg('Enter all 6 digits of your code.', 'err');
    this._otpBusy = true;
    const res = await this._run(document.getElementById('btn-verify'),
      () => window.bridge.call('auth_verify_email', this.email, code));
    this._otpBusy = false;
    if (res && res.success) {
      this.show('login');
      const le = document.getElementById('login-email'); if (le) le.value = this.email;
      this._msg('Email verified! Please sign in.', 'ok');
    } else { this._clearOtp('verify'); this._focusFirstOtp('verify'); this._fail(res); }
  }

  async _resend() {
    if (!this.email) return this._msg('Enter your email on the sign-in screen first.', 'err');
    const res = await window.bridge.call('auth_resend_code', this.email);
    if (res && res.success) { this._msg('A new code has been sent to ' + this.email + '.', 'info'); this._startResendTimer(); }
    else this._fail(res);
  }

  async _login() {
    const email = document.getElementById('login-email').value.trim();
    const password = document.getElementById('login-password').value;
    if (!email || !password) return this._msg('Enter your email and password.', 'err');
    this.email = email;
    const res = await this._run(document.getElementById('btn-login'),
      () => window.bridge.call('auth_login', email, password));
    if (res && res.twofa_required) {
      this.show('twofa');
      this._msg('A login code was sent to your email.', 'info');
    } else if (res && res.success) {
      await this._onAuthenticated();
    } else if (res && res.needs_verification) {
      this.show('verify');
      this._msg('Please verify your email. We sent a new code.', 'info');
    } else this._fail(res);
  }

  async _twofa() {
    if (this._otpBusy) return;
    const code = document.getElementById('twofa-code').value.trim();
    if (code.length !== 6) return this._msg('Enter all 6 digits of your login code.', 'err');
    this._otpBusy = true;
    const res = await this._run(document.getElementById('btn-twofa'),
      () => window.bridge.call('auth_verify_2fa', this.email, code));
    this._otpBusy = false;
    if (res && res.success) await this._onAuthenticated();
    else { this._clearOtp('twofa'); this._focusFirstOtp('twofa'); this._fail(res); }
  }

  async _forgot() {
    const email = document.getElementById('forgot-email').value.trim();
    if (!email) return this._msg('Enter your email address.', 'err');
    this.email = email;
    const res = await this._run(document.getElementById('btn-forgot'),
      () => window.bridge.call('auth_forgot_password', email));
    this.show('reset');
    this._msg('If that account exists, a reset code has been emailed.', 'info');
  }

  async _reset() {
    const code = document.getElementById('reset-code').value.trim();
    const password = document.getElementById('reset-password').value;
    if (!code || !password) return this._msg('Enter the code and a new password.', 'err');
    const res = await this._run(document.getElementById('btn-reset'),
      () => window.bridge.call('auth_reset_password', this.email, code, password));
    if (res && res.success) {
      this.show('login');
      this._msg('Password reset! Please sign in.', 'ok');
    } else this._fail(res);
  }

  async _onAuthenticated() {
    this._msg('Signed in successfully!', 'ok');
    window.toast && window.toast.show('Welcome back!', 'success');
    this.close();
    if (window.app) {
      window.app.initialized = false;
      await window.app.initBackendState();
    }
  }
}

window.AuthUI = new AuthUI();
