import { useNavigate } from '@solidjs/router';
import { Show, createMemo, createSignal, onMount } from 'solid-js';
import { isExternalIdentity, pickManagementLoginError } from '~/lib/admin-auth';
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 {
      const loginPayload = {
        email: email().trim().toLowerCase(),
        password: password(),
        loginTarget: 'admin',
      };

      const attempts: string[] = [
        '/api/gateway/users/auth/internal/login',
        '/api/gateway/auth/internal/login',
      ];

      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',
            'x-portal-target': 'admin',
          },
          credentials: 'include',
          body: JSON.stringify(loginPayload),
        });
        status = response.status;
        payload = await response.json().catch(() => ({}));
        if (response.ok) {
          success = true;
          break;
        }
      }

      if (!success) {
        const fallback = status === 502
          ? 'Auth service is temporarily unavailable (502). Please retry in 1-2 minutes.'
          : 'Sign in failed.';
        throw new Error(pickManagementLoginError(payload) || fallback);
      }

      if (isExternalIdentity(payload)) {
        throw new Error('External users are not allowed on management login. Please use the external user login.');
      }

      const accessToken = String(payload?.access_token || payload?.accessToken || '').trim();
      if (accessToken && typeof sessionStorage !== 'undefined') {
        sessionStorage.setItem('nxtgauge_admin_access_token', accessToken);
      }

      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="min-h-screen bg-[radial-gradient(circle_at_10%_10%,rgba(253,98,22,0.18),transparent_35%),radial-gradient(circle_at_90%_0%,rgba(34,197,94,0.12),transparent_32%),linear-gradient(180deg,#0f1630_0%,#0b1226_100%)]">
      <div class="mx-auto grid min-h-screen w-full max-w-[1240px] grid-cols-1 items-center gap-6 px-4 py-8 lg:grid-cols-[1.05fr_0.95fr] lg:px-8">
        <section class="relative hidden min-h-[620px] overflow-hidden rounded-[28px] border border-white/20 bg-white/10 p-8 text-white shadow-[0_28px_60px_-34px_rgba(2,6,23,0.88)] backdrop-blur lg:block">
          <img src="/nxtgauge-logo.png" alt="NXTGAUGE" class="h-12 w-auto brightness-0 invert" />
          <p class="mt-8 inline-flex rounded-full border border-white/30 bg-white/10 px-3 py-1 text-[11px] font-bold uppercase tracking-[0.1em] text-orange-100">Internal Admin Portal</p>
          <h1 class="mt-6 max-w-[520px] text-[52px] font-extrabold leading-[1.05] text-white">Welcome back to Nxtgauge.</h1>
          <p class="mt-4 max-w-[520px] text-[17px] leading-relaxed text-slate-200">Sign in to manage operations, roles, and approval workflows from one secure control panel.</p>
          <div class="absolute bottom-8 left-8 right-8 rounded-2xl border border-white/20 bg-white/10 p-4 text-[14px] text-slate-100">
            <p class="font-semibold">Secure login with internal access policies.</p>
          </div>
        </section>

        <section class="rounded-[28px] border border-white/30 bg-white/95 p-6 shadow-[0_28px_60px_-34px_rgba(2,6,23,0.88)] backdrop-blur sm:p-8">
          <div class="mx-auto w-full max-w-[560px]">
            <h2 class="text-[46px] font-extrabold tracking-tight text-[#101228] sm:text-[38px] lg:text-[46px]">{mode() === 'login' ? 'Sign In' : 'Reset Password'}</h2>
            <p class="mt-2 text-[15px] text-[#535e7a]">{mode() === 'login' ? 'Internal team access only.' : 'Use your internal email to reset access.'}</p>

            <form class="mt-6 space-y-5">
              <div class="space-y-4">
                <div>
                  <label class="mb-1 block text-[11px] font-bold uppercase tracking-[0.11em] text-[#4b546f]">Email</label>
                  <input
                    type="email"
                    value={email()}
                    onInput={(event) => {
                      setEmail(event.currentTarget.value);
                      clearMessages();
                    }}
                    placeholder="Enter your email"
                    class="h-11 w-full rounded-xl border border-[#cfd4e3] bg-white px-3.5 text-[15px] text-[#101228] outline-none transition focus:border-[#fd6216] focus:ring-2 focus:ring-[#ffd8c3]"
                  />
                </div>

                <Show when={mode() === 'login'}>
                  <div>
                    <div class="mb-1 flex items-center justify-between gap-2">
                      <label class="text-[11px] font-bold uppercase tracking-[0.11em] text-[#4b546f]">Password</label>
                      <button type="button" class="text-[12px] font-bold text-[#fd6216] underline" onClick={() => switchMode('reset')}>
                        Forgot?
                      </button>
                    </div>
                    <input
                      type="password"
                      value={password()}
                      onInput={(event) => {
                        setPassword(event.currentTarget.value);
                        clearMessages();
                      }}
                      placeholder="Enter your password"
                      class="h-11 w-full rounded-xl border border-[#cfd4e3] bg-white px-3.5 text-[15px] text-[#101228] outline-none transition focus:border-[#fd6216] focus:ring-2 focus:ring-[#ffd8c3]"
                    />
                  </div>
                </Show>

                <Show when={mode() === 'reset'}>
                  <div class="space-y-4">
                    <div>
                      <label class="mb-1 block text-[11px] font-bold uppercase tracking-[0.11em] text-[#4b546f]">New Password</label>
                      <input
                        type="password"
                        value={newPassword()}
                        onInput={(event) => {
                          setNewPassword(event.currentTarget.value);
                          clearMessages();
                        }}
                        placeholder="Minimum 8 characters"
                        class="h-11 w-full rounded-xl border border-[#cfd4e3] bg-white px-3.5 text-[15px] text-[#101228] outline-none transition focus:border-[#fd6216] focus:ring-2 focus:ring-[#ffd8c3]"
                      />
                    </div>
                    <div>
                      <label class="mb-1 block text-[11px] font-bold uppercase tracking-[0.11em] text-[#4b546f]">Confirm Password</label>
                      <input
                        type="password"
                        value={confirmPassword()}
                        onInput={(event) => {
                          setConfirmPassword(event.currentTarget.value);
                          clearMessages();
                        }}
                        placeholder="Confirm new password"
                        class="h-11 w-full rounded-xl border border-[#cfd4e3] bg-white px-3.5 text-[15px] text-[#101228] outline-none transition focus:border-[#fd6216] focus:ring-2 focus:ring-[#ffd8c3]"
                      />
                    </div>
                    <Show when={resetStep() === 'verify'}>
                      <div>
                        <label class="mb-1 block text-[11px] font-bold uppercase tracking-[0.11em] text-[#4b546f]">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="000000"
                          class="h-11 w-full rounded-xl border border-[#cfd4e3] bg-white px-3.5 text-center text-[18px] tracking-[0.2em] text-[#101228] outline-none transition focus:border-[#fd6216] focus:ring-2 focus:ring-[#ffd8c3]"
                        />
                        <p class="mt-2 rounded-xl border border-emerald-200 bg-emerald-50 px-3 py-2 text-[12px] text-emerald-900">
                          Code sent to <span class="font-semibold">{maskedEmail() || email()}</span>.
                        </p>
                      </div>
                    </Show>
                  </div>
                </Show>
              </div>

              <Show when={mode() === 'login'}>
                <button
                  type="button"
                  class="h-11 w-full rounded-xl bg-[#fd6216] text-[15px] font-bold text-white transition hover:bg-[#e4570f] disabled:cursor-not-allowed disabled:opacity-70"
                  disabled={isSubmitting() || !canSubmitLoginCredentials()}
                  onClick={directSignIn}
                >
                  {isSubmitting() ? 'Signing In...' : 'Sign In'}
                </button>
              </Show>

              <Show when={mode() === 'reset'}>
                <div class="flex items-center justify-between">
                  <button type="button" class="text-[13px] font-semibold text-[#fd6216] underline" onClick={() => switchMode('login')}>
                    Back to sign in
                  </button>
                </div>
                <Show when={resetStep() === 'request'} fallback={(
                  <button
                    type="button"
                    class="h-11 w-full rounded-xl bg-[#fd6216] text-[15px] font-bold text-white transition hover:bg-[#e4570f] disabled:cursor-not-allowed disabled:opacity-70"
                    disabled={isSubmitting() || !canSubmitResetVerify()}
                    onClick={verifyResetCode}
                  >
                    {isSubmitting() ? 'Resetting Password...' : 'Verify & Reset Password'}
                  </button>
                )}>
                  <button
                    type="button"
                    class="h-11 w-full rounded-xl bg-[#fd6216] text-[15px] font-bold text-white transition hover:bg-[#e4570f] disabled:cursor-not-allowed disabled:opacity-70"
                    disabled={isSubmitting() || !canSubmitResetRequest()}
                    onClick={requestResetCode}
                  >
                    {isSubmitting() ? 'Sending Code...' : 'Send Reset Code'}
                  </button>
                </Show>
              </Show>
            </form>

            {info() ? <p class="mt-4 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-[14px] text-emerald-700">{info()}</p> : null}
            {error() ? <p class="mt-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-[14px] text-red-700">{error()}</p> : null}
          </div>
        </section>
      </div>
    </main>
  );
}
