<script setup lang="ts">
import { ref, computed, watch, onUnmounted } from "vue";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Search,
  MapPin,
  CheckCircle2,
  XCircle,
  Loader2,
  ArrowLeft,
  Zap,
  Mail,
  Phone,
  Send,
} from "lucide-vue-next";
import { z } from "zod";

// Address search via our own API (no Supabase dependency)
const API_BASE = import.meta.env.VITE_API_BASE || "";

const phoneClean = (v: string) => v.replace(/[\s\-().]/g, "");

const contactSchema = z.union([
  z.string().trim().email().max(254),
  z.string().trim().transform(phoneClean).pipe(
    z.string().regex(/^\+?1?\d{10,11}$/, "Numéro invalide"),
  ),
]);

const CONTACT_COOLDOWN_MS = 5000;

interface AddressResult {
  id: number;
  address_full: string;
  numero: string;
  rue: string;
  ville: string;
  code_postal: string;
  longitude: number;
  latitude: number;
  fiber_available: boolean;
  zone_tarifaire: number;
  max_speed: number;
  similarity_score: number;
}

type Step = "search" | "result";

const props = defineProps<{ open: boolean }>();
const emit = defineEmits<{ "update:open": [value: boolean] }>();

const openModel = computed({
  get: () => props.open,
  set: (v: boolean) => emit("update:open", v),
});

const query = ref("");
const results = ref<AddressResult[]>([]);
const searching = ref(false);
const selected = ref<AddressResult | null>(null);
const step = ref<Step>("search");
const checking = ref(false);
const contactValue = ref("");
const contactSent = ref(false);
const sendingContact = ref(false);
const contactError = ref("");
let lastSubmit = 0;
let debounceTimer: ReturnType<typeof setTimeout> | undefined;

// Reset on close
watch(
  () => props.open,
  (open) => {
    if (!open) {
      setTimeout(() => {
        query.value = "";
        results.value = [];
        selected.value = null;
        step.value = "search";
        contactValue.value = "";
        contactSent.value = false;
      }, 300);
    }
  },
);

// Cleanup debounce on unmount
onUnmounted(() => {
  if (debounceTimer) clearTimeout(debounceTimer);
});

const searchAddresses = async (term: string) => {
  if (term.length < 3) {
    results.value = [];
    return;
  }
  searching.value = true;
  try {
    const res = await fetch(API_BASE + "/rpc/search_addresses", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ search_term: term, result_limit: 8 }),
    });
    if (res.ok) {
      const data = await res.json();
      results.value = data as AddressResult[];
    }
  } finally {
    searching.value = false;
  }
};

const handleQueryChange = (value: string) => {
  query.value = value;
  if (debounceTimer) clearTimeout(debounceTimer);
  debounceTimer = setTimeout(() => searchAddresses(value), 350);
};

const handleValidate = async (address: AddressResult) => {
  selected.value = address;
  checking.value = true;
  step.value = "result";

  // Log the search (fire and forget)
  try {
    console.log("[Search]", query.value, "→", address.address_full, address.fiber_available);
  } catch (e) {
    console.error("Log search error:", e);
  }

  // Small delay for UX
  await new Promise((r) => setTimeout(r, 800));
  checking.value = false;
};

const handleContactSubmit = async () => {
  if (!contactValue.value.trim() || !selected.value) return;

  // Rate limit
  const now = Date.now();
  if (now - lastSubmit < CONTACT_COOLDOWN_MS) {
    contactError.value = "Veuillez patienter quelques secondes.";
    return;
  }

  // Validate contact
  const result = contactSchema.safeParse(contactValue.value.trim());
  if (!result.success) {
    contactError.value = "Veuillez entrer un courriel ou numéro de mobile valide.";
    return;
  }
  contactError.value = "";
  sendingContact.value = true;
  lastSubmit = now;

  const validContact = result.data;

  // Send lead notification via Mailjet
  try {
    await fetch(API_BASE + "/rpc/lead", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        contact: validContact,
        address: selected.value.address_full,
        fiber_available: selected.value.fiber_available,
        max_speed: selected.value.max_speed || 0,
      }),
    });
  } catch (e) {
    console.error("Lead send error:", e);
  }

  sendingContact.value = false;
  contactSent.value = true;
};

const speedLabel = (speed: number) => {
  if (!speed || speed === 0) return "1.5 Gbit/s";
  if (speed >= 1000) return `${(speed / 1000).toFixed(1)} Gbit/s`;
  return `${speed} Mbit/s`;
};

const backToSearch = () => {
  step.value = "search";
  selected.value = null;
  contactSent.value = false;
  contactValue.value = "";
};
</script>

<template>
  <Dialog v-model:open="openModel">
    <DialogContent class="sm:max-w-lg max-h-[85vh] overflow-hidden flex flex-col top-[8%] translate-y-0 sm:top-[50%] sm:translate-y-[-50%]">
      <DialogHeader>
        <DialogTitle class="flex items-center gap-2 text-xl">
          <Zap class="w-5 h-5 text-targo-green" />
          Vérifier la disponibilité
        </DialogTitle>
        <DialogDescription>
          Entrez votre adresse pour vérifier si la fibre optique est disponible
        </DialogDescription>
      </DialogHeader>

      <Transition mode="out-in">
        <div
          v-if="step === 'search'"
          key="search"
          v-motion
          :initial="{ opacity: 0, x: -20 }"
          :enter="{ opacity: 1, x: 0 }"
          :leave="{ opacity: 0, x: -20 }"
          class="space-y-4 flex-1 overflow-hidden flex flex-col"
        >
          <!-- Search input -->
          <div class="relative">
            <Search class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground" />
            <Input
              placeholder="Ex: 1933 Avenue Goulet, Montréal"
              :model-value="query"
              class="pl-10"
              autofocus
              @update:model-value="(v) => handleQueryChange(String(v))"
            />
            <Loader2 v-if="searching" class="absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 animate-spin text-muted-foreground" />
          </div>

          <!-- Results list -->
          <div class="flex-1 overflow-y-auto space-y-1 max-h-[50vh]">
            <p v-if="results.length === 0 && query.length >= 3 && !searching" class="text-sm text-muted-foreground text-center py-8">
              Aucune adresse trouvée
            </p>
            <button
              v-for="addr in results"
              :key="addr.id"
              class="w-full text-left p-3 rounded-lg border border-border hover:border-targo-green hover:bg-targo-green/5 transition-all duration-200 group"
              @click="handleValidate(addr)"
            >
              <div class="flex items-start gap-3">
                <MapPin class="w-4 h-4 mt-0.5 text-muted-foreground group-hover:text-targo-green shrink-0" />
                <div class="min-w-0">
                  <p class="text-sm font-medium truncate">
                    {{ addr.address_full }}
                  </p>
                  <p class="text-xs text-muted-foreground">
                    {{ addr.ville }} {{ addr.code_postal }}
                  </p>
                </div>
                <span v-if="addr.fiber_available" class="ml-auto shrink-0 text-[10px] font-bold uppercase tracking-wider text-targo-green bg-targo-green/10 px-2 py-0.5 rounded-full">
                  Fibre
                </span>
              </div>
            </button>
          </div>
        </div>

        <div
          v-else-if="step === 'result' && selected"
          key="result"
          v-motion
          :initial="{ opacity: 0, x: 20 }"
          :enter="{ opacity: 1, x: 0 }"
          :leave="{ opacity: 0, x: 20 }"
          class="space-y-6"
        >
          <div v-if="checking" class="flex flex-col items-center py-12 gap-4">
            <Loader2 class="w-10 h-10 animate-spin text-targo-green" />
            <p class="text-sm text-muted-foreground">
              Vérification en cours…
            </p>
          </div>
          <!-- ✅ AVAILABLE -->
          <div v-else-if="selected.fiber_available" class="space-y-6">
            <div class="text-center space-y-3">
              <div class="w-16 h-16 rounded-full bg-targo-green/10 flex items-center justify-center mx-auto">
                <CheckCircle2 class="w-8 h-8 text-targo-green" />
              </div>
              <h3 class="text-xl font-bold text-foreground">
                Félicitations !
              </h3>
              <p class="text-muted-foreground text-sm">
                Le service est disponible à votre adresse jusqu'à{{ " " }}
                <span class="font-bold text-targo-green">
                  {{ speedLabel(selected.max_speed) }}
                </span>
              </p>
              <div class="bg-primary/5 border border-primary/20 rounded-xl p-4 mt-2">
                <p class="text-xs text-muted-foreground mb-1">Votre forfait</p>
                <p class="text-2xl font-bold text-primary font-display">
                  À partir de 39<sup class="text-sm">,95</sup>$/mois
                </p>
              </div>
              <p class="text-xs text-muted-foreground bg-muted/50 rounded-lg p-3">
                <MapPin class="inline w-3 h-3 mr-1" />
                {{ selected.address_full }}
              </p>
            </div>

            <div v-if="!contactSent" class="space-y-3">
              <p class="text-sm font-medium text-center">
                Inscrivez votre courriel ou numéro de mobile pour
                démarrer votre abonnement
              </p>
              <div class="space-y-1">
                <div class="flex gap-2">
                  <Input
                    placeholder="courriel ou mobile"
                    :model-value="contactValue"
                    class="flex-1"
                    :maxlength="254"
                    @update:model-value="(v) => { contactValue = String(v); contactError = ''; }"
                  />
                  <Button
                    :disabled="!contactValue.trim() || sendingContact"
                    class="gradient-targo"
                    @click="handleContactSubmit"
                  >
                    <Loader2 v-if="sendingContact" class="w-4 h-4 animate-spin" />
                    <Send v-else class="w-4 h-4" />
                  </Button>
                </div>
                <p v-if="contactError" class="text-xs text-destructive">{{ contactError }}</p>
              </div>
            </div>
            <div v-else class="text-center text-sm text-targo-green font-medium bg-targo-green/10 rounded-lg p-4">
              <CheckCircle2 class="w-5 h-5 mx-auto mb-2" />
              Merci ! Nous vous contacterons très bientôt.
            </div>
          </div>
          <!-- ❌ NOT AVAILABLE -->
          <div v-else class="space-y-6">
            <div class="text-center space-y-3">
              <div class="w-16 h-16 rounded-full bg-destructive/10 flex items-center justify-center mx-auto">
                <XCircle class="w-8 h-8 text-destructive" />
              </div>
              <h3 class="text-xl font-bold text-foreground">
                Adresse non confirmée
              </h3>
              <p class="text-muted-foreground text-sm">
                Nous n'arrivons pas à confirmer la disponibilité pour
                votre adresse.
              </p>
              <p class="text-xs text-muted-foreground bg-muted/50 rounded-lg p-3">
                <MapPin class="inline w-3 h-3 mr-1" />
                {{ selected.address_full }}
              </p>
            </div>

            <div class="space-y-4">
              <div class="flex items-center justify-center gap-4 text-sm">
                <a
                  href="tel:18558882746"
                  class="flex items-center gap-2 text-targo-green hover:underline font-medium"
                >
                  <Phone class="w-4 h-4" />
                  1-855-888-2746
                </a>
              </div>

              <div class="text-center text-xs text-muted-foreground">
                ou inscrivez votre courriel et nous vous contacterons
              </div>

              <div v-if="!contactSent" class="space-y-1">
                <div class="flex gap-2">
                  <Input
                    placeholder="votre courriel"
                    :model-value="contactValue"
                    class="flex-1"
                    :maxlength="254"
                    @update:model-value="(v) => { contactValue = String(v); contactError = ''; }"
                  />
                  <Button
                    :disabled="!contactValue.trim() || sendingContact"
                    variant="outline"
                    class="border-targo-green text-targo-green hover:bg-targo-green/5"
                    @click="handleContactSubmit"
                  >
                    <Loader2 v-if="sendingContact" class="w-4 h-4 animate-spin" />
                    <Mail v-else class="w-4 h-4" />
                  </Button>
                </div>
                <p v-if="contactError" class="text-xs text-destructive">{{ contactError }}</p>
              </div>
              <div v-else class="text-center text-sm text-targo-green font-medium bg-targo-green/10 rounded-lg p-4">
                <CheckCircle2 class="w-5 h-5 mx-auto mb-2" />
                Merci ! Nous vous contacterons très bientôt.
              </div>
            </div>
          </div>

          <Button
            variant="ghost"
            size="sm"
            class="w-full"
            @click="backToSearch"
          >
            <ArrowLeft class="w-4 h-4 mr-2" />
            Rechercher une autre adresse
          </Button>
        </div>
      </Transition>
    </DialogContent>
  </Dialog>
</template>
