<script lang="ts">
  import { onMount } from 'svelte';
  import { fade } from 'svelte/transition';
  import Icon from '$lib/components/Icon.svelte';
  import { reveal } from '$lib/actions/reveal';
  import type { BookingContent } from '$lib/types';
  import { promoteJourney, trackEvent } from '$lib/analytics';
  import { trackAb, type AbContext } from '$lib/ab';

  type SuccessModalComponentType = typeof import('$lib/components/SuccessModal.svelte').default;
  type ErrorModalComponentType = typeof import('$lib/components/ErrorModal.svelte').default;

  export let booking: BookingContent;
  export let pagePath = '';
  export let ab: AbContext | undefined = undefined;
  $: isCompactContactPage = pagePath === '/contact-us';

  const defaultServices = ['Tiny Gang Pack Walks', 'Solo Walks', 'Puppy Visits', 'Other Services'];
  $: serviceOptions = booking.serviceOptions && booking.serviceOptions.length > 0
    ? booking.serviceOptions
    : defaultServices;

  const serviceDescriptions: Record<string, string> = {
    'Tiny Gang Pack Walks': 'Small-group dog walks for sociable dogs.',
    'Solo Walks': 'One-on-one dog walking, your dog\'s pace.',
    'Puppy Visits': 'In-home visits while you are at work.',
    'Other Services': 'Something else? Tell us in the notes.'
  };

  const pathToService: Record<string, string> = {
    '/pack-walks': 'Tiny Gang Pack Walks',
    '/dog-walking': 'Solo Walks',
    '/puppy-visits': 'Puppy Visits'
  };

  const avatarDogs = [
    { image: '/images/archie-goodwalk-dog-walking-review-auckland.webp', alt: 'Archie' },
    { image: '/images/monty-goodwalk-dog-walking-review-auckland.webp', alt: 'Monty' },
    { image: '/images/otis-goodwalk-dog-walking-review-auckland.webp', alt: 'Otis' }
  ];

  const visitStartedStorageKey = 'goodwalk_visit_started_at';
  const journeyStorageKey = 'goodwalk_journey';
  const maxJourneyEntries = 8;

  let step = 1;
  let petName = '';
  let location = '';
  let message = '';
  let fullName = '';
  let email = '';
  let phone = '';
  let selectedServices: string[] = [];
  let website = '';

  let formStartedAt = 0;
  let visitStartedAt = 0;
  let pageEnteredAt = 0;
  let firstInteractionAt = 0;
  let sendClickedAt = 0;
  let stepChanges = 0;
  let journey: string[] = [];
  let trackedFormStart = false;

  let errors: Record<string, string> = {};
  let submitting = false;
  let submitted = false;
  let showErrorModal = false;
  let submitErrorDetail = '';

  let SuccessModalComponent: SuccessModalComponentType | null = null;
  let ErrorModalComponent: ErrorModalComponentType | null = null;

  $: headingParts = splitTitle(booking.title || "Let's meet!");
  $: leadCopy = booking.subtitle && booking.subtitle.trim()
    ? booking.subtitle
    : 'Start with a few details about your dog. We will come back within 24 hours with the right next step.';
  $: trustTitle = petName.trim()
    ? `${capitalizeFirst(petName.trim())} could be a great fit for Goodwalk.`
    : 'Trusted by Goodwalk dog owners across Auckland.';
  $: trustNote = selectedServices.length === 1
    ? `${selectedServices[0]}, planned around your dog rather than a generic routine.`
    : 'Tell us a little about your dog and we will help you find the right fit.';

  $: if (submitted) ensureSuccessModal();
  $: if (showErrorModal) ensureErrorModal();

  onMount(() => {
    const now = Date.now();
    formStartedAt = now;
    pageEnteredAt = now;
    visitStartedAt = readOrCreateVisitStartedAt(now);
    journey = updateJourneySnapshot(window.location.pathname, window.location.search);

    const path = pagePath || window.location.pathname;
    const preset = pathToService[path];
    if (preset && serviceOptions.includes(preset) && selectedServices.length === 0) {
      selectedServices = [preset];
    }

    const handleRequestedService = (event: Event) => {
      const detail = (event as CustomEvent<{ service?: string }>).detail;
      const service = detail?.service?.trim();
      if (service && serviceOptions.includes(service) && !selectedServices.includes(service)) {
        selectedServices = [...selectedServices, service];
      }
    };

    window.addEventListener('goodwalk:service-selected', handleRequestedService as EventListener);
    return () => {
      window.removeEventListener('goodwalk:service-selected', handleRequestedService as EventListener);
    };
  });

  function splitTitle(title: string) {
    const trimmed = title.trim();
    const lastSpace = trimmed.lastIndexOf(' ');
    if (lastSpace === -1) return { plain: trimmed, highlight: '' };
    return {
      plain: trimmed.slice(0, lastSpace),
      highlight: trimmed.slice(lastSpace + 1)
    };
  }

  function capitalizeFirst(value: string) {
    if (!value) return value;
    return value.charAt(0).toLocaleUpperCase() + value.slice(1);
  }

  function readOrCreateVisitStartedAt(fallback: number) {
    try {
      const raw = window.sessionStorage.getItem(visitStartedStorageKey);
      const parsed = raw ? Number(raw) : NaN;
      if (Number.isFinite(parsed) && parsed > 0) return parsed;
      window.sessionStorage.setItem(visitStartedStorageKey, String(fallback));
    } catch {
      return fallback;
    }
    return fallback;
  }

  function updateJourneySnapshot(pathname: string, search: string) {
    const nextEntry = `${pathname}${search}`;
    try {
      const raw = window.sessionStorage.getItem(journeyStorageKey);
      const previous = raw ? (JSON.parse(raw) as string[]) : [];
      const cleaned = previous.filter((value) => typeof value === 'string' && value.trim());
      const deduped = cleaned[cleaned.length - 1] === nextEntry ? cleaned : [...cleaned, nextEntry];
      const nextJourney = deduped.slice(-maxJourneyEntries);
      window.sessionStorage.setItem(journeyStorageKey, JSON.stringify(nextJourney));
      return nextJourney;
    } catch {
      return [nextEntry];
    }
  }

  async function ensureSuccessModal() {
    if (SuccessModalComponent) return;
    SuccessModalComponent = (await import('$lib/components/SuccessModal.svelte')).default;
  }

  async function ensureErrorModal() {
    if (ErrorModalComponent) return;
    ErrorModalComponent = (await import('$lib/components/ErrorModal.svelte')).default;
  }

  function noteInteraction() {
    if (!firstInteractionAt) firstInteractionAt = Date.now();
    if (!trackedFormStart) {
      trackedFormStart = true;
      trackEvent('lead_form_start', {
        form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
        step: step,
        page_path: typeof window !== 'undefined' ? window.location.pathname : pagePath || ''
      });
    }
  }

  function clearError(field: string) {
    if (errors[field]) errors = { ...errors, [field]: '' };
  }

  function toggleService(service: string) {
    noteInteraction();
    selectedServices = selectedServices.includes(service)
      ? selectedServices.filter((s) => s !== service)
      : [...selectedServices, service];
    trackEvent('service_interest_select', {
      form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
      selected_service: service,
      selection_state: selectedServices.includes(service) ? 'removed' : 'added',
      step
    });
    clearError('services');
  }

  function validateEmail(raw: string): string {
    const value = raw.trim();
    if (!value) return 'Please enter your email';
    if (!value.includes('@')) return 'Email is missing the @ sign';
    const re = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
    if (!re.test(value)) return "That email doesn't look quite right";
    return '';
  }

  function validateStep(target: number): boolean {
    const next: Record<string, string> = {};
    if (target === 1) {
      if (!petName.trim()) next.petName = "Please tell us your dog's name.";
      if (selectedServices.length === 0) next.services = 'Pick at least one service.';
      if (message.trim().length < 10) {
        next.message = 'Tell us a little about your dog so we can prepare properly.';
      }
    }
    if (target === 2) {
      if (!fullName.trim()) next.fullName = 'Please enter your full name';
      const emailErr = validateEmail(email);
      if (emailErr) next.email = emailErr;
      if (!phone.trim()) next.phone = 'Please enter your phone number';
      if (!location.trim()) next.location = 'Please enter your suburb';
    }
    errors = next;
    return Object.keys(next).length === 0;
  }

  function validateCompactContactForm(): boolean {
    const next: Record<string, string> = {};
    if (!petName.trim()) next.petName = "Please tell us your dog's name.";
    if (selectedServices.length === 0) next.services = 'Pick at least one service.';
    if (message.trim().length < 10) {
      next.message = 'Tell us a little about your dog so we can prepare properly.';
    }
    if (!fullName.trim()) next.fullName = 'Please enter your full name';
    const emailErr = validateEmail(email);
    if (emailErr) next.email = emailErr;
    if (!phone.trim()) next.phone = 'Please enter your phone number';
    if (!location.trim()) next.location = 'Please enter your suburb';
    errors = next;
    return Object.keys(next).length === 0;
  }

  function goNext() {
    noteInteraction();
    if (!validateStep(step)) return;
    trackEvent('lead_form_step_complete', {
      form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
      step,
      next_step: step + 1
    });
    step += 1;
    stepChanges += 1;
  }

  function goBack() {
    noteInteraction();
    if (step > 1) {
      trackEvent('lead_form_step_back', {
        form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
        step,
        previous_step: step - 1
      });
      step -= 1;
      stepChanges += 1;
      errors = {};
    }
  }

  async function handleSubmit() {
    noteInteraction();
    if (isCompactContactPage) {
      if (!validateCompactContactForm()) return;
    } else if (!validateStep(2)) return;

    submitting = true;
    sendClickedAt = Date.now();
    submitErrorDetail = '';
    showErrorModal = false;
    trackEvent('lead_form_submit_attempt', {
      form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
      selected_services: selectedServices.join(' | '),
      step,
      step_changes: stepChanges
    });

    try {
      const res = await fetch('/api/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          enquiryType: 'booking',
          fullName,
          email,
          phone,
          petName,
          location,
          message,
          services: selectedServices,
          website,
          formStartedAt,
          visitStartedAt,
          pageEnteredAt,
          firstInteractionAt,
          sendClickedAt,
          stepChanges,
          journey,
          referrer: typeof document !== 'undefined' ? document.referrer : '',
          page: typeof window !== 'undefined' ? window.location.href : '',
          variant: isCompactContactPage ? 'contact-compact' : 'booking-wizard'
        })
      });

      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        const detail =
          typeof body?.detail === 'string'
            ? body.detail
            : body?.detail?.message ?? body?.message ?? `Server responded with ${res.status}`;
        throw new Error(detail);
      }

      submitted = true;
      trackEvent('lead_form_submit_success', {
        form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
        selected_services: selectedServices.join(' | '),
        step_changes: stepChanges
      });
      // Link the visitor's session_events journey to the submitted email so
      // the owner can review it from the CP dashboard. Without this call,
      // session_events expire after 24h. See docs/server-side-analytics.md.
      promoteJourney(email);
      if (ab) trackAb({ ...ab, event_type: 'conversion', meta: { surface: 'booking_submit' } });
    } catch (err: unknown) {
      submitErrorDetail = err instanceof Error ? err.message : String(err);
      showErrorModal = true;
      trackEvent('lead_form_submit_error', {
        form_name: isCompactContactPage ? 'contact_compact' : 'booking_wizard',
        error_detail: submitErrorDetail.slice(0, 120)
      });
    } finally {
      submitting = false;
    }
  }
</script>

<section id="newlead" use:reveal={{ delay: 70 }} class="wiz reveal-block">
  <div class="wiz-inner" class:wiz-inner--compact={isCompactContactPage}>
    {#if submitted && SuccessModalComponent}
      <svelte:component
        this={SuccessModalComponent}
        firstName={fullName.split(' ')[0]}
        petName={petName.trim() ? capitalizeFirst(petName.trim()) : 'your dog'}
        {email}
        enquiryType="booking"
        onClose={() => (submitted = false)}
      />
    {/if}

    {#if showErrorModal && ErrorModalComponent}
      <svelte:component
        this={ErrorModalComponent}
        detail={submitErrorDetail}
        enquiryType="booking"
        onClose={() => (showErrorModal = false)}
        onRetry={() => (showErrorModal = false)}
      />
    {/if}

    {#if !isCompactContactPage}
      <div class="wiz-header">
        <span class="wiz-eyebrow">Free Meet &amp; Greet</span>
        <h2 class="wiz-title">
          <span class="wiz-title-plain">{headingParts.plain}</span>
          {#if headingParts.highlight}
            {' '}
            <span class="wiz-title-highlight">{headingParts.highlight}</span>
          {/if}
        </h2>
        <p class="wiz-lead">{leadCopy}</p>
      </div>

      <div class="wiz-trust" aria-label="Goodwalk dog families">
        <div class="wiz-avatars" aria-hidden="true">
          {#each avatarDogs as dog}
            <span class="wiz-avatar">
              <img src={dog.image} alt="" loading="lazy" />
            </span>
          {/each}
        </div>
        <div class="wiz-trust-copy">
          <p>{trustTitle}</p>
          <span>{trustNote}</span>
        </div>
      </div>

      <div class="wiz-progress" role="progressbar" aria-valuemin="1" aria-valuemax="2" aria-valuenow={step}>
        <span class="wiz-step-mark" class:active={step >= 1} class:done={step > 1}>
          <span class="wiz-step-num">1</span>
          <span class="wiz-step-label">{booking.dogStepLabel || 'Your dog'}</span>
        </span>
        <span class="wiz-step-line" class:done={step > 1} aria-hidden="true"></span>
        <span class="wiz-step-mark" class:active={step === 2}>
          <span class="wiz-step-num">2</span>
          <span class="wiz-step-label">{booking.ownerStepLabel || 'Your details'}</span>
        </span>
      </div>
    {/if}

    <form
      class="wiz-form"
      novalidate
      on:submit|preventDefault={handleSubmit}
      on:focusin={noteInteraction}
      on:input={noteInteraction}
    >
      <div class="wiz-honeypot" aria-hidden="true">
        <label for="website">Website</label>
        <input
          bind:value={website}
          type="text"
          id="website"
          name="website"
          tabindex="-1"
          autocomplete="new-password"
        />
      </div>

      <article class="wiz-card" class:wiz-card--compact={isCompactContactPage}>
        {#key step}
          <div class="wiz-step" class:wiz-step--compact={isCompactContactPage} in:fade={{ duration: 200 }}>
            {#if isCompactContactPage}
              <span class="wiz-step-eyebrow">Start here</span>
              <h3 class="wiz-step-heading">Tell us about your dog</h3>
              <p class="wiz-step-helper">A few details now. We come back with the right next step.</p>

              <label class="wiz-field">
                <span class="wiz-label">
                  <Icon name="fas fa-dog" />&nbsp;Your dog's name
                </span>
                <input
                  bind:value={petName}
                  on:input={() => clearError('petName')}
                  type="text"
                  placeholder="For example, Teddy"
                  class:invalid={errors.petName}
                  autocomplete="off"
                />
                {#if errors.petName}
                  <span class="wiz-error">
                    <Icon name="fas fa-circle-exclamation" />
                    {errors.petName}
                  </span>
                {/if}
              </label>

              <fieldset class="wiz-fieldset">
                <legend class="wiz-label">
                  <Icon name="fas fa-paw" />&nbsp;Which service are you interested in?
                </legend>
                <div
                  class="wiz-service-grid"
                  class:wiz-service-grid--compact={isCompactContactPage}
                  class:invalid={errors.services}
                  role="group"
                  aria-label="Service interest"
                >
                  {#each serviceOptions as service}
                    {@const checked = selectedServices.includes(service)}
                    <button
                      type="button"
                      class="wiz-service"
                      class:wiz-service--compact={isCompactContactPage}
                      class:active={checked}
                      aria-pressed={checked}
                      on:click={() => toggleService(service)}
                    >
                      <span class="wiz-service-check" aria-hidden="true">
                        {#if checked}<Icon name="fas fa-check" />{/if}
                      </span>
                      <span class="wiz-service-text">
                        <span class="wiz-service-label">{service}</span>
                        {#if serviceDescriptions[service]}
                          <span class="wiz-service-desc">{serviceDescriptions[service]}</span>
                        {/if}
                      </span>
                    </button>
                  {/each}
                </div>
                {#if errors.services}
                  <span class="wiz-error">
                    <Icon name="fas fa-circle-exclamation" />
                    {errors.services}
                  </span>
                {/if}
              </fieldset>

              <div class="wiz-grid-two">
                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-user" />&nbsp;Full name
                  </span>
                  <input
                    bind:value={fullName}
                    on:input={() => clearError('fullName')}
                    type="text"
                    placeholder="Your full name"
                    class:invalid={errors.fullName}
                    autocomplete="name"
                  />
                  {#if errors.fullName}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.fullName}
                    </span>
                  {/if}
                </label>

                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-envelope" />&nbsp;Email
                  </span>
                  <input
                    bind:value={email}
                    on:input={() => clearError('email')}
                    type="email"
                    placeholder="you@example.com"
                    class:invalid={errors.email}
                    autocomplete="email"
                    inputmode="email"
                  />
                  {#if errors.email}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.email}
                    </span>
                  {/if}
                </label>

                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-phone" />&nbsp;Phone
                  </span>
                  <input
                    bind:value={phone}
                    on:input={() => clearError('phone')}
                    type="tel"
                    placeholder="(021) 234 5678"
                    class:invalid={errors.phone}
                    autocomplete="tel"
                    inputmode="tel"
                  />
                  {#if errors.phone}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.phone}
                    </span>
                  {/if}
                </label>

                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-location-dot" />&nbsp;Your suburb
                  </span>
                  <input
                    bind:value={location}
                    on:input={() => clearError('location')}
                    type="text"
                    placeholder="For example, Grey Lynn"
                    class:invalid={errors.location}
                    autocomplete="address-level2"
                  />
                  {#if errors.location}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.location}
                    </span>
                  {/if}
                </label>
              </div>

              <label class="wiz-field">
                <span class="wiz-label">
                  <Icon name="fas fa-comment" />&nbsp;What else should we know?
                </span>
                <textarea
                  bind:value={message}
                  on:input={() => clearError('message')}
                  rows="3"
                  placeholder="Age, breed, temperament around other dogs, any health quirks, anything that helps us prepare."
                  class:invalid={errors.message}
                ></textarea>
                {#if errors.message}
                  <span class="wiz-error">
                    <Icon name="fas fa-circle-exclamation" />
                    {errors.message}
                  </span>
                {/if}
              </label>

              <div class="wiz-actions">
                <button type="submit" class="wiz-btn wiz-btn-primary wiz-btn-primary--wide" disabled={submitting}>
                  {#if submitting}
                    Sending
                  {:else}
                    Send my details
                  {/if}
                  <Icon name="fas fa-paper-plane" />
                </button>
              </div>
            {:else if step === 1}
              <span class="wiz-step-eyebrow">Step one of two</span>
              <h3 class="wiz-step-heading">Tell us about your dog</h3>
              <p class="wiz-step-helper">Just the basics. Pick everything you are open to.</p>

              <label class="wiz-field">
                <span class="wiz-label">
                  <Icon name="fas fa-dog" />&nbsp;Your dog's name
                </span>
                <input
                  bind:value={petName}
                  on:input={() => clearError('petName')}
                  type="text"
                  placeholder="For example, Teddy"
                  class:invalid={errors.petName}
                  autocomplete="off"
                />
                {#if errors.petName}
                  <span class="wiz-error">
                    <Icon name="fas fa-circle-exclamation" />
                    {errors.petName}
                  </span>
                {/if}
              </label>

              <fieldset class="wiz-fieldset">
                <legend class="wiz-label">
                  <Icon name="fas fa-paw" />&nbsp;Which service are you interested in?
                </legend>
                <div
                  class="wiz-service-grid"
                  class:invalid={errors.services}
                  role="group"
                  aria-label="Service interest"
                >
                  {#each serviceOptions as service}
                    {@const checked = selectedServices.includes(service)}
                    <button
                      type="button"
                      class="wiz-service"
                      class:active={checked}
                      aria-pressed={checked}
                      on:click={() => toggleService(service)}
                    >
                      <span class="wiz-service-check" aria-hidden="true">
                        {#if checked}<Icon name="fas fa-check" />{/if}
                      </span>
                      <span class="wiz-service-text">
                        <span class="wiz-service-label">{service}</span>
                        {#if serviceDescriptions[service]}
                          <span class="wiz-service-desc">{serviceDescriptions[service]}</span>
                        {/if}
                      </span>
                    </button>
                  {/each}
                </div>
                {#if errors.services}
                  <span class="wiz-error">
                    <Icon name="fas fa-circle-exclamation" />
                    {errors.services}
                  </span>
                {/if}
              </fieldset>

              <label class="wiz-field">
                <span class="wiz-label">
                  <Icon name="fas fa-comment" />&nbsp;What else should we know?
                </span>
                <textarea
                  bind:value={message}
                  on:input={() => clearError('message')}
                  rows="3"
                  placeholder="Age, breed, temperament around other dogs, any health quirks, anything that helps us prepare."
                  class:invalid={errors.message}
                ></textarea>
                {#if errors.message}
                  <span class="wiz-error">
                    <Icon name="fas fa-circle-exclamation" />
                    {errors.message}
                  </span>
                {/if}
              </label>

              <div class="wiz-actions">
                <button type="button" class="wiz-btn wiz-btn-primary" on:click={goNext}>
                  Continue
                  <Icon name="fas fa-arrow-right" />
                </button>
              </div>
            {:else if step === 2}
              <span class="wiz-step-eyebrow">Step two of two</span>
              <h3 class="wiz-step-heading">How do we reach you?</h3>
              <p class="wiz-step-helper">A real person replies within 24 hours, usually sooner.</p>

              <div class="wiz-grid-two">
                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-user" />&nbsp;Full name
                  </span>
                  <input
                    bind:value={fullName}
                    on:input={() => clearError('fullName')}
                    type="text"
                    placeholder="Your full name"
                    class:invalid={errors.fullName}
                    autocomplete="name"
                  />
                  {#if errors.fullName}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.fullName}
                    </span>
                  {/if}
                </label>

                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-envelope" />&nbsp;Email
                  </span>
                  <input
                    bind:value={email}
                    on:input={() => clearError('email')}
                    type="email"
                    placeholder="you@example.com"
                    class:invalid={errors.email}
                    autocomplete="email"
                    inputmode="email"
                  />
                  {#if errors.email}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.email}
                    </span>
                  {/if}
                </label>

                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-phone" />&nbsp;Phone
                  </span>
                  <input
                    bind:value={phone}
                    on:input={() => clearError('phone')}
                    type="tel"
                    placeholder="(021) 234 5678"
                    class:invalid={errors.phone}
                    autocomplete="tel"
                    inputmode="tel"
                  />
                  {#if errors.phone}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.phone}
                    </span>
                  {/if}
                </label>

                <label class="wiz-field">
                  <span class="wiz-label">
                    <Icon name="fas fa-location-dot" />&nbsp;Your suburb
                  </span>
                  <input
                    bind:value={location}
                    on:input={() => clearError('location')}
                    type="text"
                    placeholder="For example, Grey Lynn"
                    class:invalid={errors.location}
                    autocomplete="address-level2"
                  />
                  {#if errors.location}
                    <span class="wiz-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.location}
                    </span>
                  {/if}
                </label>
              </div>

              <div class="wiz-actions wiz-actions-split">
                <button type="button" class="wiz-btn wiz-btn-back" on:click={goBack}>
                  <Icon name="fas fa-arrow-left" />
                  Back
                </button>
                <button type="submit" class="wiz-btn wiz-btn-primary" disabled={submitting}>
                  {#if submitting}
                    Sending
                  {:else}
                    Send my details
                  {/if}
                  <Icon name="fas fa-paper-plane" />
                </button>
              </div>
            {/if}
          </div>
        {/key}
      </article>
    </form>

    <p class="wiz-reassurance" class:wiz-reassurance--compact={isCompactContactPage} aria-live="polite">
      <Icon name="fas fa-bolt" />
      A real reply within 24 hours, usually sooner.
    </p>
  </div>
</section>

<style>
  :global(#newlead).wiz {
    padding-left: var(--space-container-x);
    padding-right: var(--space-container-x);
    background: transparent;
  }

  .wiz-inner {
    max-width: 56rem;
    margin: 0 auto;
  }

  .wiz-inner--compact {
    max-width: 60rem;
    margin-top: 8px;
  }

  .wiz-header {
    text-align: center;
    margin-bottom: 28px;
  }

  .wiz-eyebrow {
    display: inline-block;
    padding: 8px 16px;
    margin-bottom: 18px;
    border-radius: 999px;
    background: rgba(var(--brand-rgb), 0.08);
    color: var(--text-brand);
    font-family: var(--font-head);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.02em;
  }

  .wiz-title {
    margin: 0 0 32px;
    font-family: var(--font-head);
    font-size: clamp(36px, 5.4vw, 64px);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--text-heading);
  }

  .wiz-title-highlight {
    position: relative;
    display: inline-block;
    color: var(--yellow);
  }

  .wiz-title-highlight::after {
    content: '';
    position: absolute;
    left: 0;
    right: -8px;
    bottom: -18px;
    height: 28px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 34' fill='none'%3E%3Cpath d='M4 24C67 10 131 4 198 5c43 1 82 6 118 18' stroke='%23192419' stroke-width='8' stroke-linecap='round'/%3E%3C/svg%3E")
      center / contain no-repeat;
    pointer-events: none;
  }

  @media (max-width: 640px) {
    .wiz-title-highlight::after {
      left: 12px;
      right: 12px;
      bottom: -14px;
      height: 20px;
    }
  }

  .wiz-lead {
    max-width: 38rem;
    margin: 0 auto;
    color: var(--text-subtle);
    font-size: clamp(15px, 1.4vw, 17px);
    line-height: 1.55;
  }

  .wiz-trust {
    display: flex;
    align-items: center;
    gap: clamp(14px, 2vw, 22px);
    max-width: 44rem;
    margin: 0 auto 32px;
    padding: 14px 18px;
    border-radius: 18px;
    background: rgba(var(--white-rgb), 0.72);
    border: 1px solid rgba(var(--brand-rgb), 0.08);
    box-shadow: 0 14px 32px rgba(var(--ink-rgb), 0.04);
  }

  .wiz-avatars {
    display: inline-flex;
    flex: 0 0 auto;
  }

  .wiz-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    overflow: hidden;
    border: 2px solid rgba(var(--white-rgb), 1);
    box-shadow: 0 4px 10px rgba(var(--ink-rgb), 0.08);
  }

  .wiz-avatar + .wiz-avatar {
    margin-left: -10px;
  }

  .wiz-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }

  .wiz-trust-copy p {
    margin: 0 0 2px;
    font-family: var(--font-head);
    font-weight: 700;
    color: var(--text-heading);
    font-size: 15px;
    line-height: 1.3;
  }

  .wiz-trust-copy span {
    color: var(--text-subtle);
    font-size: 13px;
    line-height: 1.45;
  }

  .wiz-progress {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-bottom: 24px;
  }

  .wiz-step-mark {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px 8px 8px;
    border-radius: 999px;
    background: rgba(var(--brand-rgb), 0.04);
    color: var(--text-subtle);
    font-family: var(--font-head);
    font-size: 13px;
    font-weight: 600;
    transition: background 200ms ease, color 200ms ease;
  }

  .wiz-step-mark.active {
    background: rgba(var(--brand-rgb), 0.1);
    color: var(--text-heading);
  }

  .wiz-step-mark.done {
    background: rgba(var(--accent-rgb), 0.18);
    color: var(--text-heading);
  }

  .wiz-step-num {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(var(--white-rgb), 1);
    color: var(--text-heading);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    box-shadow: inset 0 0 0 1px rgba(var(--brand-rgb), 0.12);
  }

  .wiz-step-mark.active .wiz-step-num {
    background: var(--yellow);
    box-shadow: inset 0 0 0 1px rgba(var(--brand-rgb), 0.18);
  }

  .wiz-step-mark.done .wiz-step-num {
    background: var(--gw-green);
    color: var(--text-inverse);
    box-shadow: none;
  }

  .wiz-step-line {
    flex: 0 0 36px;
    height: 2px;
    border-radius: 2px;
    background: rgba(var(--brand-rgb), 0.12);
  }

  .wiz-step-line.done {
    background: var(--gw-green);
  }

  .wiz-form {
    position: relative;
  }

  .wiz-honeypot {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
  }

  .wiz-card {
    position: relative;
    max-width: 44rem;
    margin: 0 auto;
    padding: clamp(24px, 3.5vw, 36px);
    border-radius: 26px;
    background: rgba(var(--white-rgb), 1);
    border: 1px solid rgba(var(--brand-rgb), 0.08);
    box-shadow: 0 30px 60px rgba(var(--ink-rgb), 0.08);
  }

  .wiz-card--compact {
    max-width: 52rem;
    padding: clamp(22px, 3vw, 32px);
  }

  .wiz-step {
    display: flex;
    flex-direction: column;
    gap: 18px;
  }

  .wiz-step--compact {
    gap: 16px;
  }

  .wiz-step-eyebrow {
    align-self: flex-start;
    padding: 6px 12px;
    border-radius: 999px;
    background: rgba(var(--brand-rgb), 0.06);
    color: var(--text-subtle);
    font-family: var(--font-head);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  .wiz-step-heading {
    margin: 0;
    font-family: var(--font-head);
    font-size: clamp(24px, 3vw, 32px);
    line-height: 1.15;
    letter-spacing: -0.015em;
    color: var(--text-heading);
  }

  .wiz-step-helper {
    margin: 0 0 6px;
    color: var(--text-subtle);
    font-size: 15px;
    line-height: 1.5;
  }

  .wiz-field {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }

  .wiz-label {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 14px;
    color: var(--text-heading);
  }

  .wiz-field input,
  .wiz-field textarea {
    width: 100%;
    padding: 13px 14px;
    border-radius: 14px;
    border: 1px solid rgba(var(--brand-rgb), 0.14);
    background: rgba(var(--white-rgb), 1);
    font-family: var(--font-body);
    font-size: 15px;
    color: var(--text-heading);
    transition: border-color 180ms ease, box-shadow 180ms ease;
  }

  .wiz-field textarea {
    resize: vertical;
    min-height: 88px;
    line-height: 1.5;
  }

  .wiz-field input:focus,
  .wiz-field textarea:focus {
    outline: none;
    border-color: var(--gw-green);
    box-shadow: 0 0 0 4px rgba(var(--brand-rgb), 0.12);
  }

  .wiz-field input.invalid,
  .wiz-field textarea.invalid {
    border-color: oklch(0.55 0.18 27);
    background: oklch(0.985 0.012 27);
  }

  .wiz-error {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: oklch(0.5 0.18 27);
    font-size: 13px;
    font-weight: 500;
  }

  .wiz-fieldset {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0;
    padding: 0;
    border: none;
  }

  .wiz-service-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }

  .wiz-service-grid.invalid {
    outline: 1px solid oklch(0.55 0.18 27);
    outline-offset: 4px;
    border-radius: 18px;
  }

  .wiz-service {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 16px;
    border-radius: 16px;
    border: 1.5px solid rgba(var(--brand-rgb), 0.12);
    background: rgba(var(--white-rgb), 1);
    text-align: left;
    cursor: pointer;
    transition: border-color 180ms ease, background 180ms ease, transform 180ms ease;
  }

  .wiz-service-text {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
  }

  .wiz-service-desc {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 13px;
    line-height: 1.4;
    color: var(--text-subtle);
  }

  .wiz-service.active .wiz-service-desc {
    color: var(--text-heading);
  }

  .wiz-service:hover {
    border-color: rgba(var(--brand-rgb), 0.32);
  }

  .wiz-service--compact {
    padding: 12px 14px;
  }

  .wiz-service.active {
    border-color: var(--gw-green);
    background: rgba(var(--accent-rgb), 0.1);
  }

  .wiz-service-check {
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
    border-radius: 6px;
    border: 1.5px solid rgba(var(--brand-rgb), 0.32);
    background: rgba(var(--white-rgb), 1);
    color: var(--text-heading);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    transition: background 180ms ease, border-color 180ms ease;
  }

  .wiz-service.active .wiz-service-check {
    background: var(--yellow);
    border-color: var(--gw-green);
  }

  .wiz-service-label {
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 15px;
    color: var(--text-heading);
    line-height: 1.25;
  }

  .wiz-grid-two {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
  }

  .wiz-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 6px;
  }

  .wiz-actions-split {
    justify-content: space-between;
  }

  .wiz-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 13px 22px;
    border-radius: 999px;
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 15px;
    border: 1.5px solid transparent;
    cursor: pointer;
    transition: transform 180ms ease, background 180ms ease, border-color 180ms ease, color 180ms ease;
  }

  .wiz-btn:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .wiz-btn-primary {
    background: var(--yellow);
    color: var(--text-heading);
    border-color: var(--yellow);
    box-shadow: 0 10px 22px rgba(255, 209, 0, 0.32);
  }

  .wiz-btn-primary:hover:not(:disabled) {
    transform: translateY(-1px);
    background: oklch(0.88 0.18 95);
  }

  .wiz-btn-primary--wide {
    width: 100%;
    justify-content: center;
  }

  .wiz-btn-back {
    background: transparent;
    color: var(--text-subtle);
    border-color: rgba(var(--brand-rgb), 0.18);
  }

  .wiz-reassurance {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    max-width: 44rem;
    margin: 18px auto 0;
    color: var(--text-subtle);
    font-size: 14px;
    font-weight: 500;
    text-align: center;
  }

  .wiz-reassurance--compact {
    margin-top: 14px;
  }

  .wiz-reassurance :global(.icon) {
    color: var(--yellow);
    font-size: 13px;
  }

  .wiz-btn-back:hover {
    color: var(--text-heading);
    border-color: rgba(var(--brand-rgb), 0.4);
  }

  @media (max-width: 768px) {
    :global(#newlead).wiz {
      padding-left: var(--space-container-x-mobile);
      padding-right: var(--space-container-x-mobile);
    }

    .wiz-inner--compact {
      margin-top: 0;
    }
  }

  @media (max-width: 640px) {
    .wiz-trust {
      flex-direction: column;
      text-align: center;
      gap: 10px;
    }

    .wiz-progress {
      gap: 8px;
    }

    .wiz-step-label {
      display: none;
    }

    .wiz-step-mark {
      padding: 6px 10px 6px 6px;
    }

    .wiz-step-line {
      flex: 0 0 24px;
    }

    .wiz-service-grid {
      grid-template-columns: 1fr;
    }

    .wiz-service-grid--compact {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .wiz-service--compact {
      min-height: 100%;
      padding: 12px;
    }

    .wiz-service--compact .wiz-service-desc {
      display: none;
    }

    .wiz-card--compact {
      padding: 20px 18px;
      border-radius: 22px;
    }

    .wiz-grid-two {
      grid-template-columns: 1fr;
    }

    .wiz-actions-split {
      flex-direction: column-reverse;
      gap: 10px;
    }

    .wiz-btn {
      width: 100%;
      justify-content: center;
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .wiz-step-mark,
    .wiz-service,
    .wiz-btn {
      transition: none;
    }
  }
</style>
