import { A, useNavigate, useSearchParams } from '@solidjs/router';
import { createMemo, createSignal, For, onMount, Show } from 'solid-js';
import PublicBackground from '~/components/PublicBackground';
import PublicHeader from '~/components/PublicHeader';
import CaptchaCanvas from '~/components/CaptchaCanvas';
import {
  checkPasswordStrength,
  isPasswordStrong,
  isValidCaptcha,
  isValidEmail,
  isValidName,
  validateRegisterForm,
} from '~/lib/form-validation';

type RoleKey = 'company' | 'job_seeker' | 'professional' | 'customer';

type RegisterErrors = Record<string, string>;

function normalizeIntent(intent: string | null | undefined): RoleKey {
  const v = String(intent || '').toLowerCase();
  if (v.includes('company')) return 'company';
  if (v.includes('professional')) return 'professional';
  if (v.includes('developer') || v.includes('photographer') || v.includes('makeup') || v.includes('tutor') || v.includes('video') || v.includes('graphic') || v.includes('social') || v.includes('fitness') || v.includes('catering') || v.includes('ugc')) return 'professional';
  if (v.includes('customer')) return 'customer';
  return 'job_seeker';
}

function randomCaptcha(length = 6): string {
  const alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
  let out = '';
  for (let i = 0; i < length; i += 1) {
    out += alphabet[Math.floor(Math.random() * alphabet.length)];
  }
  return out;
}

function PasswordVisibilityIcon(props: { visible: boolean }) {
  if (props.visible) {
    return (
      <svg viewBox="0 0 24 24" aria-hidden="true">
        <path d="M3 3l18 18" />
        <path d="M10.58 10.58a2 2 0 0 0 2.83 2.83" />
        <path d="M9.88 5.09A11 11 0 0 1 12 4.9c5.5 0 10 4.1 10 7.1 0 1.2-.72 2.53-1.95 3.72" />
        <path d="M6.1 6.1C3.54 7.58 2 9.79 2 12c0 3 4.48 7.1 10 7.1 1.72 0 3.36-.4 4.84-1.12" />
      </svg>
    );
  }
  return (
    <svg viewBox="0 0 24 24" aria-hidden="true">
      <path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" />
      <circle cx="12" cy="12" r="3" />
    </svg>
  );
}

export default function SignupRoute() {
  const navigate = useNavigate();
  const [search] = useSearchParams();
  onMount(() => {
    const intent = String(search.intent || '').trim();
    const role = String(search.role || '').trim();
    if (!intent && !role) navigate('/users/choose-role', { replace: true });
  });

  const [step, setStep] = createSignal<'register' | 'verify'>('register');
  const [firstName, setFirstName] = createSignal('');
  const [lastName, setLastName] = createSignal('');
  const [email, setEmail] = createSignal('');
  const [password, setPassword] = createSignal('');
  const [confirmPassword, setConfirmPassword] = createSignal('');
  const role = createMemo<RoleKey>(() => normalizeIntent(search.intent || search.role));
  const selectedProfessionalRole = createMemo(() => String(search.role || '').trim().toUpperCase());
  const [termsAccepted, setTermsAccepted] = createSignal(false);
  const [captcha, setCaptcha] = createSignal('');
  const [captchaCode, setCaptchaCode] = createSignal(randomCaptcha());
  const [otp, setOtp] = createSignal(['', '', '', '', '', '']);
  const [errors, setErrors] = createSignal<RegisterErrors>({});
  const [serverError, setServerError] = createSignal('');
  const [emailExists, setEmailExists] = createSignal(false);
  const [submitting, setSubmitting] = createSignal(false);
  const [pendingEmail, setPendingEmail] = createSignal('');
  const [pendingPassword, setPendingPassword] = createSignal('');
  const [showPassword, setShowPassword] = createSignal(false);
  const [showConfirmPassword, setShowConfirmPassword] = createSignal(false);

  const passwordChecks = createMemo(() => checkPasswordStrength(password(), confirmPassword()));
  const otpCode = createMemo(() => otp().join(''));
  const firstNameValid = createMemo(() => !firstName().trim() || isValidName(firstName()));
  const lastNameValid = createMemo(() => !lastName().trim() || isValidName(lastName()));
  const emailValid = createMemo(() => !email().trim() || isValidEmail(email()));
  const canSubmit = createMemo(() =>
    firstName().trim().length > 0 &&
    firstNameValid() &&
    lastName().trim().length > 0 &&
    lastNameValid() &&
    emailValid() &&
    isValidEmail(email()) &&
    isPasswordStrong(passwordChecks()) &&
    passwordChecks().match &&
    isValidCaptcha(captcha(), captchaCode()) &&
    termsAccepted() &&
    !emailExists()
  );

  const refreshCaptcha = () => {
    setCaptcha('');
    setCaptchaCode(randomCaptcha());
  };

  const checkEmailExists = async (emailValue: string) => {
    const normalized = emailValue.trim().toLowerCase();
    if (!normalized || !isValidEmail(normalized)) {
      setEmailExists(false);
      return false;
    }

    try {
      const response = await fetch('/api/gateway/api/auth/check-email', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ email: normalized }),
      });
      const payload = await response.json().catch(() => ({}));
      const exists = Boolean(response.ok && payload?.exists);
      setEmailExists(exists);
      return exists;
    } catch {
      setEmailExists(false);
      return false;
    }
  };

  const setOtpDigit = (index: number, value: string) => {
    const clean = value.replace(/\D/g, '').slice(0, 1);
    setOtp((prev) => {
      const next = prev.slice();
      next[index] = clean;
      return next;
    });
    if (clean) {
      const nextEl = document.querySelector<HTMLInputElement>(`#otp-${index + 1}`);
      if (nextEl) nextEl.focus();
    }
  };

  const saveUserForDashboard = (input: { firstName: string; lastName: string; email: string; roleKey: RoleKey; user?: any }) => {
    const fullName = `${input.firstName} ${input.lastName}`.trim();
    const payload = {
      firstName: input.firstName,
      lastName: input.lastName,
      fullName,
      name: fullName,
      displayName: fullName,
      email: input.email.toLowerCase(),
      roleKey: input.roleKey,
      role: input.roleKey,
      selectedProfessionalRole: selectedProfessionalRole() || null,
      user: input.user || null,
    };
    if (typeof window !== 'undefined') {
      window.localStorage.setItem('nxtgauge_signup_profile_v1', JSON.stringify(payload));
      window.localStorage.setItem('nxtgauge_auth_user', JSON.stringify(payload));
      window.localStorage.setItem('nxtgauge_user', JSON.stringify(payload));
    }
  };

  const storeAuth = (payload: any) => {
    const accessToken = String(payload?.access_token || '').trim();
    if (typeof window !== 'undefined' && accessToken) {
      window.sessionStorage.setItem('nxtgauge_access_token', accessToken);
      window.sessionStorage.setItem('nxtgauge_frontend_access_token', accessToken);
      window.localStorage.setItem('nxtgauge_access_token', accessToken);
    }
  };

  const register = async () => {
    setServerError('');
    const validation = validateRegisterForm({
      firstName: firstName(),
      lastName: lastName(),
      email: email(),
      password: password(),
      confirmPassword: confirmPassword(),
      captcha: captcha(),
      expectedCaptcha: captchaCode(),
      termsAccepted: termsAccepted(),
    });
    setErrors(validation.errors);
    if (!validation.isValid) return;

    setSubmitting(true);
    try {
      const res = await fetch('/api/gateway/api/auth/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        credentials: 'include',
        body: JSON.stringify({
          full_name: `${firstName().trim()} ${lastName().trim()}`.trim(),
          email: email().trim().toLowerCase(),
          password: password(),
          phone: null,
        }),
      });

      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setServerError(String(data?.error || data?.message || 'Unable to create account.'));
        refreshCaptcha();
        return;
      }

      const cleanEmail = email().trim().toLowerCase();
      setPendingEmail(cleanEmail);
      setPendingPassword(password());
      saveUserForDashboard({
        firstName: firstName().trim(),
        lastName: lastName().trim(),
        email: cleanEmail,
        roleKey: role(),
      });
      setStep('verify');
      setOtp(['', '', '', '', '', '']);
    } finally {
      setSubmitting(false);
    }
  };

  const verifyOtp = async () => {
    setServerError('');
    if (otpCode().length !== 6) {
      setServerError('Enter the 6-digit code sent to your email.');
      return;
    }
    setSubmitting(true);
    try {
      const verifyRes = await fetch('/api/gateway/api/auth/verify-email', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ otp: otpCode() }),
      });
      const verifyData = await verifyRes.json().catch(() => ({}));
      if (!verifyRes.ok) {
        setServerError(String(verifyData?.error || verifyData?.message || 'Verification failed.'));
        return;
      }

      const loginRes = await fetch('/api/gateway/api/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        credentials: 'include',
        body: JSON.stringify({
          email: pendingEmail() || email().trim().toLowerCase(),
          password: pendingPassword() || password(),
        }),
      });
      const loginData = await loginRes.json().catch(() => ({}));
      if (!loginRes.ok) {
        setServerError(String(loginData?.error || loginData?.message || 'Email verified. Please login manually.'));
        navigate('/login', { replace: true });
        return;
      }

      storeAuth(loginData);
      saveUserForDashboard({
        firstName: firstName().trim(),
        lastName: lastName().trim(),
        email: pendingEmail() || email().trim().toLowerCase(),
        roleKey: role(),
        user: loginData?.user,
      });
      navigate('/dashboard', { replace: true });
    } finally {
      setSubmitting(false);
    }
  };

  const resendOtp = async () => {
    setServerError('');
    setSubmitting(true);
    try {
      const res = await fetch('/api/gateway/api/auth/resend-otp', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        credentials: 'include',
        body: JSON.stringify({ email: pendingEmail() || email().trim().toLowerCase() }),
      });
      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        setServerError(String(data?.error || data?.message || 'Unable to resend OTP right now.'));
      }
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <main class="auth-page">
      <PublicBackground />
      <PublicHeader />
      <div class="auth-layout">
        <section class="auth-visual card glass-dark">
          <img class="auth-visual-img" src="/images/auth-company-2.jpg" alt="Get Started" />
          <div class="auth-visual-overlay" />
          <div class="auth-visual-content">
            <p class="eyebrow">Get Started</p>
            <h1 class="title light">Create Your Nxtgauge Account</h1>
            <p class="subtitle light">Join verified opportunities and continue directly to your dashboard after signup.</p>
          </div>
        </section>

        <section class="auth-form card glass-light">
          <Show when={step() === 'register'} fallback={
            <>
              <h2 class="title">Verify Email</h2>
              <p class="subtitle">Enter the 6-digit code sent to <strong>{pendingEmail() || email()}</strong>.</p>

              <div class="otp-row">
                <For each={Array.from({ length: 6 }, (_, index) => index)}>
                  {(index) => (
                    <input
                      id={`otp-${index}`}
                      class="otp-input"
                      inputMode="numeric"
                      maxlength={1}
                      value={otp()[index]}
                      onInput={(e) => setOtpDigit(index, e.currentTarget.value)}
                    />
                  )}
                </For>
              </div>

              <button class="auth-submit-btn" type="button" disabled={submitting()} onClick={() => void verifyOtp()}>
                {submitting() ? 'Verifying...' : 'Verify and Continue'}
              </button>

              <div class="auth-footer-row">
                <p class="note">Didn’t receive code?</p>
                <button class="auth-forgot-link" type="button" onClick={() => void resendOtp()} disabled={submitting()}>
                  Resend OTP
                </button>
              </div>
            </>
          }>
            <h2 class="title">Create Your Account</h2>
            <p class="subtitle">Sign up first, then go directly to dashboard after email verification.</p>

            <div class="grid" style={{ 'grid-template-columns': '1fr 1fr', margin: 0 }}>
              <div class="field">
                <label class="label" for="first-name">FULL NAME</label>
                <input id="first-name" class="input" value={firstName()} onInput={(e) => setFirstName(e.currentTarget.value)} />
                <p class="validation-note" style={{ color: firstName().trim() && firstNameValid() ? '#fd6116' : '#6e7591' }}>
                  {firstName().trim() && firstNameValid() ? '✓ First name looks good' : '• First name is required'}
                </p>
              </div>
              <div class="field">
                <label class="label" for="last-name">LAST NAME</label>
                <input id="last-name" class="input" value={lastName()} onInput={(e) => setLastName(e.currentTarget.value)} />
                <p class="validation-note" style={{ color: lastName().trim() && lastNameValid() ? '#fd6116' : '#6e7591' }}>
                  {lastName().trim() && lastNameValid() ? '✓ Last name looks good' : '• Last name is required'}
                </p>
              </div>
            </div>

            <div class="field">
              <label class="label" for="email">EMAIL ADDRESS</label>
              <input
                id="email"
                type="email"
                class="input"
                value={email()}
                onInput={(e) => {
                  setEmail(e.currentTarget.value);
                  setEmailExists(false);
                }}
                onBlur={() => { void checkEmailExists(email()); }}
              />
              <p class="validation-note" style={{ color: emailExists() ? '#dc2626' : (email().trim() && emailValid() ? '#fd6116' : '#6e7591') }}>
                {emailExists()
                  ? '• This email is already registered'
                  : (email().trim() && emailValid() ? '✓ Valid email format' : '• Enter a valid email format')}
              </p>
            </div>

            <div class="grid" style={{ 'grid-template-columns': '1fr 1fr', margin: 0 }}>
              <div class="field">
                <label class="label" for="password">PASSWORD</label>
                <div class="auth-password-wrap">
                  <input id="password" type={showPassword() ? 'text' : 'password'} class="input" value={password()} onInput={(e) => setPassword(e.currentTarget.value)} />
                  <button
                    class="auth-toggle-visibility"
                    type="button"
                    onClick={() => setShowPassword((prev) => !prev)}
                    aria-label={showPassword() ? 'Hide password' : 'Show password'}
                  >
                    <PasswordVisibilityIcon visible={showPassword()} />
                  </button>
                </div>
                <div class="password-strength-grid">
                  <p style={{ color: passwordChecks().minLength ? '#fd6116' : '#6e7591' }}>{passwordChecks().minLength ? '✓' : '•'} 8+ chars</p>
                  <p style={{ color: passwordChecks().uppercase ? '#fd6116' : '#6e7591' }}>{passwordChecks().uppercase ? '✓' : '•'} Uppercase</p>
                  <p style={{ color: passwordChecks().special ? '#fd6116' : '#6e7591' }}>{passwordChecks().special ? '✓' : '•'} Special</p>
                  <p style={{ color: passwordChecks().lowercase ? '#fd6116' : '#6e7591' }}>{passwordChecks().lowercase ? '✓' : '•'} Lowercase</p>
                  <p style={{ color: passwordChecks().number ? '#fd6116' : '#6e7591' }}>{passwordChecks().number ? '✓' : '•'} Number</p>
                </div>
              </div>
              <div class="field">
                <label class="label" for="confirm-password">CONFIRM PASSWORD</label>
                <div class="auth-password-wrap">
                  <input id="confirm-password" type={showConfirmPassword() ? 'text' : 'password'} class="input" value={confirmPassword()} onInput={(e) => setConfirmPassword(e.currentTarget.value)} />
                  <button
                    class="auth-toggle-visibility"
                    type="button"
                    onClick={() => setShowConfirmPassword((prev) => !prev)}
                    aria-label={showConfirmPassword() ? 'Hide password' : 'Show password'}
                  >
                    <PasswordVisibilityIcon visible={showConfirmPassword()} />
                  </button>
                </div>
                <p class="validation-note" style={{ color: confirmPassword() && passwordChecks().match ? '#fd6116' : '#6e7591' }}>
                  {confirmPassword() && passwordChecks().match ? '✓ Passwords match' : '• Passwords do not match'}
                </p>
              </div>
            </div>

            <div class="field">
              <label class="label" for="captcha">CAPTCHA</label>
              <div class="auth-captcha-row">
                <button type="button" class="auth-captcha-refresh" onClick={refreshCaptcha} aria-label="Refresh captcha">↻</button>
                <CaptchaCanvas code={captchaCode()} class="auth-captcha-canvas" />
                <input id="captcha" class="input" value={captcha()} onInput={(e) => setCaptcha(e.currentTarget.value.toUpperCase())} placeholder="Enter captcha" />
              </div>
              <p class="validation-note" style={{ color: captcha() && isValidCaptcha(captcha(), captchaCode()) ? '#fd6116' : '#6e7591' }}>
                {captcha() ? (isValidCaptcha(captcha(), captchaCode()) ? '✓ Captcha matched' : '• Captcha does not match') : '• Enter captcha to continue'}
              </p>
            </div>

            <div class="field" style={{ 'margin-top': '16px' }}>
              <label class="auth-checkbox-wrapper">
                <input class="auth-checkbox" type="checkbox" checked={termsAccepted()} onChange={(e) => setTermsAccepted(e.currentTarget.checked)} />
                <span class="auth-checkbox-label">I agree to the <A href="/terms">Terms and Conditions</A> and <A href="/privacy">Privacy Policy</A></span>
              </label>
            </div>

            <button class="auth-submit-btn" type="button" disabled={submitting() || !canSubmit()} onClick={() => void register()}>
              {submitting() ? 'Creating Account...' : 'Sign Up'}
            </button>

            <div class="auth-footer-row">
              <p class="footer-text">We will send a verification code to your email.</p>
              <p class="note">Already have an account? <A href="/login">Sign In</A></p>
            </div>
          </Show>

          <Show when={serverError()}>
            <p class="error">{serverError()}</p>
          </Show>
        </section>
      </div>
    </main>
  );
}
