<script lang="ts">
  import { onMount } from 'svelte';
  import Icon from '$lib/components/Icon.svelte';
  import SuccessModal from '$lib/components/SuccessModal.svelte';
  import ErrorModal from '$lib/components/ErrorModal.svelte';
  import { reveal } from '$lib/actions/reveal';
  import type { BookingContent } from '$lib/types';

  export let booking: BookingContent;

  let step = 1;
  $: headingParts = splitBookingTitle(booking.title);

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

  let fullNameInput: HTMLInputElement;
  let emailInput: HTMLInputElement;
  let phoneInput: HTMLInputElement;
  let petNameInput: HTMLInputElement;
  let locationInput: HTMLInputElement;

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

  function validateEmail(raw: string): string {
    const value = raw.trim();
    if (!value) return 'Please enter your email address';
    if (!value.includes('@')) return 'Email is missing the @ sign';

    const [local, ...domainParts] = value.split('@');
    const domain = domainParts.join('@');

    if (domainParts.length > 1) return 'Email can only contain one @ sign';
    if (!local) return 'Please add the part before the @';
    if (!domain) return 'Please add a domain after the @, like @gmail.com';
    if (!domain.includes('.')) return 'Please include a domain ending, like @gmail.com';

    const tld = domain.split('.').pop() ?? '';
    if (tld.length < 2) return 'That domain ending looks too short';

    if (/\s/.test(value)) return 'Email cannot contain spaces';

    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 '';
  }

  const defaultDogIntro =
    'Tell us about your dog and where you are based so we can plan the right Meet & Greet.';

  $: dogIntro = booking.dogIntro?.trim() || defaultDogIntro;
  $: hasBanner = Boolean(booking.subtitle?.trim());
  $: hasServices = booking.serviceOptions.length > 0;
  $: ownerStepLabel = booking.ownerStepLabel?.trim() || 'Owner Details';
  $: dogStepLabel = booking.dogStepLabel?.trim() || 'Your dog';

  onMount(() => {
    formStartedAt = Date.now();
  });

  function splitBookingTitle(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 clearError(field: string) {
    if (errors[field]) {
      errors = { ...errors, [field]: '' };
    }
  }

  function toggleService(service: string, checked: boolean) {
    if (checked) {
      selectedServices = [...selectedServices, service];
      return;
    }

    selectedServices = selectedServices.filter((item) => item !== service);
  }

  function validateStepOne(): boolean {
    const next: Record<string, string> = {};

    if (!fullName.trim()) next.fullName = 'Please enter your full name';

    const emailError = validateEmail(email);
    if (emailError) next.email = emailError;

    if (!phone.trim()) next.phone = 'Please enter your contact number';

    errors = next;

    if (next.fullName) { fullNameInput?.focus(); return false; }
    if (next.email) { emailInput?.focus(); return false; }
    if (next.phone) { phoneInput?.focus(); return false; }

    return true;
  }

  function goToDogStep() {
    if (!validateStepOne()) return;
    errors = {};
    step = 2;
  }

  async function handleSubmit(event: SubmitEvent) {
    event.preventDefault();

    if (step === 1) {
      goToDogStep();
      return;
    }

    const next: Record<string, string> = {};
    if (!petName.trim()) next.petName = "Please enter your dog's name";
    if (!location.trim()) next.location = 'Please enter your location';

    if (Object.keys(next).length > 0) {
      errors = next;
      if (next.petName) petNameInput?.focus();
      else if (next.location) locationInput?.focus();
      return;
    }

    submitting = true;
    submitErrorDetail = '';
    showErrorModal = false;

    try {
      const res = await fetch('/api/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            fullName, email, phone, petName, location, message,
            services: selectedServices,
            website,
            formStartedAt,
            referrer: document.referrer,
            page: window.location.href,
          }),
      });

      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;
    } catch (err: unknown) {
      submitErrorDetail = err instanceof Error ? err.message : String(err);
      showErrorModal = true;
    } finally {
      submitting = false;
    }
  }
</script>

<section id="newlead" use:reveal={{ delay: 70 }} class="reveal-block">
  <div class="form-inner">

    {#if submitted}
      <SuccessModal
        firstName={fullName.split(' ')[0]}
        {petName}
        {email}
        onClose={() => (submitted = false)}
      />
    {/if}

    {#if showErrorModal}
      <ErrorModal
        detail={submitErrorDetail}
        onClose={() => (showErrorModal = false)}
        onRetry={() => (showErrorModal = false)}
      />
    {/if}

    <div class="booking-header">
      <h2 class="booking-title">
        <span class="booking-title-plain">{headingParts.plain}</span>{' '}<span class="booking-title-highlight">{headingParts.highlight}</span>
      </h2>

      <div class="booking-stepper" aria-label="Booking form steps">
        <button
          type="button"
          class:active={step === 1}
          class="booking-step"
          on:click={() => (step = 1)}
        >
          <span class="booking-step-number">1</span>
          <span class="booking-step-label">{ownerStepLabel}</span>
        </button>
        <span class="booking-step-divider" aria-hidden="true"></span>
        <button
          type="button"
          class:active={step === 2}
          class="booking-step"
          on:click={goToDogStep}
        >
          <span class="booking-step-number">2</span>
          <span class="booking-step-label">{dogStepLabel}</span>
        </button>
      </div>
    </div>

    <form
      class="booking-form"
      id="bookingForm"
      novalidate
      on:submit={handleSubmit}
    >
      <div class="booking-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>

      {#if step === 1}
        <div class="booking-panel">
          {#if hasBanner}
            <div class="booking-panel-banner">{booking.subtitle}</div>
          {/if}

          <div class:booking-card-grid-with-banner={hasBanner} class="booking-card-grid booking-card-grid-owner">
            <div class="booking-field-card booking-field-card-group booking-field-card-full">
              <div class="booking-field-group booking-field-group-owner">
                <div class="booking-field-stack" class:booking-field-stack-invalid={errors.fullName}>
                  <label for="fullName">
                    <Icon name="fas fa-user" />&nbsp;Full Name <span class="booking-required">*</span>
                  </label>
                  <input
                    bind:this={fullNameInput}
                    bind:value={fullName}
                    type="text"
                    id="fullName"
                    name="fullName"
                    required
                    placeholder="Enter full name"
                    class:input-invalid={errors.fullName}
                    on:input={() => clearError('fullName')}
                  />
                  {#if errors.fullName}
                    <p class="field-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.fullName}
                    </p>
                  {/if}
                </div>

                <div class="booking-field-stack" class:booking-field-stack-invalid={errors.email}>
                  <label for="email">
                    <Icon name="fas fa-envelope" />&nbsp;Email <span class="booking-required">*</span>
                  </label>
                  <input
                    bind:this={emailInput}
                    bind:value={email}
                    type="email"
                    id="email"
                    name="email"
                    required
                    placeholder="Email"
                    class:input-invalid={errors.email}
                    on:input={() => clearError('email')}
                    on:blur={() => {
                      if (!email.trim()) return;
                      const msg = validateEmail(email);
                      errors = { ...errors, email: msg };
                    }}
                  />
                  {#if errors.email}
                    <p class="field-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.email}
                    </p>
                  {/if}
                </div>

                <div class="booking-field-stack" class:booking-field-stack-invalid={errors.phone}>
                  <label for="phone">
                    <Icon name="fas fa-phone" />&nbsp;Contact # <span class="booking-required">*</span>
                  </label>
                  <input
                    bind:this={phoneInput}
                    bind:value={phone}
                    type="tel"
                    id="phone"
                    name="phone"
                    required
                    placeholder="E.g. 021 1234567"
                    class:input-invalid={errors.phone}
                    on:input={() => clearError('phone')}
                  />
                  {#if errors.phone}
                    <p class="field-error">
                      <Icon name="fas fa-circle-exclamation" />
                      {errors.phone}
                    </p>
                  {/if}
                </div>
              </div>
            </div>
          </div>

          {#if hasServices}
            <div class="booking-service-row">
              <span class="booking-service-label"><Icon name="fas fa-paw" />&nbsp;Services</span>
              <div class="booking-service-options">
                {#each booking.serviceOptions as service}
                  <label class="booking-check-option">
                    <input
                      type="checkbox"
                      name="services"
                      value={service}
                      checked={selectedServices.includes(service)}
                      on:change={(event) =>
                        toggleService(service, (event.currentTarget as HTMLInputElement).checked)}
                    />
                    <span class="booking-check-box" aria-hidden="true"></span>
                    <span>{service}</span>
                  </label>
                {/each}
              </div>
            </div>
          {/if}
        </div>

        <div class="booking-actions booking-actions-next">
          <button type="button" class="btn btn-yellow booking-next-button" on:click={goToDogStep}>
            {dogStepLabel}
            <Icon name="fas fa-arrow-right" />
          </button>
        </div>
      {:else}
        <input type="hidden" name="fullName" value={fullName} />
        <input type="hidden" name="email" value={email} />
        <input type="hidden" name="phone" value={phone} />
        {#each selectedServices as service}
          <input type="hidden" name="services" value={service} />
        {/each}

        <div class="booking-panel">
          {#if dogIntro}
            <div class="booking-panel-banner">{dogIntro}</div>
          {/if}

          <div class:booking-card-grid-with-banner={Boolean(dogIntro)} class="booking-card-grid booking-card-grid-dog">
            <div class="booking-field-card" class:booking-field-card-invalid={errors.petName}>
              <label for="petName">
                <Icon name="fas fa-dog" />&nbsp;Pet's Name <span class="booking-required">*</span>
              </label>
              <input
                bind:this={petNameInput}
                bind:value={petName}
                type="text"
                id="petName"
                name="petName"
                required
                placeholder="Your dog's name"
                class:input-invalid={errors.petName}
                on:input={() => clearError('petName')}
              />
              {#if errors.petName}
                <p class="field-error">
                  <Icon name="fas fa-circle-exclamation" />
                  {errors.petName}
                </p>
              {/if}
            </div>

            <div class="booking-field-card booking-field-card-wide" class:booking-field-card-invalid={errors.location}>
              <label for="location">
                <Icon name="fas fa-location-dot" />&nbsp;Location <span class="booking-required">*</span>
              </label>
              <input
                bind:this={locationInput}
                bind:value={location}
                type="text"
                id="location"
                name="location"
                required
                placeholder="Neighborhood, street..."
                class:input-invalid={errors.location}
                on:input={() => clearError('location')}
              />
              {#if errors.location}
                <p class="field-error">
                  <Icon name="fas fa-circle-exclamation" />
                  {errors.location}
                </p>
              {/if}
            </div>

            <div class="booking-field-card booking-field-card-full">
              <label for="message"><Icon name="fas fa-comment" />&nbsp;About Your Dog</label>
              <textarea
                bind:value={message}
                id="message"
                name="message"
                rows="4"
                placeholder="Describe your pet, any special needs, or anything we should know."
              ></textarea>
            </div>
          </div>
        </div>

        <div class="booking-actions booking-actions-final">
          <button
            type="button"
            class="btn btn-outline btn-outline-green"
            on:click={() => { step = 1; errors = {}; }}
          >
            Back
          </button>
          <button type="submit" class="btn btn-yellow booking-submit-button" disabled={submitting}>
            {#if submitting}Sending…{:else}Send <Icon name="fas fa-arrow-right" />{/if}
          </button>
        </div>
      {/if}
    </form>
  </div>
</section>

<style>
  :global(.reveal-ready.reveal-block) {
    opacity: 0;
    transform: translate3d(0, var(--reveal-distance, 24px), 0);
    transition:
      opacity 0.55s ease,
      transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1);
    transition-delay: var(--reveal-delay, 0ms);
  }

  :global(.reveal-visible.reveal-block) {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }

  .booking-honeypot {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
  }
</style>
