"use client";

import * as React from "react";
import { useConvex } from "convex/react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import { CalendarSearch, ChevronRight, Headset, MessageCircle, Phone, PhoneCall, Star, X } from "lucide-react";
import { api } from "../../../convex/_generated/api";
import { cn } from "@/lib/utils";
import { fmtDate, parseDay } from "@/lib/dates";
import { LeadForm, type LeadContext } from "./lead-form";
import { track } from "./fb-pixel";
import type { Business } from "./showroom-page";

const digitsOf = (s: string) => s.replace(/[^\d]/g, "");
const spring = { type: "spring", stiffness: 420, damping: 34 } as const;
const ONLINE_MS = 3 * 60_000;

/**
 * Is the desk staffed? Read once on arrival and again each time the visitor
 * opens the panel — deliberately not a live subscription, because every
 * visitor holding one would re-run on each staff heartbeat. The verdict is
 * recomputed on a local timer so the dot still greys out when the team leaves.
 */
function useDeskOnline(open: boolean) {
  const convex = useConvex();
  const [seenAt, setSeenAt] = React.useState<number | null>(null);
  const [, tick] = React.useReducer((n: number) => n + 1, 0);
  const read = React.useCallback(() => {
    let alive = true;
    convex
      .query(api.showroom.presence, {})
      .then((r) => alive && setSeenAt((r as { lastSeenAt: number | null }).lastSeenAt))
      .catch(() => {});
    return () => {
      alive = false;
    };
  }, [convex]);
  React.useEffect(() => read(), [read]);
  React.useEffect(() => (open ? read() : undefined), [open, read]);
  React.useEffect(() => {
    const t = setInterval(tick, 30_000);
    return () => clearInterval(t);
  }, []);
  return seenAt !== null && Date.now() - seenAt < ONLINE_MS;
}

/**
 * Always-there way to reach the desk. Desktop: a floating bubble that opens
 * a small "talk to us" card with an honest online dot, quick questions that
 * open WhatsApp already written, and a call-back form. Phone: a sticky
 * bottom bar with WhatsApp, Call and Dates — the three things an ad visitor
 * does.
 */
export function ContactDock({ business, ctx, onDates, reviewsAvailable }: { business: Business; ctx: LeadContext; onDates: () => void; reviewsAvailable: boolean }) {
  const reduced = useReducedMotion();
  const [open, setOpen] = React.useState(false);
  const online = useDeskOnline(open);
  const [mode, setMode] = React.useState<"chat" | "callback">("chat");
  const [seen, setSeen] = React.useState(false);
  const wa = digitsOf(business.whatsapp);
  const nights = ctx.checkIn && ctx.checkOut ? Math.round((Date.parse(ctx.checkOut) - Date.parse(ctx.checkIn)) / 864e5) : 0;
  const stay = nights > 0 ? `${fmtDate(parseDay(ctx.checkIn!), { style: "short" })} → ${fmtDate(parseDay(ctx.checkOut!), { style: "short" })}` : "";

  // A gentle nudge after 18 s of browsing: the bubble grows a label once.
  React.useEffect(() => {
    const t = setTimeout(() => setSeen(true), 18_000);
    return () => clearTimeout(t);
  }, []);
  React.useEffect(() => {
    if (!open) return;
    const onKey = (e: KeyboardEvent) => e.key === "Escape" && setOpen(false);
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  const quick = [
    ctx.apartment ? { label: `Is ${ctx.apartment.name} free${stay ? ` ${stay}` : ""}?`, text: `Hello ${business.name}, is ${ctx.apartment.name} (${ctx.apartment.code}) available${stay ? ` from ${ctx.checkIn} to ${ctx.checkOut}` : ""}?` } : { label: stay ? `What is free ${stay}?` : "What is free tonight?", text: `Hello ${business.name}, which apartments are free${stay ? ` from ${ctx.checkIn} to ${ctx.checkOut}` : " tonight"}${ctx.guests ? ` for ${ctx.guests} guest${ctx.guests! > 1 ? "s" : ""}` : ""}?` },
    { label: "Send me photos & prices", text: `Hello ${business.name}, could you send me photos and prices${ctx.apartment ? ` for ${ctx.apartment.name}` : ""}?` },
    { label: "I want to book now", text: `Hello ${business.name}, I want to book${ctx.apartment ? ` ${ctx.apartment.name} (${ctx.apartment.code})` : " an apartment"}${stay ? ` from ${ctx.checkIn} to ${ctx.checkOut}` : ""}. How do we proceed?` },
  ];
  const waLink = (text: string) => `https://wa.me/${wa}?text=${encodeURIComponent(text)}`;
  const status = online ? `Team online · replies in ~${Math.max(1, business.replyMinutes || 5)} min` : "We reply as soon as we are back — usually within the hour";

  return (
    <>
      {/* Phone: sticky bottom bar */}
      <div className="fixed inset-x-0 bottom-0 z-40 p-2.5 pb-[calc(0.625rem+env(safe-area-inset-bottom))] md:hidden" aria-label="Contact bar">
        <motion.div initial={reduced ? false : { y: 80, opacity: 0 }} animate={{ y: 0, opacity: 1 }} transition={{ ...spring, delay: 0.6 }} className="glass flex items-stretch gap-1.5 rounded-2xl p-1.5 shadow-2xl">
          {wa ? (
            <a href={waLink(quick[2].text)} target="_blank" rel="noreferrer" onClick={() => track("Contact", { method: "whatsapp" })} className="flex flex-1 items-center justify-center gap-2 rounded-xl bg-[#25D366] px-3 py-2.5 text-sm font-semibold text-white shadow-[0_0_0_0_rgb(37_211_102/0.5)] animate-glow-pulse active:scale-95">
              <MessageCircle className="size-4" /> WhatsApp
            </a>
          ) : null}
          <a href={`tel:${business.phone}`} onClick={() => track("Contact", { method: "call" })} className="flex flex-1 items-center justify-center gap-2 rounded-xl bg-surface px-3 py-2.5 text-sm font-semibold ring-1 ring-border active:scale-95">
            <Phone className="size-4" /> Call
          </a>
          <button type="button" onClick={onDates} className="flex items-center justify-center gap-2 rounded-xl bg-primary px-3 py-2.5 text-sm font-semibold text-primary-fg active:scale-95" aria-label="Check dates">
            <CalendarSearch className="size-4" />
          </button>
          <button type="button" onClick={() => setOpen(true)} className="relative flex items-center justify-center rounded-xl bg-surface px-3 ring-1 ring-border active:scale-95" aria-label="Talk to us">
            <Headset className="size-4" />
            <span className={cn("absolute right-1.5 top-1.5 size-2 rounded-full ring-2 ring-surface", online ? "bg-positive-500 live-dot" : "bg-fg-subtle")} />
          </button>
        </motion.div>
      </div>

      {/* Desktop: floating bubble */}
      <div className="fixed bottom-6 right-6 z-40 hidden md:block">
        <AnimatePresence>
          {!open ? (
            <motion.button key="bubble" type="button" onClick={() => setOpen(true)} initial={reduced ? false : { scale: 0, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} exit={{ scale: 0.6, opacity: 0 }} transition={spring} className="group flex items-center gap-3 rounded-full bg-primary py-2 pl-2 pr-5 text-primary-fg shadow-xl shadow-primary/30 transition hover:shadow-2xl hover:shadow-primary/40 active:scale-95 animate-glow-pulse" aria-label="Talk to us">
              <span className="relative flex size-10 items-center justify-center rounded-full bg-white/15">
                <Headset className="size-5" />
                <span className={cn("absolute -right-0.5 -top-0.5 size-3 rounded-full ring-2 ring-primary", online ? "bg-positive-400 live-dot" : "bg-white/50")} />
              </span>
              <span className="text-left leading-tight">
                <span className="block text-sm font-semibold">{seen ? "Questions? We're here" : "Talk to us"}</span>
                <span className="block text-[11px] text-primary-fg/75">{online ? "Online now" : "Leave a message"}</span>
              </span>
            </motion.button>
          ) : null}
        </AnimatePresence>
      </div>

      {/* Panel (both) */}
      <AnimatePresence>
        {open ? (
          <>
            <motion.div key="bd" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className="fixed inset-0 z-40 bg-stone-950/40 backdrop-blur-[2px] md:bg-transparent md:backdrop-blur-none" onClick={() => setOpen(false)} />
            <motion.aside key="panel" role="dialog" aria-label="Talk to us" initial={reduced ? false : { y: 40, opacity: 0, scale: 0.96 }} animate={{ y: 0, opacity: 1, scale: 1 }} exit={{ y: 30, opacity: 0, scale: 0.96 }} transition={spring} className="glass fixed inset-x-2 bottom-2 z-50 overflow-hidden rounded-3xl shadow-2xl md:inset-auto md:bottom-6 md:right-6 md:w-[380px]">
              <div className="brand-tile relative p-4 text-white">
                <button type="button" onClick={() => setOpen(false)} className="absolute right-3 top-3 flex size-8 items-center justify-center rounded-full bg-white/15 transition hover:rotate-90 hover:bg-white/25" aria-label="Close"><X className="size-4" /></button>
                <p className="flex items-center gap-2 text-2xs font-semibold uppercase tracking-[0.2em] text-white/70"><Headset className="size-3.5" /> {business.name}</p>
                <p className="mt-1 font-display text-2xl font-medium leading-tight">How can we help?</p>
                <p className="mt-1 flex items-center gap-1.5 text-xs text-white/85"><span className={cn("size-2 rounded-full", online ? "bg-positive-400 live-dot" : "bg-white/50")} /> {status}</p>
              </div>
              <div className="max-h-[70dvh] overflow-y-auto p-3 scrollbar-thin">
                <div className="mb-2 flex gap-1 rounded-xl bg-surface-2 p-1">
                  {(["chat", "callback"] as const).map((m) => (
                    <button key={m} type="button" onClick={() => setMode(m)} className={cn("relative flex-1 rounded-lg py-1.5 text-xs font-semibold transition", mode === m ? "text-fg" : "text-fg-muted")}>
                      {mode === m ? <motion.span layoutId="dock-mode" className="absolute inset-0 rounded-lg bg-surface shadow-xs" transition={spring} /> : null}
                      <span className="relative">{m === "chat" ? "Message now" : "Call me back"}</span>
                    </button>
                  ))}
                </div>
                <AnimatePresence mode="wait" initial={false}>
                  {mode === "chat" ? (
                    <motion.div key="chat" initial={{ opacity: 0, x: -10 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -10 }} className="space-y-1.5">
                      {quick.map((qk, i) => (
                        <motion.a key={qk.label} href={waLink(qk.text)} target="_blank" rel="noreferrer" onClick={() => track("Contact", { method: "whatsapp", content_name: qk.label })} initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.05 * i }} className="flex items-center gap-3 rounded-xl border border-border bg-surface px-3 py-2.5 text-sm transition hover:border-[#25D366]/60 hover:bg-[#25D366]/5 active:scale-[0.98]">
                          <span className="flex size-8 shrink-0 items-center justify-center rounded-full bg-[#25D366]/15 text-[#128C4B]"><MessageCircle className="size-4" /></span>
                          <span className="flex-1 font-medium">{qk.label}</span>
                          <ChevronRight className="size-4 text-fg-subtle" />
                        </motion.a>
                      ))}
                      <a href={`tel:${business.phone}`} onClick={() => track("Contact", { method: "call" })} className="flex items-center gap-3 rounded-xl border border-border bg-surface px-3 py-2.5 text-sm transition hover:border-primary/50 active:scale-[0.98]">
                        <span className="flex size-8 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary"><PhoneCall className="size-4" /></span>
                        <span className="flex-1 font-medium">Call {business.phone}</span>
                        <ChevronRight className="size-4 text-fg-subtle" />
                      </a>
                      {reviewsAvailable && business.reviewUrl ? (
                        <a href={business.reviewUrl} target="_blank" rel="noreferrer" className="flex items-center gap-3 rounded-xl px-3 py-2 text-xs text-fg-muted transition hover:text-fg">
                          <Star className="size-3.5 text-gold-500" /> Stayed with us? Share your experience on Google
                        </a>
                      ) : null}
                    </motion.div>
                  ) : (
                    <motion.div key="cb" initial={{ opacity: 0, x: 10 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 10 }} className="p-1">
                      <LeadForm business={business} ctx={ctx} kind="CALLBACK" compact subtitle="Leave your number — a real person calls you." />
                    </motion.div>
                  )}
                </AnimatePresence>
              </div>
            </motion.aside>
          </>
        ) : null}
      </AnimatePresence>
    </>
  );
}
