import { A, useNavigate } 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 { fetchCaptcha } from "~/lib/api";
import {
  checkPasswordStrength,
  isPasswordStrong,
  isValidCaptcha,
  isValidEmail,
  isValidName,
} from "~/lib/form-validation";

export default function CustomerSignupRoute() {
  const navigate = useNavigate();

  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 [captcha, setCaptcha] = createSignal("");
  const [captchaId, setCaptchaId] = createSignal("");
  const [captchaChallenge, setCaptchaChallenge] = createSignal("");
  const [otp, setOtp] = createSignal(["", "", "", "", "", ""]);
  const [errors, setErrors] = createSignal<Record<string, string>>({});
  const [serverError, setServerError] = createSignal("");
  const [emailExists, setEmailExists] = createSignal(false);
  const [submitting, setSubmitting] = createSignal(false);
  const [pendingEmail, setPendingEmail] = createSignal("");
  const [verifiedSuccess, setVerifiedSuccess] = createSignal(false);
  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())
  );

  const refreshCaptcha = async () => {
    setCaptcha("");
    setCaptchaId("");
    setCaptchaChallenge("");
    try {
      const challenge = await fetchCaptcha();
      setCaptchaId(challenge.captcha_id);
      setCaptchaChallenge(challenge.challenge);
    } catch {
      // Leave captcha blank; user can retry via the refresh button.
    }
  };

  onMount(() => {
    void refreshCaptcha();
  });

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

    try {
      const response = await fetch("/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;
    });
    queueMicrotask(() => {
      if (clean && index < 5) {
        const nextEl = document.querySelector<HTMLInputElement>(`#otp-${index + 1}`);
        if (nextEl) nextEl.focus();
      }
    });
  };

  const saveUserForDashboard = (input: {
    firstName: string;
    lastName: string;
    email: string;
  }) => {
    const displayName = `${input.firstName} ${input.lastName}`.trim();
    const payload = {
      firstName: input.firstName,
      lastName: input.lastName,
      fullName: displayName,
      name: displayName,
      displayName,
      email: input.email.toLowerCase(),
      roleKey: "customer",
      role: "customer",
    };
    if (typeof window !== "undefined") {
      window.sessionStorage.setItem("nxtgauge_signup_profile_v1", JSON.stringify(payload));
      window.sessionStorage.setItem("nxtgauge_auth_user", JSON.stringify(payload));
      window.sessionStorage.setItem("nxtgauge_user", JSON.stringify(payload));
    }
  };

  const register = async () => {
    setServerError("");
    
    // Custom validation for customer
    const validationErrors: Record<string, string> = {};
    
    if (!firstName().trim()) {
      validationErrors.firstName = "First name is required";
    }
    if (!lastName().trim()) {
      validationErrors.lastName = "Last name is required";
    }
    if (!email().trim() || !isValidEmail(email())) {
      validationErrors.email = "Enter a valid email format";
    }
    const checks = checkPasswordStrength(password(), confirmPassword());
    if (!isPasswordStrong(checks)) {
      validationErrors.password = "Password must be strong";
    }
    if (!isValidCaptcha(captcha())) {
      validationErrors.captcha = "Enter captcha to continue";
    }

    setErrors(validationErrors);
    if (Object.keys(validationErrors).length > 0) return;

    setSubmitting(true);
    try {
      const res = await fetch("/api/auth/register", {
        method: "POST",
        headers: { "Content-Type": "application/json", Accept: "application/json" },
        credentials: "include",
        body: JSON.stringify({
          first_name: firstName().trim(),
          last_name: lastName().trim(),
          email: email().trim().toLowerCase(),
          password: password(),
          phone: "",
          intent: "customer",
          role_key: "CUSTOMER",
          captcha_id: captchaId(),
          captcha_answer: captcha().trim(),
        }),
      });

      const data = await res.json().catch(() => ({}));
      if (!res.ok) {
        const code = String(data?.code || "").toUpperCase();
        if (code === "CAPTCHA_FAILED") {
          setServerError(String(data?.error || "Invalid or expired captcha. Please try again."));
          void refreshCaptcha();
          return;
        }
        setServerError(String(data?.error || data?.message || "Unable to create account."));
        void refreshCaptcha();
        return;
      }

      const cleanEmail = email().trim().toLowerCase();
      setPendingEmail(cleanEmail);
      setVerifiedSuccess(false);
      saveUserForDashboard({
        firstName: firstName().trim(),
        lastName: lastName().trim(),
        email: cleanEmail,
      });
      setStep("verify");
    } catch (err) {
      setServerError("Network error — please check your connection and try again.");
      void refreshCaptcha();
    } 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/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;
      }
      setVerifiedSuccess(true);
      // Auto-login after verification
      const loginRes = await fetch("/api/auth/login", {
        method: "POST",
        headers: { "Content-Type": "application/json", Accept: "application/json" },
        credentials: "include",
        body: JSON.stringify({
          email: pendingEmail() || email().trim().toLowerCase(),
          password: password(),
        }),
      });
      const loginData = await loginRes.json().catch(() => ({}));
      if (loginRes.ok && loginData?.access_token) {
        if (typeof window !== "undefined") {
          window.sessionStorage.setItem("nxtgauge_access_token", loginData.access_token);
        }
      }
      setTimeout(() => navigate("/dashboard?role=CUSTOMER", { replace: true }), 1400);
    } catch (err) {
      setServerError("Network error — please try again.");
    } finally {
      setSubmitting(false);
    }
  };

  const resendOtp = async () => {
    setServerError("");
    setSubmitting(true);
    try {
      const res = await fetch("/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."));
      }
    } catch (err) {
      setServerError("Network error — please try again.");
    } 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="Customer Registration" />
          <div class="auth-visual-overlay" />
          <div class="auth-visual-content">
            <p class="eyebrow">Customer Registration</p>
            <h1 class="title light">Hire Verified Professionals</h1>
            <p class="subtitle light">
              Post requirements and connect with trusted specialists.
            </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>

                <Show
                  when={!verifiedSuccess()}
                  fallback={
                    <div
                      style={{
                        "margin-top": "12px",
                        "border-radius": "12px",
                        border: "1px solid #FED7AA",
                        background: "#FFF7ED",
                        padding: "14px 16px",
                        color: "#C2410C",
                        "text-align": "center",
                      }}
                    >
                      <div style={{ "font-size": "30px", "line-height": "1" }}>✓</div>
                      <p style={{ margin: "8px 0 0", "font-weight": "700", "font-size": "14px" }}>
                        Your email has been verified.
                      </p>
                      <p style={{ margin: "6px 0 0", "font-size": "13px" }}>
                        Redirecting to dashboard...
                      </p>
                    </div>
                  }
                >
                  <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>
                </Show>
              </>
            }
          >
            <h2 class="title">Create Customer Account</h2>
            <p class="subtitle">
              Register to post requirements and hire verified professionals.
            </p>

            <div class="grid" style={{ "grid-template-columns": "1fr 1fr", margin: 0 }}>
              <div class="field">
                <label class="label" for="first-name">FIRST NAME</label>
                <input
                  id="first-name"
                  class="input"
                  value={firstName()}
                  onInput={(e) => setFirstName(e.currentTarget.value)}
                  placeholder="John"
                />
                <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)}
                  placeholder="Doe"
                />
                <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())}
                placeholder="john.doe@example.com"
              />
              <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"
                    aria-label={showPassword() ? "Hide password" : "Show password"}
                    onClick={() => setShowPassword((s) => !s)}
                  >
                    <svg viewBox="0 0 24 24" aria-hidden="true">
                      {showPassword() ? (
                        <>
                          <path d="M3 3l18 18" />
                          <path d="M10.58 10.58a2 2 0 0 0 2.83 2.83" />
                        </>
                      ) : (
                        <>
                          <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>
                  </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"
                    aria-label={showConfirmPassword() ? "Hide password" : "Show password"}
                    onClick={() => setShowConfirmPassword((s) => !s)}
                  >
                    <svg viewBox="0 0 24 24" aria-hidden="true">
                      {showConfirmPassword() ? (
                        <>
                          <path d="M3 3l18 18" />
                          <path d="M10.58 10.58a2 2 0 0 0 2.83 2.83" />
                        </>
                      ) : (
                        <>
                          <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>
                  </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"
                  aria-label="Refresh captcha"
                  onClick={() => void refreshCaptcha()}
                >
                  ↻
                </button>
                <CaptchaCanvas challenge={captchaChallenge()} class="auth-captcha-canvas" />
                <input
                  id="captcha"
                  class="input"
                  value={captcha()}
                  onInput={(e) => setCaptcha(e.currentTarget.value)}
                  placeholder="Enter answer"
                />
              </div>
              <p
                class="validation-note"
                style={{
                  color: isValidCaptcha(captcha()) ? "#fd6116" : "#6e7591",
                }}
              >
                {isValidCaptcha(captcha())
                  ? "✓ Answer entered"
                  : "• Enter captcha to continue"}
              </p>
            </div>

            <Show when={serverError()}>
              <p class="error">{serverError()}</p>
            </Show>

            <button
              class="auth-submit-btn"
              type="button"
              disabled={submitting() || !canSubmit()}
              onClick={() => void register()}
            >
              {submitting() ? "Creating Account..." : "Create Customer Account"}
            </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>
        </section>
      </div>
    </main>
  );
}
