<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, watch } from "vue";
import { Icon } from "@iconify/vue";
import { createTranslator, getLocalizedRoute } from "../../i18n";

const props = defineProps({
  locale: String,
  formConfigUrl: { type: String, required: false, default: "/forms/formulario-inscripcion.json" },
  turnstileSiteKey: { type: String, required: false, default: "" }
});

const tl = createTranslator(props.locale);

const config = ref(null);
const configError = ref(false);
const currentStep = ref(0);
const formData = reactive({});
const isSubmitting = ref(false);
const isSuccess = ref(false);
const isError = ref(false);
const errorMsg = ref("");

const reglamentoScrollRef = ref(null);
const reglamentoHTML = ref("");
const reglamentoLoading = ref(false);
const reglamentoScrolled = ref(false);
const reglamentoFetchAttempted = ref(false);

const turnstileToken = ref("");
const turnstileContainer = ref(null);
const honeypot = ref("");

const turnstileReady = ref(false);

const totalSteps = computed(() => config.value?.steps?.length ?? 0);
const currentStepData = computed(() => config.value?.steps?.[currentStep.value] ?? null);

const isFirstStep = computed(() => currentStep.value === 0);
const isLastStep = computed(() => currentStep.value === totalSteps.value - 1);

const termsUrl = computed(() => {
  const slug = getLocalizedRoute("terminos", props.locale);
  return `/${props.locale}/${slug}`;
});

const fieldHelp = (key) => {
  const k = "form." + key + "_help";
  const v = tl(k);
  return v !== k ? v : "";
};

const isMinorBetween12and18 = (key) => {
  const y = dateParts[key]?.year;
  if (!y) return false;
  const age = new Date().getFullYear() - y;
  return age >= 12 && age < 18;
};

const stepErrors = reactive({});
const formatErrors = reactive({});
const phoneParts = reactive({});
const dateParts = reactive({});
const triedToProceed = ref(false);
const helpOpen = reactive({});

const toggleHelp = (key) => {
  helpOpen[key] = !helpOpen[key];
};

const closeHelp = () => {
  Object.keys(helpOpen).forEach((k) => (helpOpen[k] = false));
};

const months = computed(() =>
  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((n) => tl(`form.month.${n}`))
);

const years = (() => {
  const y = new Date().getFullYear();
  return Array.from({ length: 101 }, (_, i) => y - 12 - i);
})();

const remainingRequired = computed(() => {
  const step = config.value?.steps?.[currentStep.value];
  if (!step) return 0;
  let count = 0;
  step.fields.forEach((field) => {
    if (field.showWhen) {
      const sv = formData[field.showWhen.field];
      const sf = findField(field.showWhen.field);
      const met = sf?.type === "checkbox"
        ? Array.isArray(sv) && sv.includes(field.showWhen.value)
        : sv === field.showWhen.value;
      if (!met) return;
    }
    if (!field.required) return;
    const val = formData[field.key];
    if (field.type === "checkbox") {
      const ro = field.options?.filter(o => o.required)?.map(o => o.value) || [];
      if (ro.length > 0) {
        if (!ro.every(v => val?.includes(v))) count++;
      } else if (!val || val.length === 0) {
        count++;
      }
    } else if (field.type === "phone_country") {
      const p = phoneParts[field.key];
      if (!p || !p.code || !p.number) count++;
    } else if (!val || (typeof val === "string" && val.trim() === "")) {
      count++;
    }
  });
  return count;
});

const fetchConfig = async () => {
  isSuccess.value = false;
  try {
    const res = await fetch(props.formConfigUrl);
    if (!res.ok) throw new Error("Failed to load form config");
    const json = await res.json();
    config.value = json;
    json.steps.forEach((step, si) => {
      step.fields.forEach((field) => {
        if (field.type === "checkbox") {
          formData[field.key] = [];
        } else if (field.type === "date") {
          formData[field.key] = "";
          dateParts[field.key] = { day: null, month: null, year: null };
        } else if (field.type === "phone_country") {
          formData[field.key] = "";
          phoneParts[field.key] = { code: "", number: "", flag: "" };
        } else {
          formData[field.key] = "";
        }
      });
    });
  } catch {
    configError.value = true;
  }
};

const initTurnstile = () => {
  if (!props.turnstileSiteKey || !turnstileContainer.value) return;
  if (window.turnstile) {
    window.turnstile.render(turnstileContainer.value, {
      sitekey: props.turnstileSiteKey,
      callback: (token) => { turnstileToken.value = token; },
    });
    turnstileReady.value = true;
  }
};

onMounted(() => {
  fetchConfig();
  document.addEventListener("click", closeHelp);
  if (props.turnstileSiteKey) {
    if (document.querySelector('script[src*="turnstile"]')) {
      const check = setInterval(() => {
        if (window.turnstile) {
          clearInterval(check);
          initTurnstile();
        }
      }, 100);
    } else {
      const script = document.createElement("script");
      script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js";
      script.async = true;
      script.defer = true;
      script.onload = initTurnstile;
      document.head.appendChild(script);
    }
  }
});

onBeforeUnmount(() => {
  document.removeEventListener("click", closeHelp);
});

const validateStep = (stepIndex) => {
  const step = config.value?.steps?.[stepIndex];
  if (!step) return true;
  let valid = true;
  if (stepIndex === 0 && !reglamentoScrolled.value) {
    valid = false;
  }
  step.fields.forEach((field) => {
    if (field.showWhen) {
      const sourceVal = formData[field.showWhen.field];
      const sourceField = findField(field.showWhen.field);
      const conditionMet = sourceField?.type === "checkbox"
        ? Array.isArray(sourceVal) && sourceVal.includes(field.showWhen.value)
        : sourceVal === field.showWhen.value;
      if (!conditionMet) return;
    }
    const val = formData[field.key];
    if (field.type === "checkbox") {
      const requiredOptions = field.options?.filter(o => o.required)?.map(o => o.value) || [];
      if (field.required) {
        if (requiredOptions.length > 0) {
          const allRequiredSelected = requiredOptions.every(optVal => val?.includes(optVal));
          if (!allRequiredSelected) {
            stepErrors[field.key] = true;
            valid = false;
          } else {
            stepErrors[field.key] = false;
          }
        } else {
          if (!val || val.length === 0) {
            stepErrors[field.key] = true;
            valid = false;
          } else {
            stepErrors[field.key] = false;
          }
        }
      }
    }
    if (field.required && field.type !== "checkbox") {
      if (!val || val.trim() === "") {
        stepErrors[field.key] = true;
        valid = false;
      } else {
        stepErrors[field.key] = false;
      }
    }
    if (field.type === "email" && val && val.trim() !== "") {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(val.trim())) {
        stepErrors[field.key] = true;
        valid = false;
      } else {
        stepErrors[field.key] = false;
      }
    }
    if (field.type === "phone" && val && val.trim() !== "") {
      const phoneRegex = /^\d+$/;
      if (!phoneRegex.test(val.trim())) {
        formatErrors[field.key] = true;
        stepErrors[field.key] = true;
        valid = false;
      } else {
        formatErrors[field.key] = false;
      }
    }
    if (field.type === "phone_country") {
      const parts = phoneParts[field.key];
      if (field.required && (!parts || !parts.code || !parts.number)) {
        stepErrors[field.key] = true;
        valid = false;
      } else if (parts && parts.number) {
        const full = parts.code + parts.number;
        if (full.length > 15) {
          formatErrors[field.key] = true;
          stepErrors[field.key] = true;
          valid = false;
        } else if (parts.number.length < 7) {
          formatErrors[field.key] = true;
          stepErrors[field.key] = true;
          valid = false;
        } else {
          stepErrors[field.key] = false;
          formatErrors[field.key] = false;
        }
      }
    }
    if (field.type === "checkbox" && field.levels && Array.isArray(val)) {
      val.forEach((optVal) => {
        if (!formData[`${field.key}_nivel_${optVal}`]) {
          stepErrors[`${field.key}_nivel_${optVal}`] = true;
          valid = false;
        } else {
          stepErrors[`${field.key}_nivel_${optVal}`] = false;
        }
      });
    }
  });
  return valid;
};

const nextStep = () => {
  triedToProceed.value = true;
  if (!validateStep(currentStep.value)) return;
  if (currentStep.value < totalSteps.value - 1) {
    currentStep.value++;
  }
};

const prevStep = () => {
  if (currentStep.value > 0) {
    currentStep.value--;
  }
};

const goToStep = (index) => {
  if (index < currentStep.value) {
    currentStep.value = index;
    return;
  }
  for (let i = 0; i < index; i++) {
    if (!validateStep(i)) return;
  }
  currentStep.value = index;
};

const handleCheckboxChange = (key, value, checked) => {
  if (checked) {
    formData[key].push(value);
  } else {
    formData[key] = formData[key].filter((v) => v !== value);
    delete formData[`${key}_nivel_${value}`];
  }
  stepErrors[key] = false;
};

const buildPayload = () => {
  const responses = [];
  config.value.steps.forEach((step, si) => {
    step.fields.forEach((field) => {
      if (field.key === "segundo_nombre") return;
      let finalValue = formData[field.key];
      if (field.key === "nombre" && formData.segundo_nombre) {
        finalValue = `${finalValue} ${formData.segundo_nombre}`;
      }
      if (finalValue !== "" && !(Array.isArray(finalValue) && finalValue.length === 0)) {
        responses.push({
          key: field.key,
          value: finalValue,
          section_id: `step_${si}`
        });
        if (field.levels && Array.isArray(finalValue)) {
          finalValue.forEach((optVal) => {
            const levelKey = `${field.key}_nivel_${optVal}`;
            const levelVal = formData[levelKey];
            if (levelVal) {
              responses.push({
                key: levelKey,
                value: levelVal,
                section_id: `step_${si}`
              });
            }
          });
        }
      }
    });
  });
  return { formData: { ...formData, locale: props.locale }, responses, turnstileToken: turnstileToken.value, honeypot: honeypot.value };
};

const handleSubmit = async () => {
  for (let i = 0; i < totalSteps.value; i++) {
    if (!validateStep(i)) {
      currentStep.value = i;
      return;
    }
  }

  isSubmitting.value = true;
  isSuccess.value = false;
  isError.value = false;
  errorMsg.value = "";

  try {
    const payload = buildPayload();
    const res = await fetch("/api/formulario/send", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    const data = await res.json();
    if (data.success) {
      isSuccess.value = true;
    } else {
      throw new Error(data.message || "Error al enviar el formulario");
    }
  } catch (error) {
    isError.value = true;
    errorMsg.value = error.message || "Error al enviar el formulario";
  } finally {
    isSubmitting.value = false;
  }
};

const getFieldError = (key) => stepErrors[key] || false;

const composeDate = (key) => {
  const parts = dateParts[key];
  if (!parts) return;
  const d = parts.day;
  const m = parts.month;
  const y = parts.year;
  if (d && m && y) {
    formData[key] = `${y}-${String(m).padStart(2, "0")}-${String(d).padStart(2, "0")}`;
  } else {
    formData[key] = "";
  }
  stepErrors[key] = false;
};

const onPhoneInput = (key, event) => {
  const cleaned = event.target.value.replace(/\D/g, "");
  formData[key] = cleaned;
  stepErrors[key] = false;
  formatErrors[key] = false;
};

const onPhoneCountryNumberInput = (key, event) => {
  if (!phoneParts[key]) return;
  const cleaned = event.target.value.replace(/\D/g, "");
  event.target.value = cleaned;
  phoneParts[key].number = cleaned;
  formData[key] = phoneParts[key].code + cleaned;
  stepErrors[key] = false;
};

const getPhoneCountryDisplay = (key) => {
  if (phoneCountrySearchText[key] !== undefined && phoneCountrySearchText[key] !== null) {
    return phoneCountrySearchText[key];
  }
  if (!phoneParts[key] || !phoneParts[key].code) return "";
  return phoneParts[key].flag
    ? `${phoneParts[key].code}`
    : phoneParts[key].code;
};

const filteredPhoneCountries = (field, key) => {
  const text = (phoneCountrySearchText[key] || "").toLowerCase().trim();
  const list = suggestionsCache.value[field.source] || [];
  if (!text) return list;
  return list.filter(
    item => item.label.toLowerCase().includes(text) || item.dial_code.includes(text)
  );
};

const onPhoneCountrySearchFocus = (field, key) => {
  loadSuggestions(field.source);
  showCountrySuggestions[key] = true;
};

const onPhoneCountrySearchBlur = (key) => {
  setTimeout(() => {
    showCountrySuggestions[key] = false;
    phoneCountrySearchText[key] = undefined;
  }, 200);
};

const onPhoneCountrySearchInput = (key, event) => {
  phoneCountrySearchText[key] = event.target.value;
  showCountrySuggestions[key] = true;
};

const onPhoneCountrySelect = (key, item) => {
  phoneParts[key].code = item.dial_code;
  phoneParts[key].flag = item.flag;
  phoneParts[key].number = phoneParts[key].number || "";
  formData[key] = item.dial_code + phoneParts[key].number;
  phoneCountrySearchText[key] = undefined;
  showCountrySuggestions[key] = false;
  stepErrors[key] = false;
};

const suggestionsCache = ref({});
const showSuggestions = reactive({});
const phoneCountrySearchText = reactive({});
const showCountrySuggestions = reactive({});

const loadSuggestions = async (source) => {
  if (suggestionsCache.value[source]) return;
  let url = source;
  if (source?.includes("paises.json") && props.locale && props.locale !== "es") {
    const localized = `/forms/paises-${props.locale}.json`;
    try {
      const res = await fetch(localized);
      if (res.ok) url = localized;
    } catch {}
  }
  try {
    const res = await fetch(url);
    suggestionsCache.value[source] = await res.json();
  } catch {}
};

const filteredSuggestions = (field) => {
  const val = formData[field.key]?.toLowerCase().trim() || "";
  if (!val) return [];
  const list = suggestionsCache.value[field.source] || [];
  return list.filter(item => item.label.toLowerCase().includes(val));
};

const selectSuggestion = (field, item) => {
  formData[field.key] = item.value;
  showSuggestions[field.key] = false;
  stepErrors[field.key] = false;
};

const onAutocompleteFocus = (field) => {
  loadSuggestions(field.source);
  showSuggestions[field.key] = true;
};

const onAutocompleteBlur = (field) => {
  setTimeout(() => { showSuggestions[field.key] = false; }, 200);
};

const getSelectOptions = (field) => {
  loadSuggestions(field.source);
  return suggestionsCache.value[field.source] || [];
};

const findField = (key) => {
  if (!config.value) return null;
  for (const step of config.value.steps) {
    const found = step.fields.find((f) => f.key === key);
    if (found) return found;
  }
  return null;
};

const shouldShow = (field) => {
  if (!field.showWhen) return true;
  const sourceField = findField(field.showWhen.field);
  const value = formData[field.showWhen.field];
  if (!value) return false;
  if (sourceField?.type === "checkbox") {
    return Array.isArray(value) && value.includes(field.showWhen.value);
  }
  return value === field.showWhen.value;
};

const fetchReglamento = async () => {
  if (reglamentoFetchAttempted.value) return;
  reglamentoFetchAttempted.value = true;
  reglamentoScrolled.value = false;
  reglamentoLoading.value = true;
  reglamentoHTML.value = "";
  try {
    const locales = [props.locale, "es"];
    let html = null;
    for (const l of locales) {
      const res = await fetch(`/reglamento/${l}.html`);
      if (res.ok) { html = await res.text(); break; }
    }
    reglamentoHTML.value = html || "<p>Error al cargar el reglamento</p>";
  } catch {
    reglamentoHTML.value = "<p>Error al cargar el reglamento</p>";
  } finally {
    reglamentoLoading.value = false;
  }
};

const onReglamentoScroll = () => {
  const el = reglamentoScrollRef.value;
  if (!el) return;
  const threshold = 10;
  if (el.scrollTop + el.clientHeight >= el.scrollHeight - threshold) {
    reglamentoScrolled.value = true;
  }
};

watch(currentStep, (step) => {
  closeHelp();
  if (step === 0) {
    fetchReglamento();
  } else {
    reglamentoFetchAttempted.value = false;
  }
}, { immediate: true });

watch([() => formData.nombre, () => formData.segundo_nombre], ([nombre, segundo_nombre]) => {
  formData.nombre_completo = [nombre, segundo_nombre].filter(Boolean).join(" ");
});

const getFieldIcon = (field) => {
  const k = field.key;
  if (k === "nombre" || k === "segundo_nombre" || k === "emergencia_nombre") return "ph:user";
  if (k === "apellido") return "ph:identification-card";
  if (k === "documentos") return "ph:cardholder";
  if (k === "correo" || k === "emergencia_correo") return "ph:envelope";
  if (k === "reglamento_firma") return "ph:signature";
  if (k === "fecha_nacimiento") return "ph:calendar";
  if (k === "nacionalidad" || k === "pais") return "ph:flag";
  if (k === "direccion_completa") return "ph:house";
  if (k === "direccion_postal") return "ph:map-pin";
  if (k === "ciudad") return "ph:city";
  if (k === "estado" || k === "postal") return "ph:map-pin";
  if (k === "telefono" || k === "whatsapp" || k === "emergencia_telefono") return "ph:phone";
  if (k === "profesion") return "ph:briefcase";
  if (k === "lugar_trabajo_actual") return "ph:buildings";
  if (k === "nivel_academico") return "ph:graduation-cap";
  if (k === "idioma_otro") return "ph:translate";
  if (k === "areas_otra") return "ph:plus-circle";
  if (k === "emergencia_parentesco") return "ph:users-three";
  if (field.type === "phone") return "ph:phone";
  if (field.type === "email") return "ph:envelope";
  if (field.type === "textarea") return "ph:note-pencil";
  if (field.type === "date") return "ph:calendar";
  return "ph:newspaper-clip";
};

const getFieldInputType = (field) => {
  if (field.type === "email") return "email";
  if (field.type === "phone") return "tel";
  if (field.type === "date") return "date";
  return "text";
};
</script>

<template>
  <div v-if="configError" class="text-center py-12 text-red-500">
    {{ tl("form.config_error") }}
  </div>

  <div v-else-if="!config" class="flex justify-center py-12">
    <span class="w-8 h-8 border-2 border-[#22523F] font-secondary border-t-transparent rounded-full animate-spin"></span>
  </div>

  <template v-else>
    <div v-if="!isSuccess" class="w-full max-w-3xl mx-auto md:px-4 sm:px-0">
      <div class="flex flex-wrap sm:flex-nowrap items-center justify-center gap-x-1 md:gap-x-2 gap-y-2 sm:gap-y-3 mb-4 sm:mb-6 lg:mb-8 overflow-x-auto">
        <template v-for="(step, index) in config.steps" :key="index">
          <button
            type="button"
            @click="goToStep(index)"
            class="flex flex-col lg:flex-row items-center gap-1 text-sm transition-colors text-center"
            :class="index === currentStep ? 'text-[#EBE6D2] font-bold' : 'text-[#EBE6D2]/60 hover:text-[#EBE6D2]'"
          >
            <span
              class="flex items-center justify-center w-7 h-7 rounded-full text-xs font-bold border-2 transition-colors shrink-0"
              :class="index === currentStep
                ? 'bg-[#CBA16A] text-[#22523F] border-[#CBA16A]'
                : index < currentStep
                  ? 'bg-[#EBE6D2] text-[#22523F] border-[#EBE6D2]'
                  : 'border-[#EBE6D2]/50 text-[#EBE6D2]/60'"
            >
              {{ index < currentStep ? '✓' : index + 1 }}
            </span>
            <span class="text-[10px] lg:text-xs leading-tight max-w-[60px] md:max-w-[70px] lg:max-w-none font-secondary">{{ tl(step.label) }}</span>
          </button>
          <span v-if="index < config.steps.length - 1" class="w-4 md:w-6 lg:w-8 h-px bg-[#EBE6D2]/30 shrink-0 hidden sm:inline"></span>
        </template>
      </div>

      <form @submit.prevent="handleSubmit" class="bg-[#EBE6D2] p-5 sm:p-8 lg:p-10 rounded-none w-auto">
        <h3 class="text-lg sm:text-xl font-bold text-[#22523F] mb-4 sm:mb-6 text-center font-secondary">
          {{ tl(currentStepData.label) }}
        </h3>

        <div v-if="currentStep === 0" class="mb-4 sm:mb-6">
          <div v-if="reglamentoLoading" class="flex justify-center py-8">
            <span class="w-8 h-8 border-2 border-[#22523F] border-t-transparent rounded-full animate-spin"></span>
          </div>
          <div v-else>
            <div
              ref="reglamentoScrollRef"
              class="md:max-h-[720px] max-h-[500px] overflow-y-auto border scrollbar-thin scrollbar-thumb-[#22523F] border-gray-300 p-4 bg-white reglamento-content"
              @scroll="onReglamentoScroll"
            >
              <div v-html="reglamentoHTML"></div>
            </div>
            <div class="flex items-center gap-2 mt-3">
              <Icon
                :icon="reglamentoScrolled ? 'ph:check-circle-fill' : 'ph:arrow-down'"
                :class="reglamentoScrolled ? 'text-green-600' : 'text-gray-400'"
                class="text-lg"
              />
              <span :class="reglamentoScrolled ? 'text-green-700 font-medium' : 'text-gray-500'" class="text-sm font-secondary">
                {{ reglamentoScrolled ? tl("form.reglamento_leido") : tl("form.reglamento_scroll_needed") }}
              </span>
            </div>
            <div v-if="!reglamentoScrolled" class="bg-amber-50 border-l-4 border-amber-400 text-amber-800 p-3 mt-3 text-sm flex items-start gap-2">
              <Icon icon="ph:info" class="text-lg mt-0.5 shrink-0" />
              <span class="font-secondary">{{ tl("form.reglamento_aviso") }}</span>
            </div>
          </div>
        </div>

        <div class="grid gap-4 sm:gap-5" :class="{ 'grid-cols-1': !currentStepData.column || currentStepData.column === 1, 'md:grid-cols-2': currentStepData.column === 2, 'md:grid-cols-3': currentStepData.column === 3 }">
          <template v-for="field in currentStepData.fields" :key="field.key">
            <div v-if="shouldShow(field)" class="flex flex-col gap-1.5" :class="{ 'md:col-span-2': field.colspan === 2 && currentStepData.column > 1, 'md:col-span-3': field.colspan === 3 && currentStepData.column > 1 }">

              <span class="text-[#22523F] font-secondary font-medium text-sm leading-tight inline-flex items-center">
                {{ tl(field.label) }}
                <span v-if="field.required" class="text-red-500 ml-0.5">*</span>
                <div v-if="fieldHelp(field.key)" class="relative inline-flex group cursor-help ml-1">
                  <button
                    type="button"
                    class="inline-flex items-center cursor-help"
                    :aria-expanded="!!helpOpen[field.key]"
                    aria-label="Ayuda"
                    @click.stop="toggleHelp(field.key)"
                  >
                    <Icon icon="ph:question" class="text-gray-400 text-sm" />
                  </button>
                  <div
                    class="absolute bottom-full mb-1 left-1/2 -translate-x-1/2 bg-gray-800 text-white text-xs rounded px-3 py-1.5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-20 shadow-lg w-64 whitespace-normal text-center leading-normal"
                    :class="helpOpen[field.key] ? 'opacity-100' : ''"
                  >
                    <span v-if="field.required" class="text-red-300 block">* {{ tl("form.required") }}</span>
                    <span v-else class="text-gray-300 block">{{ tl("form.optional") }}</span>
                    {{ fieldHelp(field.key) }}
                  </div>
                </div>
              </span>

              <div v-if="field.readonly" class="py-2.5 px-3 bg-gray-100 border border-gray-200 text-[#6B7280] rounded-xl min-h-[2.5rem] flex items-center text-sm">
                {{ field.valueFrom ? (formData[field.valueFrom] || "—") : (formData[field.key] || "—") }}
              </div>

              <label
                v-else-if="field.type === 'text' || field.type === 'email' || field.type === 'phone'"
                class="input w-full bg-white rounded-xl focus-within:outline-2 focus-within:outline-[#22523F]"
                :class="{ 'input-error border-red-500 focus-within:outline-red-500': getFieldError(field.key) }"
              >
                <Icon :icon="getFieldIcon(field)" class="shrink-0 opacity-50 text-gray-400 text-lg" />
                <input
                  class="grow text-[#1a1a1a]"
                  :type="getFieldInputType(field)"
                  v-model="formData[field.key]"
                  :placeholder="tl(field.placeholder || field.label)"
                  @input="field.type === 'phone' ? onPhoneInput(field.key, $event) : (stepErrors[field.key] = false)"
                />
              </label>

              <div
                v-else-if="field.type === 'date'"
                class="flex gap-2 w-full"
                :class="{ 'input-error': getFieldError(field.key) }"
              >
                <select
                  class="select select-bordered bg-white rounded-xl w-full focus:outline-2 focus:outline-[#22523F] text-[#1a1a1a]"
                  :class="{ 'border-red-500 focus:outline-red-500': getFieldError(field.key) }"
                  v-model="dateParts[field.key].day"
                  @change="composeDate(field.key)"
                >
                  <option :value="null" disabled>{{ tl("form.date.day") }}</option>
                  <option v-for="d in 31" :key="d" :value="d">{{ d }}</option>
                </select>
                <select
                  class="select select-bordered bg-white rounded-xl w-full focus:outline-2 focus:outline-[#22523F] text-[#1a1a1a]"
                  :class="{ 'border-red-500 focus:outline-red-500': getFieldError(field.key) }"
                  v-model="dateParts[field.key].month"
                  @change="composeDate(field.key)"
                >
                  <option :value="null" disabled>{{ tl("form.date.month") }}</option>
                  <option v-for="(m, i) in months" :key="i" :value="i + 1">{{ m }}</option>
                </select>
                <select
                  class="select select-bordered bg-white rounded-xl w-full focus:outline-2 focus:outline-[#22523F] text-[#1a1a1a]"
                  :class="{ 'border-red-500 focus:outline-red-500': getFieldError(field.key) }"
                  v-model="dateParts[field.key].year"
                  @change="composeDate(field.key)"
                >
                  <option :value="null" disabled>{{ tl("form.date.year") }}</option>
                  <option v-for="y in years" :key="y" :value="y">{{ y }}</option>
                </select>
              </div>

              <div v-if="field.type === 'date' && isMinorBetween12and18(field.key)" class="bg-amber-50 border-l-4 border-amber-400 text-amber-800 p-3 mt-1 text-sm flex items-start gap-2">
                <Icon icon="ph:info" class="text-lg mt-0.5 shrink-0" />
                <span class="font-secondary">{{ tl("form.fecha_nacimiento_menor_aviso") }}</span>
              </div>

              <div v-else-if="field.type === 'select'" class="relative">
                <label
                  class="input w-full bg-white rounded-xl focus-within:outline-2 focus-within:outline-[#22523F]"
                  :class="{ 'input-error border-red-500 focus-within:outline-red-500': getFieldError(field.key) }"
                >
                  <Icon :icon="getFieldIcon(field)" class="shrink-0 opacity-50 text-gray-400 text-lg" />
                  <select
                    class="grow text-[#1a1a1a] bg-transparent"
                    v-model="formData[field.key]"
                    @change="stepErrors[field.key] = false"
                  >
                    <option value="" disabled>{{ tl("form.select_placeholder", { label: tl(field.label) }) }}</option>
                    <option v-for="item in getSelectOptions(field)" :key="item.value" :value="item.value">
                      {{ item.label }}
                    </option>
                  </select>
                </label>
              </div>

              <div v-else-if="field.type === 'phone_country'" class="relative">
                <div class="join w-full">
                  <div class="join-item relative w-28">
                    <label
                      class="input border-gray-200 rounded-l-xl bg-white w-full focus-within:outline-2 focus-within:outline-[#22523F]"
                      :class="{ 'border-red-500': getFieldError(field.key) }"
                    >
                      <input
                        class="w-full text-[#1a1a1a]"
                        type="text"
                        autocomplete="off"
                        :value="getPhoneCountryDisplay(field.key)"
                        :placeholder="tl('form.phone_code_select')"
                        @input="onPhoneCountrySearchInput(field.key, $event)"
                        @focus="onPhoneCountrySearchFocus(field, field.key)"
                        @blur="onPhoneCountrySearchBlur(field.key)"
                      />
                    </label>
                    <ul
                      v-if="showCountrySuggestions[field.key] && filteredPhoneCountries(field, field.key).length"
                      class="absolute left-0 right-0 z-50 bg-white shadow-lg rounded-b-xl border border-gray-200 border-t-0 max-h-[200px] overflow-y-auto"
                    >
                      <li
                        v-for="item in filteredPhoneCountries(field, field.key)"
                        :key="item.value"
                        class="px-3 py-2 cursor-pointer text-sm text-[#1a1a1a] hover:bg-[#22523F]/10 transition-colors flex items-center gap-2"
                        @mousedown.prevent="onPhoneCountrySelect(field.key, item)"
                      >
                        <span>{{ item.flag }}</span>
                        <span class="font-mono">{{ item.dial_code }}</span>
                      </li>
                    </ul>
                  </div>
                  <label
                    class="input join-item grow bg-white rounded-r-xl border-gray-200 focus-within:outline-2 focus-within:outline-[#22523F]"
                    :class="{ 'border-red-500': getFieldError(field.key) }"
                  >
                    <input
                      class="grow text-[#1a1a1a]"
                      type="tel"
                      :placeholder="tl(field.placeholder || field.label)"
                      @input="onPhoneCountryNumberInput(field.key, $event)"
                    />
                  </label>
                </div>
              </div>

              <div v-else-if="field.type === 'autocomplete'" class="relative">
                <label
                  class="input w-full bg-white rounded-xl focus-within:outline-2 focus-within:outline-[#22523F]"
                  :class="{ 'input-error border-red-500 focus-within:outline-red-500': getFieldError(field.key) }"
                >
                  <Icon :icon="getFieldIcon(field)" class="shrink-0 opacity-50 text-gray-400 text-lg" />
                  <input
                    class="grow text-[#1a1a1a]"
                    type="text"
                    v-model="formData[field.key]"
                    :placeholder="tl(field.placeholder || field.label)"
                    autocomplete="off"
                    @input="stepErrors[field.key] = false; showSuggestions[field.key] = true"
                    @focus="onAutocompleteFocus(field)"
                    @blur="onAutocompleteBlur(field)"
                  />
                </label>
                <ul
                  v-if="showSuggestions[field.key] && filteredSuggestions(field).length"
                  class="absolute left-0 right-0 z-50 bg-white shadow-lg rounded-b-xl border border-gray-200 border-t-0 max-h-[200px] overflow-y-auto"
                >
                  <li
                    v-for="item in filteredSuggestions(field)"
                    :key="item.value"
                    class="px-4 py-2.5 cursor-pointer text-sm text-[#1a1a1a] hover:bg-[#22523F]/10 transition-colors"
                    @mousedown.prevent="selectSuggestion(field, item)"
                  >
                    {{ item.label }}
                  </li>
                </ul>
              </div>

              <div v-else-if="field.type === 'textarea'" class="relative">
                <Icon icon="ph:note-pencil" class="absolute left-3 top-3.5 text-gray-400 opacity-50 shrink-0 pointer-events-none text-lg" />
                <textarea
                  class="textarea w-full bg-white text-[#1a1a1a] pl-10 rounded-xl resize-none min-h-[6rem] focus:outline-2 focus:outline-[#22523F] focus:outline-offset-[-1px]"
                  :class="{ 'border-red-500 focus:outline-red-500': getFieldError(field.key) }"
                  v-model="formData[field.key]"
                  :placeholder="tl(field.placeholder || field.label)"
                  rows="4"
                  @input="stepErrors[field.key] = false"
                />
              </div>

              <div v-else-if="field.type === 'radio'" class="flex flex-wrap gap-x-5 gap-y-1">
                <label
                  v-for="opt in field.options"
                  :key="opt.value"
                  class="flex items-center gap-2 cursor-pointer p-1 -ml-1 rounded-lg hover:bg-[#22523F]/5 transition-colors"
                >
                  <input
                    type="radio"
                    :name="field.key"
                    :value="opt.value"
                    v-model="formData[field.key]"
                    class="radio radio-sm border-gray-300 bg-white checked:border-[#4A8C6F] checked:bg-[#4A8C6F]"
                    @change="stepErrors[field.key] = false"
                  />
                  <span class="text-[#1a1a1a] text-sm">{{ tl(opt.label) }}</span>
                </label>
              </div>

              <div v-else-if="field.type === 'checkbox'" class="flex flex-col gap-1">
                <div
                  v-for="opt in field.options"
                  :key="opt.value"
                  class="flex flex-col"
                >
                  <label
                    class="flex items-center gap-3 cursor-pointer p-1.5 rounded-lg transition-colors"
                    :class="currentStep === 0 && !reglamentoScrolled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-[#22523F]/5'"
                  >
                    <input
                      type="checkbox"
                      :value="opt.value"
                      :disabled="currentStep === 0 && !reglamentoScrolled"
                      class="checkbox checkbox-sm border-gray-300 bg-white checked:border-[#4A8C6F] checked:bg-[#4A8C6F]"
                      :checked="formData[field.key]?.includes(opt.value)"
                      @change="handleCheckboxChange(field.key, opt.value, $event.target.checked)"
                    />
                    <span class="text-[#1a1a1a] text-sm" v-html="tl(opt.label, { terms_url: termsUrl })"></span>
                  </label>
                  <div
                    v-if="formData[field.key]?.includes(opt.value) && field.levels"
                    class="flex flex-wrap gap-x-4 gap-y-1 ml-9 mt-1"
                  >
                    <label
                      v-for="lvl in field.levels.options"
                      :key="lvl.value"
                      class="flex items-center gap-1.5 cursor-pointer text-sm"
                    >
                      <input
                        type="radio"
                        :name="`${field.key}_nivel_${opt.value}`"
                        :value="lvl.value"
                        v-model="formData[`${field.key}_nivel_${opt.value}`]"
                        class="radio radio-sm border-gray-300 bg-white checked:border-[#4A8C6F] checked:bg-[#4A8C6F]"
                      />
                      <span class="text-[#1a1a1a]">{{ tl(lvl.label) }}</span>
                    </label>
                    <span
                      v-if="getFieldError(`${field.key}_nivel_${opt.value}`)"
                      class="text-red-500 text-xs"
                    >
                      {{ tl("form.required") }}
                    </span>
                  </div>
                </div>
              </div>

              <p
                v-if="getFieldError(field.key) && (field.type !== 'checkbox' || triedToProceed)"
                class="text-xs text-red-500 flex items-center gap-1 mt-0.5"
              >
                <Icon icon="ph:warning-circle" class="text-sm shrink-0" />
                {{ formatErrors[field.key] ? (field.type === "phone_country" ? tl("form.phone_number_invalid") : tl("form.phone_invalid")) : tl("form.required") }}
              </p>
            </div>
          </template>
        </div>

        <div v-if="isError && errorMsg" class="text-red-600 text-sm text-center mt-4">
          {{ errorMsg }}
        </div>

        <div v-if="isLastStep && props.turnstileSiteKey" class="flex justify-center my-4">
          <div ref="turnstileContainer"></div>
        </div>
        <input
          v-if="props.turnstileSiteKey"
          type="text"
          name="website"
          v-model="honeypot"
          class="hidden"
          autocomplete="off"
          tabindex="-1"
        />

        <div class="border-t border-gray-300/30 mt-6 sm:mt-8 mb-4 sm:mb-6"></div>

        <div class="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-3">

          <div class="flex justify-center sm:hidden">
            <span class="text-xs text-gray-500 font-secondary font-medium">
              {{ tl("form.step_counter", { current: currentStep + 1, total: totalSteps }) }}
            </span>
          </div>

          <div class="flex justify-between items-center w-full sm:contents">
            <button
              v-if="!isFirstStep"
              type="button"
              @click="prevStep"
              class="btn bg-white border border-gray-200 text-gray-500 hover:bg-gray-50 hover:text-gray-700"
            >
              <Icon icon="ph:arrow-left" class="text-lg" />
              {{ tl("form.back") }}
            </button>
            <div v-else></div>

            <div class="flex items-center gap-3">
              <span class="hidden sm:inline text-xs text-gray-500 font-secondary font-medium whitespace-nowrap">
                {{ tl("form.step_counter", { current: currentStep + 1, total: totalSteps }) }}
              </span>

              <div class="relative group">
                <button
                  v-if="!isLastStep"
                  type="button"
                  @click="nextStep"
                  :disabled="currentStep === 0 && !reglamentoScrolled"
                  class="btn rounded-none text-sm sm:text-base px-3 sm:px-4"
                  :class="currentStep === 0 && !reglamentoScrolled
                    ? 'bg-gray-300 text-gray-500 cursor-not-allowed'
                    : 'bg-[#22523F] text-white hover:bg-[#1a3d2f]'"
                >
                  {{ tl("form.next") }}
                  <Icon icon="ph:arrow-right" class="text-base sm:text-lg" />
                </button>
                <div
                  v-if="currentStep === 0 && !reglamentoScrolled"
                  class="absolute bottom-full mb-1 sm:mb-2 right-0 w-64 max-w-[80vw] whitespace-normal text-center leading-normal bg-gray-800 text-white text-xs rounded px-3 py-1.5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-10 shadow-lg"
                >
                  {{ tl("form.reglamento_tooltip") }}
                </div>
                <div
                  v-else-if="remainingRequired > 0"
                  class="absolute bottom-full mb-1 sm:mb-2 right-0 w-64 max-w-[80vw] whitespace-normal text-center leading-normal bg-gray-800 text-white text-xs rounded px-3 py-1.5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none z-10 shadow-lg"
                >
                  {{ tl(remainingRequired === 1 ? "form.remaining_required_one" : "form.remaining_required", { count: remainingRequired }) }}
                </div>
              </div>

              <button
                v-if="isLastStep"
                type="submit"
                :disabled="isSubmitting"
                class="btn rounded-none px-3 sm:px-5 transition-colors text-xs sm:text-sm leading-tight min-w-0"
                :class="isSubmitting
                  ? 'bg-gray-400 text-white cursor-not-allowed'
                  : 'bg-[#22523F] text-white hover:bg-[#1a3d2f]'"
              >
                <span v-if="isSubmitting" class="flex items-center gap-1 sm:gap-2">
                  <span class="w-3 h-3 sm:w-4 sm:h-4 border-2 border-white border-t-transparent rounded-full animate-spin shrink-0"></span>
                  <span class="truncate">{{ tl("form.sending") }}</span>
                </span>
                <span v-else class="truncate">
                  {{ tl(config.submit_label) }}
                </span>
              </button>
            </div>
          </div>

        </div>
      </form>
  </div>

  <div v-else class="w-full max-w-3xl mx-auto md:px-4 sm:px-0">
    <div class="bg-[#EBE6D2] p-8 sm:p-12 rounded-none text-center">
      <img
        src="/img/logo-metalico.webp"
        alt="Logo Centro del Reino de Paz y Justicia"
        class="w-20 h-20 sm:w-28 sm:h-28 mx-auto mb-6"
      />
      <h2 class="text-xl sm:text-2xl font-bold text-[#22523F] font-secondary mb-4">
        {{ tl("form.success_title") }}
      </h2>
      <p class="text-[#1a1a1a]/80 text-sm sm:text-base max-w-lg mx-auto mb-8 leading-relaxed">
        {{ tl("form.success_info") }}
      </p>
      <div class="bg-[#22523F]/5 border border-[#22523F]/10 rounded-xl p-5 sm:p-6 text-left text-sm text-gray-600 max-w-lg mx-auto mb-8">
        <div class="flex items-start gap-3">
          <Icon icon="ph:info" class="text-[#22523F] text-lg mt-0.5 shrink-0" />
          <p>{{ tl("form.success_detail") }}</p>
        </div>
      </div>
      <a :href="`/${props.locale}`" class="btn bg-[#22523F] text-white hover:bg-[#1a3d2f] rounded-none px-8">
        {{ tl("form.back_home") }}
      </a>
    </div>
  </div>

  </template>
</template>

<style>
.reglamento-content h2 {
  color: #22523F;
  font-size: 1.25rem;
  font-weight: 700;
  margin-top: 1.5rem;
  margin-bottom: 0.75rem;
}
.reglamento-content h2:first-of-type {
  margin-top: 0;
}
.reglamento-content p {
  color: #374151;
  line-height: 1.625;
  margin-bottom: 0.75rem;
}
.reglamento-content ul {
  list-style: disc;
  padding-left: 1.5rem;
  margin-bottom: 0.75rem;
}
.reglamento-content li {
  color: #374151;
  line-height: 1.625;
  margin-bottom: 0.25rem;
}
.reglamento-content h1 {
  color: #22523F;
  font-size: 1.5rem;
  font-weight: 800;
  margin-bottom: 0.25rem;
}
.reglamento-content > p:first-of-type {
  color: #6B7280;
  font-size: 0.875rem;
  margin-bottom: 1.5rem;
}
</style>
