---
interface Props {
  source?: string;
}

const { source = 'home' } = Astro.props;
---

<form class="contact-form rr-block" data-contact-form data-form-source={source} novalidate>
  <div class="form-field">
    <label for={`contact-name-${source}`}>ชื่อ</label>
    <input id={`contact-name-${source}`} name="name" type="text" autocomplete="name" maxlength="80" required aria-describedby={`contact-name-error-${source}`} />
    <p class="field-error" id={`contact-name-error-${source}`} data-error-for="name"></p>
  </div>
  <div class="form-field">
    <label for={`contact-method-${source}`}>เบอร์โทรหรืออีเมล</label>
    <input id={`contact-method-${source}`} name="contact" type="text" maxlength="160" required aria-describedby={`contact-method-error-${source}`} />
    <p class="field-error" id={`contact-method-error-${source}`} data-error-for="contact"></p>
  </div>
  <div class="form-field form-field-wide">
    <label for={`contact-problem-${source}`}>ตอนนี้ติดเรื่องอะไร</label>
    <textarea id={`contact-problem-${source}`} name="problem" rows="4" minlength="5" maxlength="1500" required aria-describedby={`contact-problem-error-${source}`}></textarea>
    <p class="field-error" id={`contact-problem-error-${source}`} data-error-for="problem"></p>
  </div>
  <div class="form-trap" aria-hidden="true">
    <label for={`contact-website-${source}`}>เว็บไซต์</label>
    <input id={`contact-website-${source}`} name="website" type="text" tabindex="-1" autocomplete="off" />
  </div>
  <div class="form-submit-row">
    <button type="submit" data-submit>ให้ทีมติดต่อกลับ <span aria-hidden="true">↗</span></button>
    <p class="form-privacy">ใช้ข้อมูลเพื่อติดต่อกลับ และเมื่อยินยอมการตลาด อาจส่งชื่อ/ช่องทางติดต่อแบบแฮช พร้อม IP, เบราว์เซอร์ และรหัส Meta (_fbp/_fbc) เพื่อวัดผลโฆษณา</p>
  </div>
  <p class="form-status" data-form-status role="status" aria-live="polite"></p>
</form>

<script>
  const forms = document.querySelectorAll<HTMLFormElement>('[data-contact-form]');
  const trackingWindow = window as typeof window & {
    __moreminiTrackingConsent?: { analytics?: boolean; marketing?: boolean };
    gtag?: (...args: unknown[]) => void;
    trackMarketingEvent?: (
      eventName: string,
      eventData: Record<string, string>,
      metaEventName?: string,
      options?: { eventId?: string; skipGoogle?: boolean; skipMeta?: boolean; skipUmami?: boolean },
    ) => void;
  };

  const cookieValue = (name: string) => {
    const prefix = `${name}=`;
    const item = document.cookie.split('; ').find((cookie) => cookie.startsWith(prefix));
    return item ? decodeURIComponent(item.slice(prefix.length)) : '';
  };

  const readGoogleIds = async (allowed: boolean) => {
    if (!allowed || typeof trackingWindow.gtag !== 'function') return { gaClientId: '', gaSessionId: '' };
    const getValue = (field: 'client_id' | 'session_id') => new Promise<string>((resolve) => {
      let settled = false;
      const finish = (value = '') => {
        if (settled) return;
        settled = true;
        resolve(String(value));
      };
      const timeout = window.setTimeout(() => finish(), 180);
      trackingWindow.gtag?.('get', 'G-74BHREDLC3', field, (value: unknown) => {
        window.clearTimeout(timeout);
        finish(typeof value === 'string' || typeof value === 'number' ? String(value) : '');
      });
    });
    const [clientId, sessionId] = await Promise.all([getValue('client_id'), getValue('session_id')]);
    return {
      gaClientId: /^\d{1,20}\.\d{1,20}$/.test(clientId) ? clientId : '',
      gaSessionId: /^\d{6,20}$/.test(sessionId) ? sessionId : '',
    };
  };

  forms.forEach((form) => {
    if (form.dataset.ready === 'true') return;
    form.dataset.ready = 'true';
    const submit = form.querySelector<HTMLButtonElement>('[data-submit]');
    const status = form.querySelector<HTMLElement>('[data-form-status]');
    let started = false;
    let retryEventId = '';
    let retryFingerprint = '';

    const track = (name: string, data: Record<string, string>, meta?: string, options?: { eventId?: string; skipGoogle?: boolean }) => {
      trackingWindow.trackMarketingEvent?.(name, data, meta, options);
    };

    const setError = (name: string, message = '') => {
      const field = form.elements.namedItem(name);
      const error = form.querySelector<HTMLElement>(`[data-error-for="${name}"]`);
      if (field instanceof HTMLElement) field.setAttribute('aria-invalid', message ? 'true' : 'false');
      if (error) error.textContent = message;
    };

    const validate = (data: FormData) => {
      const errors: Record<string, string> = {};
      const name = String(data.get('name') || '').trim();
      const contact = String(data.get('contact') || '').trim();
      const problem = String(data.get('problem') || '').trim();
      if (name.length < 2) errors.name = 'กรุณากรอกชื่ออย่างน้อย 2 ตัวอักษร';
      if (contact.length < 5) errors.contact = 'กรุณากรอกเบอร์โทรหรืออีเมลที่ติดต่อได้';
      if (problem.length < 5) errors.problem = 'กรุณาเล่าปัญหาสั้น ๆ อย่างน้อย 5 ตัวอักษร';
      return errors;
    };

    form.addEventListener('focusin', () => {
      if (started) return;
      started = true;
      track('form_started', { form_location: form.dataset.formSource || 'unknown' });
    });

    form.addEventListener('input', (event) => {
      const target = event.target;
      if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
        setError(target.name);
        if (['name', 'contact', 'problem', 'website'].includes(target.name)) {
          retryEventId = '';
          retryFingerprint = '';
        }
      }
    });

    form.addEventListener('submit', async (event) => {
      event.preventDefault();
      if (!submit || !status) return;
      const data = new FormData(form);
      const errors = validate(data);
      ['name', 'contact', 'problem'].forEach((name) => setError(name, errors[name]));
      if (Object.keys(errors).length) {
        status.textContent = 'กรุณาตรวจสอบข้อมูลที่ไฮไลต์';
        form.querySelector<HTMLElement>('[aria-invalid="true"]')?.focus();
        return;
      }

      submit.disabled = true;
      submit.setAttribute('aria-busy', 'true');
      const originalLabel = submit.innerHTML;
      submit.textContent = 'กำลังส่ง…';
      status.textContent = 'กำลังส่งข้อมูล';

      try {
        const submission = {
          name: String(data.get('name') || '').trim(),
          contact: String(data.get('contact') || '').trim(),
          problem: String(data.get('problem') || '').trim(),
          website: String(data.get('website') || ''),
          source: form.dataset.formSource || 'unknown',
        };
        const fingerprint = JSON.stringify(submission);
        if (!retryEventId || retryFingerprint !== fingerprint) {
          retryEventId = crypto.randomUUID();
          retryFingerprint = fingerprint;
        }
        const eventId = retryEventId;
        const consentState = trackingWindow.__moreminiTrackingConsent;
        const consent = {
          analytics: consentState?.analytics === true,
          marketing: consentState?.marketing === true,
        };
        const googleIds = await readGoogleIds(consent.analytics);
        const fbp = consent.marketing ? cookieValue('_fbp') : '';
        const fbc = consent.marketing ? cookieValue('_fbc') : '';
        const response = await fetch('/api/contact', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
          body: JSON.stringify({
            ...submission,
            eventId,
            tracking: {
              consent,
              fbp: /^fb\.\d\.\d{10,16}\.[A-Za-z0-9._-]{1,120}$/.test(fbp) ? fbp : '',
              fbc: /^fb\.\d\.\d{10,16}\.[A-Za-z0-9._-]{1,160}$/.test(fbc) ? fbc : '',
              ...googleIds,
            },
          }),
        });
        const result = await response.json().catch(() => ({}));
        if (!response.ok || !result.ok) {
          if (result.fields && typeof result.fields === 'object') {
            Object.entries(result.fields as Record<string, string>).forEach(([name, message]) => setError(name, message));
            form.querySelector<HTMLElement>('[aria-invalid="true"]')?.focus();
          }
          status.textContent = typeof result.error === 'string' ? result.error : 'ส่งไม่สำเร็จ กรุณาลองใหม่';
          return;
        }
        form.reset();
        retryEventId = '';
        retryFingerprint = '';
        status.textContent = 'ขอบคุณครับ ทีมจะติดต่อกลับโดยเร็ว';
        track('form_submitted', { form_location: form.dataset.formSource || 'unknown' }, 'Lead', { eventId, skipGoogle: true });
      } catch {
        status.textContent = 'ส่งไม่สำเร็จ กรุณาลองใหม่ หรือโทร 080-995-5945';
      } finally {
        submit.disabled = false;
        submit.removeAttribute('aria-busy');
        submit.innerHTML = originalLabel;
      }
    });
  });
</script>
