import { createFileRoute } from "@tanstack/react-router";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner";
import { useServerFn } from "@tanstack/react-start";
import {
  getPublicForm,
  submitPublicForm,
  trackFormStart,
  trackFormView,
} from "@/lib/forms.functions";
import { sendCapiEvent } from "@/lib/capi.functions";
import { supabase } from "@/integrations/supabase/client";
import { captureUtmFromUrl } from "@/lib/tracking";
import { renderRichText } from "@/lib/rich-text";
import { CalEmbed } from "@/components/CalEmbed";



type Question = {
  id: string;
  position: number;
  type: "short_text" | "long_text" | "email" | "phone" | "number" | "radio" | "checkbox";
  label: string;
  description: string;
  required: boolean;
  options: string[];
};

type FormRow = {
  id: string;
  slug: string;
  name: string;
  welcome_title: string;
  welcome_subtitle: string;
  welcome_cta: string;
  thank_you_title: string;
  thank_you_message: string;
  primary_color: string;
  background_color: string;
  text_color: string;
  highlight_color: string;
  send_to_meta: boolean;
  show_cal: boolean;
};


type W = Window & {
  fbq?: (...args: unknown[]) => void;
  gtag?: (...args: unknown[]) => void;
  dataLayer?: unknown[];
};

export const Route = createFileRoute("/f/$slug")({
  component: FormPage,
  head: () => ({ meta: [{ title: "Formulário" }, { name: "robots", content: "noindex" }] }),
});


function makeSessionKey() {
  return (
    Date.now().toString(36) +
    "-" +
    Math.random().toString(36).slice(2, 10) +
    Math.random().toString(36).slice(2, 10)
  );
}

/**
 * Persist a stable session key per form in localStorage so page reloads
 * within the same browser reuse the same event_id namespace. This keeps
 * Pixel + CAPI deduplication working even after a refresh.
 */
function getOrCreateSessionKey(formId: string): string {
  const storageKey = `form_session_${formId}`;
  try {
    const existing = window.localStorage.getItem(storageKey);
    if (existing) return existing;
  } catch {
    /* ignore */
  }
  const fresh = makeSessionKey();
  try {
    window.localStorage.setItem(storageKey, fresh);
  } catch {
    /* ignore */
  }
  return fresh;
}

/** Deterministic event id = form + session + event → same across Pixel/CAPI/retries. */
function buildEventId(formId: string, sessionKey: string, eventName: string) {
  return `${formId}:${sessionKey}:${eventName}`;
}

function readCookie(name: string): string | null {
  if (typeof document === "undefined") return null;
  const m = document.cookie.match(new RegExp("(?:^|; )" + name + "=([^;]+)"));
  return m ? decodeURIComponent(m[1]) : null;
}

function ensureFbq(pixelId: string) {
  if (typeof window === "undefined") return;
  const w = window as W & { _fbq?: unknown };
  if (w.fbq) return;
  /* eslint-disable @typescript-eslint/no-explicit-any */
  const f: any = function (...args: unknown[]) {
    if (f.callMethod) f.callMethod.apply(f, args);
    else f.queue.push(args);
  };
  if (!w._fbq) w._fbq = f;
  f.push = f;
  f.loaded = true;
  f.version = "2.0";
  f.queue = [];
  (w as unknown as { fbq: typeof f }).fbq = f;
  const s = document.createElement("script");
  s.async = true;
  s.src = "https://connect.facebook.net/en_US/fbevents.js";
  document.head.appendChild(s);
  (w as unknown as { fbq: (...a: unknown[]) => void }).fbq("init", pixelId);
  /* eslint-enable */
}

function ensureGtag(gaId: string) {
  if (typeof window === "undefined") return;
  const w = window as W;
  if (w.gtag) return;
  w.dataLayer = w.dataLayer || [];
  const gtag = function (...args: unknown[]) {
    (w.dataLayer as unknown[]).push(args);
  };
  w.gtag = gtag;
  gtag("js", new Date());
  gtag("config", gaId, { send_page_view: false });
  if (!document.getElementById("ga4-form-loader")) {
    const s = document.createElement("script");
    s.id = "ga4-form-loader";
    s.async = true;
    s.src = `https://www.googletagmanager.com/gtag/js?id=${gaId}`;
    document.head.appendChild(s);
  }
}

function gaEvent(name: string, params: Record<string, unknown>) {
  try {
    (window as W).gtag?.("event", name, params);
  } catch {
    /* noop */
  }
}

function fbqSafe(...args: unknown[]) {
  try {
    (window as W).fbq?.(...args);
  } catch {
    /* noop */
  }
}

function FormPage() {
  const { slug } = Route.useParams();

  const load = useServerFn(getPublicForm);
  const view = useServerFn(trackFormView);
  const start = useServerFn(trackFormStart);
  const submit = useServerFn(submitPublicForm);
  const capi = useServerFn(sendCapiEvent);

  const [form, setForm] = useState<FormRow | null>(null);
  const [questions, setQuestions] = useState<Question[]>([]);
  const [pixelId, setPixelId] = useState<string | null>(null);
  const [calLink, setCalLink] = useState<string | null>(null);
  const lastLeadRef = useRef<{ email: string | null; phone: string | null; name: string | null } | null>(null);

  const [step, setStep] = useState<number>(-1); // -1 welcome, 0..N-1 questions, N thank-you
  const [answers, setAnswers] = useState<Record<string, string | string[]>>({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const sessionKey = useRef<string>("");
  const started = useRef<boolean>(false);
  // Client-side dedup guard: never fire the same (event_id) twice from the same tab,
  // even across React re-renders, StrictMode double-invokes, or user retries.
  const firedPixel = useRef<Set<string>>(new Set());
  const firedCapi = useRef<Set<string>>(new Set());
  const utmRef = useRef<{
    utm_source: string | null;
    utm_medium: string | null;
    utm_campaign: string | null;
    utm_term: string | null;
    utm_content: string | null;
  }>({
    utm_source: null,
    utm_medium: null,
    utm_campaign: null,
    utm_term: null,
    utm_content: null,
  });

  useEffect(() => {
    (async () => {
      try {
        const res = await load({ data: { slug } });
        setForm(res.form as FormRow);
        setQuestions(res.questions as Question[]);
        sessionKey.current = getOrCreateSessionKey(res.form.id);

        const { data: settings } = await supabase
          .from("site_settings")
          .select("meta_pixel_id, ga4_id, cal_link")
          .eq("id", true)
          .maybeSingle();
        const px = (settings as { meta_pixel_id?: string } | null)?.meta_pixel_id ?? null;
        const ga = (settings as { ga4_id?: string } | null)?.ga4_id ?? null;
        const cal = (settings as { cal_link?: string } | null)?.cal_link ?? null;
        if (cal) setCalLink(cal);


        if (res.form.send_to_meta && px) {
          setPixelId(px);
          ensureFbq(px);
        }
        if (ga) {
          ensureGtag(ga);
        }

        // Capture UTMs
        const utm = captureUtmFromUrl();
        const utmParams = {
          utm_source: utm.utm_source ?? null,
          utm_medium: utm.utm_medium ?? null,
          utm_campaign: utm.utm_campaign ?? null,
          utm_term: utm.utm_term ?? null,
          utm_content: utm.utm_content ?? null,
        };
        utmRef.current = utmParams;
        const ctx = {
          ...utmParams,
          referrer: utm.referrer ?? null,
          landing_path: utm.landing_path ?? null,
          fbp: readCookie("_fbp"),
          fbc: readCookie("_fbc"),
          user_agent: typeof navigator !== "undefined" ? navigator.userAgent.slice(0, 500) : null,
        };
        await view({ data: { formId: res.form.id, sessionKey: sessionKey.current, ctx } });

        const formMeta = {
          form_id: res.form.id,
          form_slug: res.form.slug,
          form_name: res.form.name,
          ...utmParams,
        };

        // GA4: page_view + form_view custom event
        gaEvent("page_view", { page_location: window.location.href, page_title: res.form.name, ...utmParams });
        gaEvent("form_view", formMeta);

        // Meta Pixel — standard + per-form custom events. Deterministic event_id
        // (form + session + event) matches CAPI, so Meta dedups Pixel⇄CAPI.
        const evId = buildEventId(res.form.id, sessionKey.current, "ViewContent");
        if (!firedPixel.current.has(evId)) {
          firedPixel.current.add(evId);
          fbqSafe("track", "ViewContent", { content_name: res.form.name, ...formMeta }, { eventID: evId });
          fbqSafe("trackCustom", `FormView_${res.form.slug}`, { ...formMeta, eventID: evId });
          fbqSafe("trackCustom", "PontoView", { ...formMeta, eventID: evId });
        }

        if (res.form.send_to_meta && !firedCapi.current.has(evId)) {
          firedCapi.current.add(evId);
          capi({
            data: {
              event_name: "ViewContent",
              event_id: evId,
              form_id: res.form.id,
              event_source_url: window.location.href,
              user_data: {
                client_user_agent: ctx.user_agent ?? undefined,
                fbp: ctx.fbp ?? undefined,
                fbc: ctx.fbc ?? undefined,
              },
              custom_data: formMeta,
            },
          }).catch(() => {});
        }
      } catch (e) {
        setError(e instanceof Error ? e.message : "Erro ao carregar");
      } finally {
        setLoading(false);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [slug]);


  const fireStart = useCallback(() => {
    if (started.current || !form) return;
    started.current = true;
    start({ data: { formId: form.id, sessionKey: sessionKey.current } }).catch(() => {});
    const evId = buildEventId(form.id, sessionKey.current, "InitiateCheckout");
    const formMeta = { form_id: form.id, form_slug: form.slug, form_name: form.name, ...utmRef.current };

    gaEvent("form_start", formMeta);
    if (!firedPixel.current.has(evId)) {
      firedPixel.current.add(evId);
      fbqSafe("track", "InitiateCheckout", { content_name: form.name, ...formMeta }, { eventID: evId });
      fbqSafe("trackCustom", `FormStart_${form.slug}`, { ...formMeta, eventID: evId });
      fbqSafe("trackCustom", "PontoFirstinteraction", { ...formMeta, eventID: evId });
    }

    if (form.send_to_meta && !firedCapi.current.has(evId)) {
      firedCapi.current.add(evId);
      capi({
        data: {
          event_name: "InitiateCheckout",
          event_id: evId,
          form_id: form.id,
          event_source_url: window.location.href,
          user_data: {
            client_user_agent: navigator.userAgent.slice(0, 500),
            fbp: readCookie("_fbp") ?? undefined,
            fbc: readCookie("_fbc") ?? undefined,
          },
          custom_data: formMeta,
        },
      }).catch(() => {});
    }
  }, [form, start, capi]);


  const total = questions.length;
  const progress = useMemo(() => {
    if (step < 0) return 0;
    if (step >= total) return 100;
    return Math.round((step / total) * 100);
  }, [step, total]);

  const currentQ = step >= 0 && step < total ? questions[step] : null;

  const validate = (q: Question, val: string | string[] | undefined): string | null => {
    const isEmpty =
      val === undefined || val === "" || (Array.isArray(val) && val.length === 0);
    if (q.required && isEmpty) return "Este campo é obrigatório.";
    if (!isEmpty && q.type === "email" && typeof val === "string") {
      if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val)) return "E-mail inválido.";
    }
    if (!isEmpty && q.type === "phone" && typeof val === "string") {
      const digits = val.replace(/\D/g, "");
      if (digits.length < 10) return "Telefone inválido.";
    }
    return null;
  };

  const next = () => {
    if (!currentQ) return;
    const val = answers[currentQ.id];
    const err = validate(currentQ, val);
    if (err) return toast.error(err);
    if (step + 1 >= total) void doSubmit();
    else setStep(step + 1);
  };

  const doSubmit = async () => {
    if (!form) return;
    setSubmitting(true);
    // Extract contact-ish fields (first email/phone/name-ish question)
    let email: string | null = null;
    let phone: string | null = null;
    let name: string | null = null;
    for (const q of questions) {
      const v = answers[q.id];
      if (typeof v !== "string") continue;
      if (!email && q.type === "email") email = v;
      if (!phone && q.type === "phone") phone = v;
      if (!name && q.type === "short_text" && /nome/i.test(q.label)) name = v;
    }
    try {
      await submit({
        data: {
          formId: form.id,
          sessionKey: sessionKey.current,
          responses: answers as Record<string, string | string[]>,
          contact: { name, email, phone },
        },
      });
      const evId = buildEventId(form.id, sessionKey.current, "Lead");
      const formMeta = { form_id: form.id, form_slug: form.slug, form_name: form.name, ...utmRef.current };

      // GA4: standard generate_lead + custom form_submit
      gaEvent("generate_lead", { currency: "BRL", value: 0, ...formMeta });
      gaEvent("form_submit", formMeta);

      // Meta Pixel — Lead + per-form custom event
      if (!firedPixel.current.has(evId)) {
        firedPixel.current.add(evId);
        fbqSafe("track", "Lead", { content_name: form.name, ...formMeta }, { eventID: evId });
        fbqSafe("trackCustom", `Lead_${form.slug}`, { ...formMeta, eventID: evId });
        fbqSafe("trackCustom", "PontoSubmit", { ...formMeta, eventID: evId });
      }

      if (form.send_to_meta && !firedCapi.current.has(evId)) {
        firedCapi.current.add(evId);
        capi({
          data: {
            event_name: "Lead",
            event_id: evId,
            form_id: form.id,
            event_source_url: window.location.href,
            user_data: {
              email: email ?? undefined,
              phone: phone ?? undefined,
              first_name: name ?? undefined,
              client_user_agent: navigator.userAgent.slice(0, 500),
              fbp: readCookie("_fbp") ?? undefined,
              fbc: readCookie("_fbc") ?? undefined,
            },
            custom_data: formMeta,
          },
        }).catch(() => {});
      }

      lastLeadRef.current = { email, phone, name };
      setStep(total);

    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Erro ao enviar");
    } finally {
      setSubmitting(false);
    }
  };

  const setValue = (id: string, val: string | string[]) => {
    fireStart();
    setAnswers((a) => ({ ...a, [id]: val }));
  };

  // Dispara Ponto_View_Scheduled quando a tela de agendamento aparece
  useEffect(() => {
    if (!form) return;
    if (step < total || total === 0) return;
    if (!calLink || !form.show_cal) return;
    const evId = buildEventId(form.id, sessionKey.current, "ViewScheduled");
    if (firedPixel.current.has(evId)) return;
    firedPixel.current.add(evId);
    const formMeta = {
      form_id: form.id,
      form_slug: form.slug,
      form_name: form.name,
      ...utmRef.current,
    };
    fbqSafe("trackCustom", "Ponto_View_Scheduled", { ...formMeta, eventID: evId });
  }, [step, total, form, calLink]);

  if (loading) {
    return (
      <div className="min-h-screen bg-neutral-950 text-white flex items-center justify-center">
        <p className="text-neutral-400">Carregando...</p>
      </div>
    );
  }
  if (error || !form) {
    return (
      <div className="min-h-screen bg-neutral-950 text-white flex items-center justify-center p-6 text-center">
        <div>
          <h1 className="text-2xl font-bold mb-2">Ops!</h1>
          <p className="text-neutral-400">{error ?? "Formulário indisponível."}</p>
        </div>
      </div>
    );
  }

  const primary = form.primary_color || "#3DFF8A";
  const bg = form.background_color || "#0a0a0a";
  const fg = form.text_color || "#ffffff";
  const hl = form.highlight_color || primary;
  const rt = (s: string) => renderRichText(s, hl);

  return (
    <div className="min-h-screen flex flex-col" style={{ background: bg, color: fg }}>
      <div className="h-1 w-full" style={{ background: `${fg}20` }}>
        <div className="h-full transition-all" style={{ width: `${progress}%`, background: primary }} />
      </div>

      <div className="flex-1 flex items-center justify-center px-6 py-12">
        <div className="w-full max-w-2xl">
          {step === -1 && (
            <div className="space-y-8 animate-in fade-in duration-500">
              <div>
                <h1
                  className="text-4xl md:text-5xl font-bold leading-tight"
                  dangerouslySetInnerHTML={{
                    __html: rt(form.welcome_title || form.name),
                  }}
                />
                {form.welcome_subtitle && (
                  <p
                    className="mt-4 text-lg opacity-80"
                    dangerouslySetInnerHTML={{ __html: rt(form.welcome_subtitle) }}
                  />
                )}
              </div>
              <button
                onClick={() => {
                  fireStart();
                  setStep(0);
                }}
                className="rounded-full px-8 py-4 text-base font-bold text-black transition hover:opacity-90"
                style={{ background: primary }}
              >
                {form.welcome_cta || "Começar"} →
              </button>
            </div>
          )}

          {currentQ && (
            <div key={currentQ.id} className="space-y-6 animate-in fade-in slide-in-from-bottom-2 duration-300">
              <div>
                <div className="text-xs uppercase tracking-widest opacity-50 mb-2">
                  Pergunta {step + 1} de {total}
                </div>
                <h2 className="text-2xl md:text-3xl font-bold">
                  <span dangerouslySetInnerHTML={{ __html: rt(currentQ.label) }} />
                  {currentQ.required && <span style={{ color: primary }}> *</span>}
                </h2>
                {currentQ.description && (
                  <p
                    className="mt-2 opacity-70"
                    dangerouslySetInnerHTML={{ __html: rt(currentQ.description) }}
                  />
                )}
              </div>

              <QuestionInput
                q={currentQ}
                value={answers[currentQ.id]}
                onChange={(v) => setValue(currentQ.id, v)}
                onEnter={next}
                primary={primary}
              />

              <div className="flex items-center gap-3 pt-2">
                {step > 0 && (
                  <button
                    onClick={() => setStep(step - 1)}
                    className="rounded-full border px-5 py-3 text-sm font-semibold hover:opacity-80"
                    style={{ borderColor: `${fg}33` }}
                  >
                    ← Voltar
                  </button>
                )}
                <button
                  onClick={next}
                  disabled={submitting}
                  className="rounded-full px-7 py-3 text-sm font-bold text-black disabled:opacity-60"
                  style={{ background: primary }}
                >
                  {step + 1 >= total ? (submitting ? "Enviando..." : "Enviar") : "OK ✓"}
                </button>
                <span className="text-xs opacity-50 hidden md:inline">
                  ou pressione Enter ↵
                </span>
              </div>
            </div>
          )}

          {step >= total && total > 0 && (
            <div className="space-y-4 animate-in fade-in duration-500 text-center">
              <div
                className="mx-auto flex h-16 w-16 items-center justify-center rounded-full"
                style={{ background: primary }}
              >
                <span className="text-3xl text-black">✓</span>
              </div>
              <h1
                className="text-3xl md:text-4xl font-bold"
                dangerouslySetInnerHTML={{ __html: rt(form.thank_you_title) }}
              />
              {form.thank_you_message && (
                <p
                  className="opacity-80"
                  dangerouslySetInnerHTML={{ __html: rt(form.thank_you_message) }}
                />
              )}

              {calLink && form.show_cal && (
                <div className="mt-8 text-left">
                  <h2 className="text-xl font-bold mb-3 text-center">
                    Agende sua reunião
                  </h2>
                  <CalEmbed
                    calLink={calLink}
                    onBooking={(payload) => {
                      if (!form) return;
                      const evId = buildEventId(form.id, sessionKey.current, "Schedule");
                      const lead = lastLeadRef.current ?? { email: null, phone: null, name: null };
                      const formMeta = {
                        form_id: form.id,
                        form_slug: form.slug,
                        form_name: form.name,
                        ...utmRef.current,
                      };

                      // GA4
                      gaEvent("schedule_success", formMeta);

                      // Meta Pixel — standard Schedule + per-form custom event
                      if (!firedPixel.current.has(evId)) {
                        firedPixel.current.add(evId);
                        fbqSafe("track", "Schedule", { content_name: form.name, ...formMeta }, { eventID: evId });
                        fbqSafe("trackCustom", `Schedule_${form.slug}`, { ...formMeta, eventID: evId });
                        fbqSafe("trackCustom", "Ponto_Scheduled", { ...formMeta, eventID: evId });
                      }

                      // CAPI
                      if (form.send_to_meta && !firedCapi.current.has(evId)) {
                        firedCapi.current.add(evId);
                        capi({
                          data: {
                            event_name: "Schedule",
                            event_id: evId,
                            form_id: form.id,
                            event_source_url: typeof window !== "undefined" ? window.location.href : undefined,
                            user_data: {
                              email: lead.email ?? undefined,
                              phone: lead.phone ?? undefined,
                              first_name: lead.name ?? undefined,
                              client_user_agent: typeof navigator !== "undefined" ? navigator.userAgent.slice(0, 500) : undefined,
                              fbp: readCookie("_fbp") ?? undefined,
                              fbc: readCookie("_fbc") ?? undefined,
                            },
                            custom_data: { ...formMeta, cal_payload: payload as Record<string, unknown> | undefined },
                          },
                        }).catch(() => {});
                      }
                    }}
                  />
                </div>
              )}
            </div>
          )}

        </div>

      </div>

      {pixelId && (
        <noscript>
          <img
            height="1"
            width="1"
            style={{ display: "none" }}
            alt=""
            src={`https://www.facebook.com/tr?id=${pixelId}&ev=PageView&noscript=1`}
          />
        </noscript>
      )}
    </div>
  );
}

function QuestionInput({
  q,
  value,
  onChange,
  onEnter,
  primary,
}: {
  q: Question;
  value: string | string[] | undefined;
  onChange: (v: string | string[]) => void;
  onEnter: () => void;
  primary: string;
}) {
  const cls =
    "w-full rounded-lg border border-white/15 bg-white/5 px-4 py-3 text-lg outline-none focus:border-white/40 focus:bg-white/10 transition";
  const onKey = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && !e.shiftKey && q.type !== "long_text") {
      e.preventDefault();
      onEnter();
    }
  };

  if (q.type === "long_text") {
    return (
      <textarea
        rows={4}
        value={(value as string) ?? ""}
        onChange={(e) => onChange(e.target.value)}
        onKeyDown={onKey}
        placeholder="Sua resposta..."
        className={cls}
        autoFocus
      />
    );
  }
  if (q.type === "radio") {
    return (
      <div className="space-y-2">
        {q.options.map((opt) => {
          const active = value === opt;
          return (
            <button
              key={opt}
              type="button"
              onClick={() => onChange(opt)}
              className={`w-full rounded-lg border px-4 py-3 text-left text-base transition ${
                active ? "border-transparent text-black" : "border-white/15 hover:bg-white/5"
              }`}
              style={active ? { background: primary } : undefined}
            >
              {opt}
            </button>
          );
        })}
      </div>
    );
  }
  if (q.type === "checkbox") {
    const arr = Array.isArray(value) ? value : [];
    return (
      <div className="space-y-2">
        {q.options.map((opt) => {
          const active = arr.includes(opt);
          return (
            <button
              key={opt}
              type="button"
              onClick={() =>
                onChange(active ? arr.filter((x) => x !== opt) : [...arr, opt])
              }
              className={`w-full rounded-lg border px-4 py-3 text-left text-base transition ${
                active ? "border-transparent text-black" : "border-white/15 hover:bg-white/5"
              }`}
              style={active ? { background: primary } : undefined}
            >
              <span className="mr-2">{active ? "☑" : "☐"}</span> {opt}
            </button>
          );
        })}
      </div>
    );
  }
  const inputType =
    q.type === "email" ? "email" : q.type === "number" ? "number" : q.type === "phone" ? "tel" : "text";
  return (
    <input
      type={inputType}
      value={(value as string) ?? ""}
      onChange={(e) => onChange(e.target.value)}
      onKeyDown={onKey}
      placeholder={
        q.type === "email"
          ? "voce@email.com"
          : q.type === "phone"
            ? "(11) 99999-9999"
            : "Sua resposta..."
      }
      className={cls}
      autoFocus
    />
  );
}
