import { useNavigate } from '@solidjs/router';
import { createMemo, createSignal, onMount } from 'solid-js';
import { hasAdminSession, setAdminSession } from '~/lib/admin-session';

type AuthMode = 'login' | 'reset';
type ResetStep = 'request' | 'verify';

function pickChallengeId(payload: any): string {
  const direct = String(payload?.challengeId || '').trim();
  if (direct) return direct;
  const nested = String(payload?.data?.challengeId || '').trim();
  if (nested) return nested;
  const snake = String(payload?.challenge_id || '').trim();
  if (snake) return snake;
  return '';
}

function pickMaskedEmail(payload: any, fallback: string): string {
  const direct = String(payload?.maskedEmail || '').trim();
  if (direct) return direct;
  const nested = String(payload?.data?.maskedEmail || '').trim();
  if (nested) return nested;
  return fallback;
}

export default function LoginPage() {
  const navigate = useNavigate();
  const [mode, setMode] = createSignal<AuthMode>('login');
  const [resetStep, setResetStep] = createSignal<ResetStep>('request');
  const [email, setEmail] = createSignal('');
  const [password, setPassword] = createSignal('');
  const [resetCode, setResetCode] = createSignal('');
  const [newPassword, setNewPassword] = createSignal('');
  const [confirmPassword, setConfirmPassword] = createSignal('');
  const [challengeId, setChallengeId] = createSignal('');
  const [maskedEmail, setMaskedEmail] = createSignal('');
  const [isSubmitting, setIsSubmitting] = createSignal(false);
  const [error, setError] = createSignal('');
  const [info, setInfo] = createSignal('');

  const canSubmitResetRequest = createMemo(
    () =>
      email().trim().length > 0 &&
      newPassword().trim().length > 0 &&
      confirmPassword().trim().length > 0,
  );

  const canSubmitResetVerify = createMemo(
    () => challengeId().trim().length > 0 && resetCode().trim().length === 6,
  );
  const canSubmitLoginCredentials = createMemo(
    () => email().trim().length > 0 && password().trim().length > 0,
  );

  const clearMessages = () => {
    setError('');
    setInfo('');
  };

  const resetPasswordFlow = () => {
    setResetStep('request');
    setResetCode('');
    setChallengeId('');
    setMaskedEmail('');
    setNewPassword('');
    setConfirmPassword('');
  };

  const switchMode = (nextMode: AuthMode) => {
    clearMessages();
    setMode(nextMode);
    if (nextMode === 'login') {
      resetPasswordFlow();
    }
  };

  onMount(() => {
    if (hasAdminSession()) {
      navigate('/admin', { replace: true });
    }
  });

  const completeAdminLogin = () => {
    setAdminSession();
    const params = new URLSearchParams(window.location.search);
    const from = params.get('from');
    const nextPath = from && from.startsWith('/admin') ? from : '/admin';
    navigate(nextPath, { replace: true });
  };

  const directSignIn = async () => {
    clearMessages();
    if (!canSubmitLoginCredentials()) {
      setError('Email and password are required.');
      return;
    }

    setIsSubmitting(true);
    try {
      completeAdminLogin();
    } catch (nextError: any) {
      setError(String(nextError?.message || 'Sign in failed.'));
    } finally {
      setIsSubmitting(false);
    }
  };

  const requestResetCode = async () => {
    clearMessages();
    if (!canSubmitResetRequest()) {
      setError('Email, new password, and confirm password are required.');
      return;
    }
    if (newPassword() !== confirmPassword()) {
      setError('Passwords do not match.');
      return;
    }

    const trimmedEmail = email().trim().toLowerCase();
    const resolvedPassword = newPassword().trim();
    const requestPayload = {
      email: trimmedEmail,
      newPassword: resolvedPassword,
      new_password: resolvedPassword,
      password: resolvedPassword,
    };

    const attempts: Array<{ url: string; body: string }> = [
      {
        url: '/api/gateway/users/auth/internal/forgot-password/request-code',
        body: JSON.stringify(requestPayload),
      },
      {
        url: '/api/gateway/auth/internal/forgot-password/request-code',
        body: JSON.stringify(requestPayload),
      },
      {
        url: '/api/gateway/users/auth/internal/forgot-password/request-code',
        body: JSON.stringify({ data: requestPayload }),
      },
      {
        url: '/api/gateway/auth/internal/forgot-password/request-code',
        body: JSON.stringify({ data: requestPayload }),
      },
    ];

    setIsSubmitting(true);
    try {
      let payload: any = {};
      let status = 500;
      for (const attempt of attempts) {
        const response = await fetch(attempt.url, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Accept: 'application/json',
          },
          body: attempt.body,
        });
        status = response.status;
        payload = await response.json().catch(() => ({}));
        if (response.ok) break;
      }

      const nextChallengeId = pickChallengeId(payload);
      if (!nextChallengeId) {
        const fallbackMessage =
          status === 502
            ? 'Verification service is temporarily unavailable (502). Please retry in 1-2 minutes.'
            : 'Failed to send reset code.';
        throw new Error(String(payload?.message || payload?.error || fallbackMessage).trim());
      }

      setChallengeId(nextChallengeId);
      setMaskedEmail(pickMaskedEmail(payload, trimmedEmail));
      setResetStep('verify');
      const debugCode = String(payload?.debugCode || payload?.data?.debugCode || '').trim();
      setInfo(debugCode ? `Reset code sent. [DEV CODE: ${debugCode}]` : 'Reset code sent to your email.');
    } catch (nextError: any) {
      setError(String(nextError?.message || 'Failed to send reset code.'));
    } finally {
      setIsSubmitting(false);
    }
  };

  const verifyResetCode = async () => {
    clearMessages();
    if (!canSubmitResetVerify()) {
      setError('A valid 6-digit verification code is required.');
      return;
    }

    if (newPassword().trim() !== confirmPassword().trim()) {
      setError('Passwords do not match.');
      return;
    }

    const resolvedPassword = newPassword().trim();
    const resolvedChallengeId = challengeId().trim();
    const resolvedCode = resetCode().trim();

    const verifyPayload = {
      challengeId: resolvedChallengeId,
      challenge_id: resolvedChallengeId,
      code: resolvedCode,
      otp: resolvedCode,
      verificationCode: resolvedCode,
      verification_code: resolvedCode,
      newPassword: resolvedPassword,
      new_password: resolvedPassword,
      password: resolvedPassword,
    };

    const attempts: string[] = [
      '/api/gateway/users/auth/internal/forgot-password/verify-code',
      '/api/gateway/auth/internal/forgot-password/verify-code',
    ];

    setIsSubmitting(true);
    try {
      let payload: any = {};
      let status = 500;
      let success = false;
      for (const url of attempts) {
        const response = await fetch(url, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            Accept: 'application/json',
          },
          body: JSON.stringify(verifyPayload),
        });
        status = response.status;
        payload = await response.json().catch(() => ({}));
        if (response.ok) {
          success = true;
          break;
        }
      }

      if (!success) {
        const fallbackMessage =
          status === 502
            ? 'Verification service is temporarily unavailable (502). Please retry in 1-2 minutes.'
            : 'Password reset failed.';
        throw new Error(String(payload?.message || payload?.error || fallbackMessage).trim());
      }

      setPassword('');
      switchMode('login');
      setInfo('Password reset successful. Please sign in with your new password.');
    } catch (nextError: any) {
      setError(String(nextError?.message || 'Password reset failed.'));
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <main class="auth-page auth-page-login">
      <div class="auth-bg" />
      <div class="auth-layout">
        <section class="auth-visual">
          <p class="auth-visual-kicker">Internal Access</p>
          <h1>Welcome back to Nxtgauge.</h1>
          <p>Sign in securely to access the admin control panel.</p>
          <img
            src="https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&w=1200&q=80"
            alt="Office workspace"
          />
        </section>

        <section class="auth-card auth-form-card">
          <img src="/nxtgauge-logo.png" alt="NXTGAUGE" class="auth-logo" />
          <h2 class="auth-title">{mode() === 'login' ? 'Employee Login' : 'Reset Password'}</h2>

          <form class="auth-form-grid">
            <div class="field">
              <label>Email address</label>
              <input
                type="email"
                value={email()}
                onInput={(event) => {
                  setEmail(event.currentTarget.value);
                  clearMessages();
                }}
                placeholder="Enter your email"
              />
            </div>
            {mode() === 'login' ? (
              <>
                <div class="field">
                  <label>Password</label>
                  <input
                    type="password"
                    value={password()}
                    onInput={(event) => {
                      setPassword(event.currentTarget.value);
                      clearMessages();
                    }}
                    placeholder="Enter your password"
                  />
                </div>
                <div class="auth-switch">
                  <button type="button" class="auth-link-btn" onClick={() => switchMode('reset')}>
                    Forgot password?
                  </button>
                </div>
                <div class="actions">
                  <button
                    type="button"
                    class="btn primary block-btn"
                    disabled={isSubmitting() || !canSubmitLoginCredentials()}
                    onClick={directSignIn}
                  >
                    {isSubmitting() ? 'Signing in...' : 'Sign in'}
                  </button>
                </div>
              </>
            ) : (
              <>
                <div class="field">
                  <label>New password</label>
                  <input
                    type="password"
                    value={newPassword()}
                    onInput={(event) => {
                      setNewPassword(event.currentTarget.value);
                      clearMessages();
                    }}
                    placeholder="Enter your new password"
                  />
                </div>
                <div class="field">
                  <label>Confirm password</label>
                  <input
                    type="password"
                    value={confirmPassword()}
                    onInput={(event) => {
                      setConfirmPassword(event.currentTarget.value);
                      clearMessages();
                    }}
                    placeholder="Confirm your new password"
                  />
                </div>

                {resetStep() === 'verify' ? (
                  <div class="field">
                    <label>Verification code</label>
                    <input
                      type="text"
                      inputMode="numeric"
                      maxLength={6}
                      value={resetCode()}
                      onInput={(event) => {
                        setResetCode(event.currentTarget.value.replace(/\D/g, '').slice(0, 6));
                        clearMessages();
                      }}
                      placeholder="Enter 6-digit code"
                    />
                    <p class="hint">Code sent to {maskedEmail() || email()}.</p>
                  </div>
                ) : null}

                <div class="auth-switch">
                  <button type="button" class="auth-link-btn" onClick={() => switchMode('login')}>
                    Back to sign in
                  </button>
                </div>
                <div class="actions">
                  {resetStep() === 'request' ? (
                    <button
                      type="button"
                      class="btn primary block-btn"
                      disabled={isSubmitting() || !canSubmitResetRequest()}
                      onClick={requestResetCode}
                    >
                      {isSubmitting() ? 'Sending code...' : 'Send reset code'}
                    </button>
                  ) : (
                    <button
                      type="button"
                      class="btn primary block-btn"
                      disabled={isSubmitting() || !canSubmitResetVerify()}
                      onClick={verifyResetCode}
                    >
                      {isSubmitting() ? 'Resetting password...' : 'Verify & reset password'}
                    </button>
                  )}
                </div>
              </>
            )}
          </form>
          {info() ? <p class="inline-note auth-inline-msg">{info()}</p> : null}
          {error() ? <p class="error-note auth-inline-msg">{error()}</p> : null}
        </section>
      </div>
    </main>
  );
}
