import { useCallback, useEffect, useRef, useState, type FormEvent } from 'react';
import type { Locale } from '../../data/site';
import type { LeadFormInitialValues } from '../../data/lead-form';
import { reportGadsConversion } from '../../lib/analytics/report-conversion';
import { localizedPath } from '../../i18n/utils';

type Option = { slug: string; label: string; description?: string };

type Labels = {
  stepService: string;
  stepProfession: string;
  stepPreferences: string;
  stepContact: string;
  back: string;
  continue: string;
  submitRequest: string;
  selectService: string;
  selectProfession: string;
  nationality: string;
  religion: string;
  previousExperience: string;
  name: string;
  email: string;
  phone: string;
  message: string;
  optional: string;
  required: string;
  specifyReligion: string;
  submitting: string;
  requestError: string;
  captchaRequired: string;
};

type FormState = {
  serviceCategory: string;
  profession: string;
  nationality: string;
  religion: string;
  religionOther: string;
  experience: string;
  name: string;
  email: string;
  phone: string;
  message: string;
  website: string;
};

type Props = {
  locale: Locale;
  labels: Labels;
  serviceOptions: Option[];
  professionOptions: Option[];
  nationalityOptions: Option[];
  religionOptions: Option[];
  experienceOptions: Option[];
  initialValues?: LeadFormInitialValues;
  turnstileSiteKey: string;
};

const STEPS = ['service', 'profession', 'preferences', 'contact'] as const;
type Step = (typeof STEPS)[number];

const SERVICE_ICONS: Record<string, string> = {
  recruitment: 'M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z',
  'one-time-wage': 'M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
  rent: 'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6',
};

const PROFESSION_ICONS: Record<string, string> = {
  'domestic-worker': 'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6',
  nanny: 'M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
  'private-driver': 'M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4',
  caregiver: 'M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z',
};

function Spinner() {
  return (
    <span
      className="inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"
      aria-hidden="true"
    />
  );
}

function StepIcon({ path }: { path: string }) {
  return (
    <svg className="h-7 w-7" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d={path} />
    </svg>
  );
}

const tagPickerClass = (selected: boolean) =>
  `cursor-pointer rounded-full border-2 px-4 py-2.5 text-sm font-medium transition-all duration-200 ${
    selected
      ? 'border-primary bg-primary text-primary-content shadow-sm'
      : 'border-base-300 bg-base-100 text-base-content/70 hover:border-primary/40 hover:bg-primary/5'
  }`;

function TagPicker({
  options,
  value,
  onChange,
  groupLabel,
}: {
  options: Option[];
  value: string;
  onChange: (slug: string) => void;
  groupLabel: string;
}) {
  return (
    <div className="flex flex-wrap gap-2" role="radiogroup" aria-label={groupLabel}>
      {options.map((option) => {
        const selected = value === option.slug;
        return (
          <button
            key={option.slug}
            type="button"
            role="radio"
            aria-checked={selected}
            onClick={() => onChange(option.slug)}
            className={tagPickerClass(selected)}
          >
            {option.label}
          </button>
        );
      })}
    </div>
  );
}

declare global {
  interface Window {
    turnstile?: {
      render: (container: HTMLElement, options: Record<string, unknown>) => string;
      remove: (widgetId: string) => void;
    };
  }
}

const TURNSTILE_SCRIPT_SRC = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
let turnstileScriptPromise: Promise<void> | null = null;

function loadTurnstileScript(): Promise<void> {
  if (window.turnstile) return Promise.resolve();
  if (turnstileScriptPromise) return turnstileScriptPromise;

  turnstileScriptPromise = new Promise((resolve) => {
    const existing = document.querySelector(`script[src="${TURNSTILE_SCRIPT_SRC}"]`);
    if (existing) {
      existing.addEventListener('load', () => resolve(), { once: true });
      return;
    }
    const script = document.createElement('script');
    script.src = TURNSTILE_SCRIPT_SRC;
    script.async = true;
    script.defer = true;
    script.addEventListener('load', () => resolve(), { once: true });
    document.head.appendChild(script);
  });

  return turnstileScriptPromise;
}

function TurnstileWidget({
  siteKey,
  locale,
  onVerify,
  onExpire,
}: {
  siteKey: string;
  locale: Locale;
  onVerify: (token: string) => void;
  onExpire: () => void;
}) {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let cancelled = false;
    let widgetId: string | null = null;

    loadTurnstileScript().then(() => {
      if (cancelled || !containerRef.current || !window.turnstile) return;
      widgetId = window.turnstile.render(containerRef.current, {
        sitekey: siteKey,
        language: locale,
        callback: onVerify,
        'expired-callback': onExpire,
        'error-callback': onExpire,
      });
    });

    return () => {
      cancelled = true;
      if (widgetId && window.turnstile) {
        window.turnstile.remove(widgetId);
      }
    };
  }, [siteKey, locale, onVerify, onExpire]);

  return <div ref={containerRef} />;
}

export default function ServiceLeadForm({
  locale,
  labels,
  serviceOptions,
  professionOptions,
  nationalityOptions,
  religionOptions,
  experienceOptions,
  initialValues,
  turnstileSiteKey,
}: Props) {
  const [step, setStep] = useState<Step>('service');
  const [loading, setLoading] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [turnstileToken, setTurnstileToken] = useState('');
  const [turnstileKey, setTurnstileKey] = useState(0);
  const stepRef = useRef<HTMLDivElement>(null);

  const handleTurnstileVerify = useCallback((token: string) => {
    setTurnstileToken(token);
  }, []);

  const handleTurnstileExpire = useCallback(() => {
    setTurnstileToken('');
  }, []);

  const [form, setForm] = useState<FormState>({
    serviceCategory: initialValues?.serviceCategory ?? '',
    profession: initialValues?.profession ?? '',
    nationality: initialValues?.nationality ?? '',
    religion: '',
    religionOther: '',
    experience: '',
    name: '',
    email: '',
    phone: '',
    message: initialValues?.message ?? '',
    website: '',
  });

  const stepIndex = STEPS.indexOf(step);
  const stepLabels = [labels.stepService, labels.stepProfession, labels.stepPreferences, labels.stepContact];

  const updateField = useCallback(<K extends keyof FormState>(key: K, value: FormState[K]) => {
    setForm((prev) => ({ ...prev, [key]: value }));
    setErrors((prev) => {
      const next = { ...prev };
      delete next[key];
      delete next._form;
      return next;
    });
  }, []);

  function validateStep(current: Step): boolean {
    const stepErrors: Record<string, string> = {};

    if (current === 'service' && !form.serviceCategory) {
      stepErrors.serviceCategory = labels.selectService;
    }
    if (current === 'profession' && !form.profession) {
      stepErrors.profession = labels.selectProfession;
    }
    if (current === 'preferences') {
      if (!form.nationality) stepErrors.nationality = labels.nationality;
      if (!form.religion) stepErrors.religion = labels.religion;
      if (form.religion === 'other' && !form.religionOther.trim()) {
        stepErrors.religionOther = labels.specifyReligion;
      }
      if (!form.experience) stepErrors.experience = labels.previousExperience;
    }
    if (current === 'contact') {
      if (!form.name.trim()) stepErrors.name = labels.name;
      if (!form.phone.trim()) stepErrors.phone = labels.phone;
    }

    setErrors(stepErrors);
    return Object.keys(stepErrors).length === 0;
  }

  function goToStep(next: Step) {
    setStep(next);
    stepRef.current?.focus();
  }

  function handleNext() {
    if (!validateStep(step)) return;
    const nextIndex = stepIndex + 1;
    if (nextIndex < STEPS.length) {
      goToStep(STEPS[nextIndex]);
    }
  }

  function handleBack() {
    const prevIndex = stepIndex - 1;
    if (prevIndex >= 0) {
      goToStep(STEPS[prevIndex]);
    }
  }

  function resetTurnstile() {
    setTurnstileToken('');
    setTurnstileKey((key) => key + 1);
  }

  async function handleSubmit(event: FormEvent) {
    event.preventDefault();
    if (!validateStep('contact')) return;

    if (!turnstileToken) {
      setErrors({ _form: labels.captchaRequired });
      return;
    }

    setLoading(true);
    setErrors({});

    try {
      const response = await fetch('/api/leads', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          locale,
          serviceCategory: form.serviceCategory,
          profession: form.profession,
          nationality: form.nationality,
          religion: form.religion,
          religionOther: form.religionOther || undefined,
          experience: form.experience,
          name: form.name,
          email: form.email || undefined,
          phone: form.phone,
          message: form.message || undefined,
          website: form.website,
          turnstileToken,
        }),
      });

      const data = await response.json();

      if (!response.ok || !data.ok) {
        setErrors(data.errors ?? { _form: labels.requestError });
        setLoading(false);
        resetTurnstile();
        return;
      }

      reportGadsConversion('leadForm', () => {
        window.location.href = localizedPath(locale, 'request/success');
      });
    } catch {
      setErrors({ _form: labels.requestError });
      setLoading(false);
      resetTurnstile();
    }
  }

  const inputClass =
    'input w-full cursor-pointer border-base-300 bg-base-100 focus:border-primary focus:outline-none';

  return (
    <div className="card card-border bg-base-100 shadow-lg">
      <div className="card-body gap-8 p-6 md:p-10">
        {/* Progress stepper */}
        <nav aria-label="Form progress" className="relative w-full">
          <div
            className="absolute top-[18px] right-[12.5%] left-[12.5%] h-0.5 bg-base-300"
            aria-hidden="true"
          >
            <div
              className="h-full bg-secondary transition-all duration-300"
              style={{
                width: stepIndex === 0 ? '0%' : `${(stepIndex / (stepLabels.length - 1)) * 100}%`,
              }}
            />
          </div>
          <ol className="relative grid w-full grid-cols-4">
            {stepLabels.map((label, i) => {
              const isActive = i === stepIndex;
              const isComplete = i < stepIndex;
              return (
                <li key={label} className="flex flex-col items-center gap-2">
                  <div
                    className={`relative z-10 flex h-9 w-9 shrink-0 items-center justify-center rounded-full text-sm font-semibold transition-all duration-300 ${
                      isActive
                        ? 'bg-secondary text-secondary-content shadow-md scale-110'
                        : isComplete
                          ? 'bg-primary text-primary-content'
                          : 'bg-base-200 text-base-content/40'
                    }`}
                    aria-current={isActive ? 'step' : undefined}
                  >
                    {isComplete ? (
                      <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M5 13l4 4L19 7" />
                      </svg>
                    ) : (
                      <span>{i + 1}</span>
                    )}
                  </div>
                  <span
                    className={`hidden w-full px-1 text-center text-xs font-medium leading-tight sm:block ${isActive ? 'text-primary' : 'text-base-content/50'}`}
                  >
                    {label}
                  </span>
                </li>
              );
            })}
          </ol>
        </nav>

        {/* Step content */}
        <div
          ref={stepRef}
          tabIndex={-1}
          className="min-h-[320px] transition-opacity duration-300 animate-fade-up"
          aria-live="polite"
        >
          {step === 'service' && (
            <div>
              <h2 className="mb-1 text-xl font-bold text-primary">{labels.selectService}</h2>
              <p className="mb-6 text-sm text-base-content/60">{labels.stepService}</p>
              <div className="grid gap-3 sm:grid-cols-3">
                {serviceOptions.map((option) => {
                  const selected = form.serviceCategory === option.slug;
                  return (
                    <button
                      key={option.slug}
                      type="button"
                      onClick={() => updateField('serviceCategory', option.slug)}
                      className={`group flex cursor-pointer flex-col items-start gap-3 rounded-xl border-2 p-5 text-start transition-all duration-200 hover:shadow-md ${
                        selected
                          ? 'border-primary bg-primary/5 shadow-md'
                          : 'border-base-300 bg-base-100 hover:border-primary/30'
                      }`}
                      aria-pressed={selected}
                    >
                      <span className={`transition-colors ${selected ? 'text-primary' : 'text-base-content/40 group-hover:text-primary/60'}`}>
                        <StepIcon path={SERVICE_ICONS[option.slug] ?? SERVICE_ICONS.recruitment} />
                      </span>
                      <span className="font-semibold text-base-content">{option.label}</span>
                      {option.description && (
                        <span className="text-xs leading-relaxed text-base-content/60">{option.description}</span>
                      )}
                    </button>
                  );
                })}
              </div>
              {errors.serviceCategory && (
                <p className="mt-3 text-sm text-error" role="alert">{errors.serviceCategory}</p>
              )}
            </div>
          )}

          {step === 'profession' && (
            <div>
              <h2 className="mb-1 text-xl font-bold text-primary">{labels.selectProfession}</h2>
              <p className="mb-6 text-sm text-base-content/60">{labels.stepProfession}</p>
              <div className="grid gap-3 sm:grid-cols-2">
                {professionOptions.map((option) => {
                  const selected = form.profession === option.slug;
                  return (
                    <button
                      key={option.slug}
                      type="button"
                      onClick={() => updateField('profession', option.slug)}
                      className={`group flex cursor-pointer items-center gap-4 rounded-xl border-2 p-5 text-start transition-all duration-200 hover:shadow-md ${
                        selected
                          ? 'border-primary bg-primary/5 shadow-md'
                          : 'border-base-300 bg-base-100 hover:border-primary/30'
                      }`}
                      aria-pressed={selected}
                    >
                      <span className={`shrink-0 transition-colors ${selected ? 'text-primary' : 'text-base-content/40 group-hover:text-primary/60'}`}>
                        <StepIcon path={PROFESSION_ICONS[option.slug] ?? PROFESSION_ICONS['domestic-worker']} />
                      </span>
                      <span className="font-semibold text-base-content">{option.label}</span>
                    </button>
                  );
                })}
              </div>
              {errors.profession && (
                <p className="mt-3 text-sm text-error" role="alert">{errors.profession}</p>
              )}
            </div>
          )}

          {step === 'preferences' && (
            <div>
              <h2 className="mb-1 text-xl font-bold text-primary">{labels.stepPreferences}</h2>
              <p className="mb-6 text-sm text-base-content/60">
                {locale === 'ar' ? 'أخبرنا بتفضيلاتك لمساعدتنا في إيجاد الأنسب' : 'Tell us your preferences so we can find the best match'}
              </p>
              <div className="space-y-6">
                <fieldset className="fieldset p-0">
                  <legend className="fieldset-legend mb-3 text-sm font-medium text-primary">
                    {labels.nationality}
                  </legend>
                  <TagPicker
                    options={nationalityOptions}
                    value={form.nationality}
                    onChange={(slug) => updateField('nationality', slug)}
                    groupLabel={labels.nationality}
                  />
                  {errors.nationality && <p className="mt-2 text-sm text-error">{errors.nationality}</p>}
                </fieldset>

                <fieldset className="fieldset p-0">
                  <legend className="fieldset-legend mb-3 text-sm font-medium text-primary">
                    {labels.religion}
                  </legend>
                  <TagPicker
                    options={religionOptions}
                    value={form.religion}
                    onChange={(slug) => updateField('religion', slug)}
                    groupLabel={labels.religion}
                  />
                  {errors.religion && <p className="mt-2 text-sm text-error">{errors.religion}</p>}
                </fieldset>

                {form.religion === 'other' && (
                  <label className="form-control w-full">
                    <span className="label-text mb-2 font-medium">{labels.specifyReligion}</span>
                    <input
                      type="text"
                      className={inputClass}
                      value={form.religionOther}
                      onChange={(e) => updateField('religionOther', e.target.value)}
                    />
                    {errors.religionOther && <span className="mt-1 text-sm text-error">{errors.religionOther}</span>}
                  </label>
                )}

                <fieldset className="fieldset p-0">
                  <legend className="fieldset-legend mb-3 text-sm font-medium text-primary">
                    {labels.previousExperience}
                  </legend>
                  <TagPicker
                    options={experienceOptions}
                    value={form.experience}
                    onChange={(slug) => updateField('experience', slug)}
                    groupLabel={labels.previousExperience}
                  />
                  {errors.experience && <p className="mt-2 text-sm text-error">{errors.experience}</p>}
                </fieldset>
              </div>
            </div>
          )}

          {step === 'contact' && (
            <form onSubmit={handleSubmit} noValidate>
              <h2 className="mb-1 text-xl font-bold text-primary">{labels.stepContact}</h2>
              <p className="mb-6 text-sm text-base-content/60">
                {locale === 'ar' ? 'كيف يمكننا التواصل معك؟' : 'How can we reach you?'}
              </p>

              {/* Honeypot */}
              <input
                type="text"
                name="website"
                value={form.website}
                onChange={(e) => updateField('website', e.target.value)}
                className="absolute left-[-9999px] h-0 w-0 opacity-0"
                tabIndex={-1}
                autoComplete="off"
                aria-hidden="true"
              />

              <div className="grid gap-5 sm:grid-cols-2">
                <label className="form-control w-full">
                  <span className="label-text mb-2 font-medium">
                    {labels.name} <span className="text-error">*</span>
                  </span>
                  <input
                    type="text"
                    className={inputClass}
                    value={form.name}
                    onChange={(e) => updateField('name', e.target.value)}
                    autoComplete="name"
                    required
                    disabled={loading}
                  />
                  {errors.name && <span className="mt-1 text-sm text-error">{errors.name}</span>}
                </label>

                <label className="form-control w-full">
                  <span className="label-text mb-2 font-medium">
                    {labels.phone} <span className="text-error">*</span>
                  </span>
                  <input
                    type="tel"
                    className={`${inputClass} text-ltr`}
                    dir="ltr"
                    value={form.phone}
                    onChange={(e) => updateField('phone', e.target.value)}
                    autoComplete="tel"
                    placeholder="05XXXXXXXX"
                    required
                    disabled={loading}
                  />
                  {errors.phone && <span className="mt-1 text-sm text-error">{errors.phone}</span>}
                </label>

                <label className="form-control w-full sm:col-span-2">
                  <span className="label-text mb-2 font-medium">
                    {labels.email}{' '}
                    <span className="text-base-content/40 font-normal">({labels.optional})</span>
                  </span>
                  <input
                    type="email"
                    className={`${inputClass} text-ltr`}
                    dir="ltr"
                    value={form.email}
                    onChange={(e) => updateField('email', e.target.value)}
                    autoComplete="email"
                    placeholder="name@example.com"
                    disabled={loading}
                  />
                  {errors.email && <span className="mt-1 text-sm text-error">{errors.email}</span>}
                </label>

                <label className="form-control w-full sm:col-span-2">
                  <span className="label-text mb-2 font-medium">
                    {labels.message}{' '}
                    <span className="text-base-content/40 font-normal">({labels.optional})</span>
                  </span>
                  <textarea
                    className="textarea w-full min-h-28 cursor-pointer border-base-300 bg-base-100 focus:border-primary focus:outline-none"
                    value={form.message}
                    onChange={(e) => updateField('message', e.target.value)}
                    disabled={loading}
                  />
                  {errors.message && <span className="mt-1 text-sm text-error">{errors.message}</span>}
                </label>
              </div>

              {turnstileSiteKey && (
                <div className="mt-6 flex justify-center">
                  <TurnstileWidget
                    key={turnstileKey}
                    siteKey={turnstileSiteKey}
                    locale={locale}
                    onVerify={handleTurnstileVerify}
                    onExpire={handleTurnstileExpire}
                  />
                </div>
              )}

              {errors._form && (
                <div className="mt-4 rounded-xl border border-error/20 bg-error/5 px-4 py-3 text-sm text-error" role="alert">
                  {errors._form}
                </div>
              )}

              <div className="mt-8 flex flex-wrap items-center justify-between gap-3">
                <button type="button" className="btn btn-ghost cursor-pointer" onClick={handleBack} disabled={loading}>
                  {labels.back}
                </button>
                <button type="submit" className="btn btn-primary btn-lg min-w-40 cursor-pointer font-semibold" disabled={loading}>
                  {loading ? (
                    <span className="inline-flex items-center gap-2">
                      <Spinner />
                      {labels.submitting}
                    </span>
                  ) : (
                    labels.submitRequest
                  )}
                </button>
              </div>
            </form>
          )}
        </div>

        {/* Navigation for steps 1-3 */}
        {step !== 'contact' && (
          <div className="flex flex-wrap items-center justify-between gap-3 border-t border-base-300 pt-6">
            <button
              type="button"
              className="btn btn-ghost cursor-pointer"
              onClick={handleBack}
              disabled={stepIndex === 0}
            >
              {labels.back}
            </button>
            <button type="button" className="btn btn-primary btn-lg min-w-40 cursor-pointer font-semibold" onClick={handleNext}>
              {labels.continue}
            </button>
          </div>
        )}
      </div>
    </div>
  );
}
