import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useQueryClient } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { MapPin, Sun, Loader2, Sparkles, Star, X, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useAuth } from "@/hooks/useAuth";
import { supabase } from "@/integrations/supabase/client";
import {
  SEGMENTS,
  PROPERTY_TYPES,
  ROOM_TYPE_OPTIONS,
  COMMON_FACILITIES,
  PMS_OPTIONS,
  POS_OPTIONS,
  CHANNEL_MANAGER_OPTIONS,
  BOOKING_ENGINE_OPTIONS,
  PAYMENT_GATEWAY_OPTIONS,
  INVOICING_OPTIONS,
  DYNAMIC_PRICING_OPTIONS,
  REVIEW_MGMT_OPTIONS,
  WEBSITE_BUILDER_OPTIONS,
  type Hotel,
} from "@/lib/hotel";
import { lookupHotel, searchHotels, type HotelSuggestion } from "@/lib/briefing.functions";
import { authHeaders } from "@/lib/authHeaders";
import { toast } from "sonner";

export const Route = createFileRoute("/onboarding")({
  validateSearch: (s: Record<string, unknown>) => ({
    hotelId: typeof s.hotelId === "string" ? s.hotelId : undefined,
  }),
  head: () => ({ meta: [{ title: "Set up your hotel — The Daily Ledger" }] }),
  component: OnboardingPage,
});

function OnboardingPage() {
  const { user, loading } = useAuth();
  const navigate = useNavigate();
  const qc = useQueryClient();
  const { hotelId } = Route.useSearch();
  const [editingHotelId, setEditingHotelId] = useState<string | null>(hotelId ?? null);
  const [busy, setBusy] = useState(false);
  const [locating, setLocating] = useState(false);
  const [looking, setLooking] = useState(false);
  const [showSensitive, setShowSensitive] = useState(false);
  const [suggestions, setSuggestions] = useState<HotelSuggestion[]>([]);
  const [searching, setSearching] = useState(false);
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [suppressSearch, setSuppressSearch] = useState(false);
  const [form, setForm] = useState({
    hotelier_name: "",
    hotel_name: "",
    location: "",
    latitude: null as number | null,
    longitude: null as number | null,
    rooms: 50,
    star_rating: null as number | null,
    property_type: "Hotel" as string,
    segment: "Business" as string,
    amenities: [] as string[],
    room_types: [] as string[],
    adr_weekday: 250 as number | null,
    adr_weekend: 320 as number | null,
    occupancy_pct: 65 as number | null,
    pms: "" as string,
    restaurant_pos: "" as string,
    channel_manager: "" as string,
    booking_engine: "" as string,
    payment_gateway: "" as string,
    invoicing: "" as string,
    dynamic_pricing: "" as string,
    review_mgmt: "" as string,
    website_builder: "" as string,
  });

  useEffect(() => {
    if (!loading && !user) {
      navigate({ to: "/login" });
      return;
    }
    if (!user) return;
    // If hotelId provided, edit that one; otherwise this is "add new" flow
    if (!editingHotelId) {
      setForm((f) => ({
        ...f,
        hotelier_name: user.user_metadata?.full_name || user.email?.split("@")[0] || "",
      }));
      return;
    }
    supabase
      .from("hotels")
      .select("*")
      .eq("id", editingHotelId)
      .eq("user_id", user.id)
      .maybeSingle()
      .then(({ data }) => {
        if (data) {
          const h = data as Hotel;
          setForm({
            hotelier_name: h.hotelier_name || user.user_metadata?.full_name || "",
            hotel_name: h.hotel_name,
            location: h.location,
            latitude: h.latitude,
            longitude: h.longitude,
            rooms: h.rooms || 50,
            star_rating: h.star_rating ?? null,
            property_type: h.property_type ?? "Hotel",
            segment: h.segment ?? "Business",
            amenities: h.amenities ?? [],
            room_types: h.room_types ?? [],
            adr_weekday: h.adr_weekday ?? 250,
            adr_weekend: h.adr_weekend ?? 320,
            occupancy_pct: h.occupancy_pct ?? 65,
            pms: h.pms ?? "",
            restaurant_pos: h.restaurant_pos ?? "",
            channel_manager: h.channel_manager ?? "",
            booking_engine: h.booking_engine ?? "",
            payment_gateway: h.payment_gateway ?? "",
            invoicing: h.invoicing ?? "",
            dynamic_pricing: h.dynamic_pricing ?? "",
            review_mgmt: h.review_mgmt ?? "",
            website_builder: h.website_builder ?? "",
          });
        }
      });
  }, [loading, user, navigate, editingHotelId]);

  // Debounced hotel-name search → suggestions
  useEffect(() => {
    if (suppressSearch) {
      setSuppressSearch(false);
      return;
    }
    const q = form.hotel_name.trim();
    if (q.length < 2) {
      setSuggestions([]);
      setShowSuggestions(false);
      return;
    }
    const handle = setTimeout(async () => {
      setSearching(true);
      try {
        const res = await searchHotels({
          data: { query: q, hint: form.location || undefined },
          headers: await authHeaders(),
        });
        setSuggestions(res.suggestions);
        setShowSuggestions(true);
      } catch {
        // silent — search is non-blocking
      } finally {
        setSearching(false);
      }
    }, 450);
    return () => clearTimeout(handle);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [form.hotel_name]);

  function pickSuggestion(s: HotelSuggestion) {
    setSuppressSearch(true);
    setShowSuggestions(false);
    setSuggestions([]);
    setForm((f) => ({
      ...f,
      hotel_name: s.hotel_name,
      location:
        [s.city, s.country].filter(Boolean).join(", ") || f.location,
      star_rating: s.star_rating ?? f.star_rating,
      property_type:
        s.property_type &&
        PROPERTY_TYPES.includes(s.property_type as (typeof PROPERTY_TYPES)[number])
          ? s.property_type
          : f.property_type,
    }));
    // Auto-run full lookup to fill the rest
    setTimeout(() => {
      void runLookup(s.hotel_name, [s.city, s.country].filter(Boolean).join(", "));
    }, 50);
  }

  async function reverseGeocode(lat: number, lon: number) {
    try {
      const res = await fetch(
        `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lon}&zoom=14&addressdetails=1`,
        { headers: { Accept: "application/json" } },
      );
      if (!res.ok) return null;
      const data = (await res.json()) as { address?: Record<string, string> };
      const a = data.address ?? {};
      const city = a.city || a.town || a.village || a.municipality || a.county || "";
      const country = a.country || "";
      return [city, country].filter(Boolean).join(", ");
    } catch {
      return null;
    }
  }

  function detectLocation() {
    if (!("geolocation" in navigator)) {
      toast.error("Geolocation not supported in this browser");
      return;
    }
    setLocating(true);
    navigator.geolocation.getCurrentPosition(
      async (pos) => {
        const { latitude, longitude } = pos.coords;
        const loc = await reverseGeocode(latitude, longitude);
        setForm((f) => ({ ...f, latitude, longitude, location: loc || f.location }));
        toast.success("Location captured", {
          description: loc ?? `${latitude.toFixed(3)}, ${longitude.toFixed(3)}`,
        });
        setLocating(false);
      },
      (err) => {
        toast.error("Couldn't get location", { description: err.message });
        setLocating(false);
      },
      { enableHighAccuracy: true, timeout: 10000 },
    );
  }

  async function runLookup(nameOverride?: string, hintOverride?: string) {
    const name = (nameOverride ?? form.hotel_name).trim();
    if (!name) {
      toast.error("Type a hotel name first");
      return;
    }
    setLooking(true);
    try {
      const result = await lookupHotel({
        data: { query: name, hint: hintOverride ?? form.location ?? undefined },
        headers: await authHeaders(),
      });
      if (!result.found) {
        toast.warning("Couldn't confidently find this hotel", {
          description: result.notes || "Please fill in the details manually.",
        });
        return;
      }
      const filledFields: string[] = [];
      setForm((f) => {
        const next = { ...f };
        if (result.hotel_name) {
          next.hotel_name = result.hotel_name;
        }
        const loc = [result.city, result.country].filter(Boolean).join(", ");
        if (loc) {
          next.location = loc;
          filledFields.push("location");
        }
        if (result.latitude != null && result.longitude != null) {
          next.latitude = result.latitude;
          next.longitude = result.longitude;
        }
        if (result.rooms) {
          next.rooms = result.rooms;
          filledFields.push("rooms");
        }
        if (result.star_rating) {
          next.star_rating = result.star_rating;
          filledFields.push("star rating");
        }
        if (result.property_type) {
          next.property_type = result.property_type;
          filledFields.push("property type");
        }
        if (result.segment) {
          next.segment = result.segment;
          filledFields.push("segment");
        }
        if (result.amenities?.length) {
          // merge unique
          next.amenities = Array.from(new Set([...f.amenities, ...result.amenities]));
          filledFields.push("facilities");
        }
        if (result.room_types?.length) {
          next.room_types = Array.from(new Set([...f.room_types, ...result.room_types]));
          filledFields.push("room types");
        }
        return next;
      });
      toast.success("Hotel details prefilled", {
        description: filledFields.length
          ? `Filled: ${filledFields.join(", ")}. Review & adjust before saving.`
          : result.address || "Review and adjust before saving.",
      });
    } catch (err) {
      toast.error("Lookup failed", { description: (err as Error).message });
    } finally {
      setLooking(false);
    }
  }

  function toggleArrayItem(field: "amenities" | "room_types", value: string) {
    setForm((f) => {
      const set = new Set(f[field]);
      if (set.has(value)) set.delete(value);
      else set.add(value);
      return { ...f, [field]: Array.from(set) };
    });
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!user) return;
    if (!form.hotel_name || !form.location) {
      toast.error("Hotel name and location are required");
      return;
    }
    setBusy(true);
    const payload = {
      user_id: user.id,
      hotelier_name: form.hotelier_name,
      hotel_name: form.hotel_name,
      location: form.location,
      latitude: form.latitude,
      longitude: form.longitude,
      rooms: form.rooms,
      star_rating: form.star_rating,
      property_type: form.property_type,
      segment: form.segment,
      amenities: form.amenities,
      room_types: form.room_types,
      adr_weekday: form.adr_weekday,
      adr_weekend: form.adr_weekend,
      occupancy_pct: form.occupancy_pct,
      currency: "MYR",
      pms: form.pms || null,
      restaurant_pos: form.restaurant_pos || null,
      channel_manager: form.channel_manager || null,
      booking_engine: form.booking_engine || null,
      payment_gateway: form.payment_gateway || null,
      invoicing: form.invoicing || null,
      dynamic_pricing: form.dynamic_pricing || null,
      review_mgmt: form.review_mgmt || null,
      website_builder: form.website_builder || null,
      radius_km: 3,
      onboarded: true,
    };

    let savedId: string | null = editingHotelId;
    if (editingHotelId) {
      const { error } = await supabase
        .from("hotels")
        .update(payload)
        .eq("id", editingHotelId)
        .eq("user_id", user.id);
      setBusy(false);
      if (error) {
        toast.error("Couldn't save your hotel", { description: error.message });
        return;
      }
    } else {
      const { data, error } = await supabase
        .from("hotels")
        .insert(payload)
        .select("id")
        .single();
      setBusy(false);
      if (error || !data) {
        toast.error("Couldn't save your hotel", { description: error?.message });
        return;
      }
      savedId = data.id;
      setEditingHotelId(savedId);
    }

    if (savedId) {
      await supabase
        .from("user_preferences")
        .upsert(
          { user_id: user.id, selected_hotel_id: savedId },
          { onConflict: "user_id" },
        );
    }
    toast.success("All set — generating your brief");
    await Promise.all([
      qc.refetchQueries({ queryKey: ["hotels", user.id] }),
      qc.refetchQueries({ queryKey: ["user_preferences", user.id] }),
    ]);
    navigate({ to: "/" });
  }

  if (loading || !user) {
    return (
      <div className="flex min-h-dvh items-center justify-center">
        <Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
      </div>
    );
  }

  return (
    <div
      className="min-h-dvh py-8 sm:py-12"
      style={{ backgroundImage: "var(--gradient-paper)", backgroundAttachment: "fixed" }}
    >
      <div className="container mx-auto max-w-xl px-4 sm:px-6">
        <div className="mb-6 flex items-center gap-3 sm:mb-8">
          <div className="flex h-9 w-9 items-center justify-center rounded-full bg-brand text-primary-foreground">
            <Sun className="h-4 w-4" />
          </div>
          <span className="font-serif text-lg font-semibold text-brand sm:text-xl">The Daily Ledger</span>
        </div>

        <div className="flex items-start justify-between gap-3">
          <div>
            <h1 className="font-serif text-3xl font-medium tracking-tight text-foreground sm:text-4xl">
              {editingHotelId ? "Edit hotel." : "Add a hotel."}
            </h1>
            <p className="mt-2 text-sm text-muted-foreground sm:text-base">
              {editingHotelId
                ? "Update the details for this property. Changes are saved to your account."
                : "Type the hotel name and we'll auto-fill from public sources. You can add as many properties as you like — switch between them anytime."}
            </p>
          </div>
          {editingHotelId ? (
            <DeleteHotelButton
              hotelId={editingHotelId}
              hotelName={form.hotel_name}
              userId={user?.id}
              onDeleted={() => navigate({ to: "/" })}
            />
          ) : null}
        </div>

        <form
          onSubmit={handleSubmit}
          className="mt-6 space-y-6 rounded-2xl border bg-card p-5 shadow-[var(--shadow-elegant)] sm:mt-8 sm:p-7"
        >
          {/* Hotel name + auto-fill */}
          <div className="grid gap-2">
            <Label htmlFor="hotel_name">Hotel name</Label>
            <div className="relative">
              <div className="flex gap-2">
                <Input
                  id="hotel_name"
                  value={form.hotel_name}
                  onChange={(e) => setForm({ ...form, hotel_name: e.target.value })}
                  onFocus={() => suggestions.length > 0 && setShowSuggestions(true)}
                  onBlur={() => setTimeout(() => setShowSuggestions(false), 150)}
                  placeholder="e.g. Aloft, Vivatel Kuala Lumpur"
                  autoComplete="off"
                  required
                />
                <Button
                  type="button"
                  variant="default"
                  onClick={() => runLookup()}
                  disabled={looking}
                  title="Auto-fill from public data"
                  className="shrink-0"
                >
                  {looking ? (
                    <Loader2 className="h-4 w-4 animate-spin" />
                  ) : (
                    <>
                      <Sparkles className="mr-1.5 h-4 w-4" /> Auto-fill
                    </>
                  )}
                </Button>
              </div>

              {showSuggestions && (suggestions.length > 0 || searching) ? (
                <div className="absolute left-0 right-0 top-full z-20 mt-1 max-h-72 overflow-auto rounded-lg border bg-popover shadow-lg">
                  {searching && suggestions.length === 0 ? (
                    <div className="flex items-center gap-2 px-3 py-2 text-xs text-muted-foreground">
                      <Loader2 className="h-3 w-3 animate-spin" /> Searching matching hotels…
                    </div>
                  ) : null}
                  {suggestions.map((s, i) => (
                    <button
                      key={`${s.hotel_name}-${i}`}
                      type="button"
                      onMouseDown={(e) => {
                        e.preventDefault();
                        pickSuggestion(s);
                      }}
                      className="flex w-full flex-col items-start gap-0.5 border-b px-3 py-2 text-left text-sm last:border-b-0 hover:bg-muted"
                    >
                      <div className="flex w-full items-center justify-between gap-2">
                        <span className="font-medium text-foreground">{s.hotel_name}</span>
                        {s.star_rating ? (
                          <span className="inline-flex items-center gap-0.5 text-xs text-amber-600">
                            {s.star_rating}
                            <Star className="h-3 w-3 fill-current" />
                          </span>
                        ) : null}
                      </div>
                      <div className="text-xs text-muted-foreground">
                        {[s.brand, [s.city, s.country].filter(Boolean).join(", "), s.short_description]
                          .filter(Boolean)
                          .join(" · ")}
                      </div>
                    </button>
                  ))}
                </div>
              ) : null}
            </div>
            <p className="text-xs text-muted-foreground">
              Start typing — we'll suggest matching hotels. Pick one to auto-fill everything.
            </p>
          </div>

          {/* Location */}
          <div className="grid gap-2">
            <Label htmlFor="location">Location (city, country)</Label>
            <div className="flex gap-2">
              <Input
                id="location"
                value={form.location}
                onChange={(e) => setForm({ ...form, location: e.target.value })}
                placeholder="Kuala Lumpur, Malaysia"
                required
              />
              <Button
                type="button"
                variant="outline"
                size="icon"
                onClick={detectLocation}
                disabled={locating}
                title="Use my device location"
              >
                {locating ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  <MapPin className="h-4 w-4" />
                )}
              </Button>
            </div>
          </div>

          {/* Rooms + Star rating */}
          <div className="grid grid-cols-2 gap-4">
            <div className="grid gap-2">
              <Label htmlFor="rooms">Number of rooms</Label>
              <Input
                id="rooms"
                type="number"
                min={1}
                value={form.rooms}
                onChange={(e) => setForm({ ...form, rooms: Number(e.target.value) || 0 })}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="star_rating">Star rating</Label>
              <Select
                value={form.star_rating != null ? String(form.star_rating) : ""}
                onValueChange={(v) => setForm({ ...form, star_rating: v ? Number(v) : null })}
              >
                <SelectTrigger id="star_rating">
                  <SelectValue placeholder="—" />
                </SelectTrigger>
                <SelectContent>
                  {[1, 2, 3, 4, 5].map((n) => (
                    <SelectItem key={n} value={String(n)}>
                      <span className="inline-flex items-center gap-1">
                        {n}
                        <Star className="h-3 w-3 fill-current text-amber-500" />
                      </span>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          {/* Property type + Segment */}
          <div className="grid grid-cols-2 gap-4">
            <div className="grid gap-2">
              <Label>Property type</Label>
              <Select
                value={form.property_type}
                onValueChange={(v) => setForm({ ...form, property_type: v })}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {PROPERTY_TYPES.map((p) => (
                    <SelectItem key={p} value={p}>
                      {p}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="grid gap-2">
              <Label>Target segment</Label>
              <Select value={form.segment} onValueChange={(v) => setForm({ ...form, segment: v })}>
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {SEGMENTS.map((s) => (
                    <SelectItem key={s} value={s}>
                      {s}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          </div>

          {/* Room types (multi-select chips) */}
          <ChipMultiSelect
            label="Room types"
            hint="Tap to add. Auto-fill prefills these from public data."
            options={ROOM_TYPE_OPTIONS as readonly string[]}
            selected={form.room_types}
            onToggle={(v) => toggleArrayItem("room_types", v)}
            onAddCustom={(v) =>
              setForm((f) => ({
                ...f,
                room_types: Array.from(new Set([...f.room_types, v])),
              }))
            }
          />

          {/* Facilities (multi-select chips) */}
          <ChipMultiSelect
            label="Facilities"
            hint="Pool, breakfast, event hall, etc."
            options={COMMON_FACILITIES as readonly string[]}
            selected={form.amenities}
            onToggle={(v) => toggleArrayItem("amenities", v)}
            onAddCustom={(v) =>
              setForm((f) => ({
                ...f,
                amenities: Array.from(new Set([...f.amenities, v])),
              }))
            }
          />

          {/* Software stack */}
          <SoftwareStackSection
            values={{
              pms: form.pms,
              restaurant_pos: form.restaurant_pos,
              channel_manager: form.channel_manager,
              booking_engine: form.booking_engine,
              payment_gateway: form.payment_gateway,
              invoicing: form.invoicing,
              dynamic_pricing: form.dynamic_pricing,
              review_mgmt: form.review_mgmt,
              website_builder: form.website_builder,
            }}
            onChange={(field, value) => setForm((f) => ({ ...f, [field]: value }))}
          />

          {/* Internal numbers */}
          <div className="rounded-xl border border-dashed bg-muted/20 p-4">
            <button
              type="button"
              onClick={() => setShowSensitive((s) => !s)}
              className="flex w-full items-center justify-between text-left"
            >
              <div>
                <div className="text-sm font-medium text-foreground">
                  Internal numbers <span className="text-muted-foreground">(optional)</span>
                </div>
                <p className="mt-0.5 text-xs text-muted-foreground">
                  Adding ADR &amp; occupancy makes pricing &amp; competitor insight much sharper. Stays private.
                </p>
              </div>
              <span className="text-xs font-medium text-brand">{showSensitive ? "Hide" : "Add"}</span>
            </button>

            {showSensitive ? (
              <div className="mt-4 space-y-4">
                <div className="grid grid-cols-2 gap-4">
                  <div className="grid gap-2">
                    <Label htmlFor="adr_weekday">Avg weekday rate (MYR)</Label>
                    <Input
                      id="adr_weekday"
                      type="number"
                      min={0}
                      value={form.adr_weekday ?? ""}
                      onChange={(e) =>
                        setForm({
                          ...form,
                          adr_weekday: e.target.value === "" ? null : Number(e.target.value),
                        })
                      }
                    />
                  </div>
                  <div className="grid gap-2">
                    <Label htmlFor="adr_weekend">Avg weekend rate (MYR)</Label>
                    <Input
                      id="adr_weekend"
                      type="number"
                      min={0}
                      value={form.adr_weekend ?? ""}
                      onChange={(e) =>
                        setForm({
                          ...form,
                          adr_weekend: e.target.value === "" ? null : Number(e.target.value),
                        })
                      }
                    />
                  </div>
                </div>
                <div className="grid gap-2">
                  <Label htmlFor="occupancy_pct">Typical occupancy (%)</Label>
                  <Input
                    id="occupancy_pct"
                    type="number"
                    min={0}
                    max={100}
                    value={form.occupancy_pct ?? ""}
                    onChange={(e) =>
                      setForm({
                        ...form,
                        occupancy_pct:
                          e.target.value === ""
                            ? null
                            : Math.min(100, Math.max(0, Number(e.target.value))),
                      })
                    }
                  />
                </div>
              </div>
            ) : null}
          </div>

          <Button type="submit" disabled={busy} size="lg" className="w-full">
            {busy ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
            Save &amp; show me today's brief
          </Button>
        </form>
      </div>
    </div>
  );
}

// =============== Reusable chip multi-select ===============
function ChipMultiSelect({
  label,
  hint,
  options,
  selected,
  onToggle,
  onAddCustom,
}: {
  label: string;
  hint?: string;
  options: readonly string[];
  selected: string[];
  onToggle: (value: string) => void;
  onAddCustom: (value: string) => void;
}) {
  const [draft, setDraft] = useState("");
  const customSelected = selected.filter((s) => !options.includes(s));
  return (
    <div className="grid gap-2">
      <div className="flex flex-wrap items-baseline justify-between gap-x-3 gap-y-0.5">
        <Label>{label}</Label>
        {hint ? <span className="text-[11px] text-muted-foreground sm:text-xs">{hint}</span> : null}
      </div>
      <div className="flex flex-wrap gap-1.5">
        {options.map((opt) => {
          const active = selected.includes(opt);
          return (
            <button
              key={opt}
              type="button"
              onClick={() => onToggle(opt)}
              className={
                "rounded-full border px-3 py-1 text-xs transition-colors " +
                (active
                  ? "border-brand bg-brand text-primary-foreground"
                  : "border-border bg-background text-foreground hover:bg-muted")
              }
            >
              {opt}
            </button>
          );
        })}
        {customSelected.map((c) => (
          <Badge key={c} variant="secondary" className="gap-1 pl-2 pr-1 py-0.5">
            {c}
            <button
              type="button"
              onClick={() => onToggle(c)}
              className="rounded-full p-0.5 hover:bg-muted-foreground/20"
              aria-label={`Remove ${c}`}
            >
              <X className="h-3 w-3" />
            </button>
          </Badge>
        ))}
      </div>
      <div className="flex gap-2">
        <Input
          value={draft}
          onChange={(e) => setDraft(e.target.value)}
          placeholder="Add your own…"
          onKeyDown={(e) => {
            if (e.key === "Enter" && draft.trim()) {
              e.preventDefault();
              onAddCustom(draft.trim());
              setDraft("");
            }
          }}
          className="h-8 text-sm"
        />
        <Button
          type="button"
          variant="outline"
          size="sm"
          disabled={!draft.trim()}
          onClick={() => {
            onAddCustom(draft.trim());
            setDraft("");
          }}
        >
          Add
        </Button>
      </div>
    </div>
  );
}

function DeleteHotelButton({
  hotelId,
  hotelName,
  userId,
  onDeleted,
}: {
  hotelId: string;
  hotelName: string;
  userId: string | undefined;
  onDeleted: () => void;
}) {
  const [open, setOpen] = useState(false);
  const [confirm, setConfirm] = useState("");
  const [busy, setBusy] = useState(false);
  const expected = (hotelName || "").trim();

  async function handleDelete() {
    if (!userId) return;
    setBusy(true);
    try {
      const { error } = await supabase
        .from("hotels")
        .delete()
        .eq("id", hotelId)
        .eq("user_id", userId);
      if (error) throw error;
      toast.success("Hotel deleted");
      setOpen(false);
      onDeleted();
    } catch (err) {
      toast.error("Couldn't delete", { description: (err as Error).message });
    } finally {
      setBusy(false);
    }
  }

  return (
    <>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="shrink-0 text-destructive hover:text-destructive"
        onClick={() => {
          setConfirm("");
          setOpen(true);
        }}
      >
        <Trash2 className="mr-1 h-3.5 w-3.5" />
        Remove hotel
      </Button>
      <Dialog open={open} onOpenChange={(v) => { if (!busy) setOpen(v); }}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle className="text-destructive">Remove this hotel?</DialogTitle>
            <DialogDescription>
              This permanently deletes <span className="font-medium text-foreground">{expected || "this hotel"}</span> and all of its briefings, self-examinations, action progress, and chat history. This cannot be undone.
            </DialogDescription>
          </DialogHeader>
          <div className="grid gap-2">
            <Label htmlFor="confirm-hotel" className="text-xs text-muted-foreground">
              Type the hotel name <span className="font-medium text-foreground">{expected}</span> to confirm
            </Label>
            <Input
              id="confirm-hotel"
              value={confirm}
              onChange={(e) => setConfirm(e.target.value)}
              autoComplete="off"
              placeholder={expected}
            />
          </div>
          <DialogFooter>
            <Button variant="ghost" onClick={() => setOpen(false)} disabled={busy}>
              Cancel
            </Button>
            <Button
              variant="destructive"
              onClick={handleDelete}
              disabled={busy || !expected || confirm.trim() !== expected}
              className="gap-2"
            >
              {busy ? <Loader2 className="h-4 w-4 animate-spin" /> : <Trash2 className="h-4 w-4" />}
              Delete permanently
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}

// =============== Software stack section ===============
type StackField =
  | "pms"
  | "restaurant_pos"
  | "channel_manager"
  | "booking_engine"
  | "payment_gateway"
  | "invoicing"
  | "dynamic_pricing"
  | "review_mgmt"
  | "website_builder";

function SoftwareStackSection({
  values,
  onChange,
}: {
  values: Record<StackField, string>;
  onChange: (field: StackField, value: string) => void;
}) {
  const [open, setOpen] = useState(false);
  const filledCount = Object.values(values).filter((v) => v && v.trim()).length;

  const fields: { key: StackField; label: string; options: readonly string[] }[] = [
    { key: "pms", label: "Property Management System (PMS)", options: PMS_OPTIONS },
    { key: "channel_manager", label: "Channel manager", options: CHANNEL_MANAGER_OPTIONS },
    { key: "booking_engine", label: "Booking engine", options: BOOKING_ENGINE_OPTIONS },
    { key: "restaurant_pos", label: "Restaurant POS", options: POS_OPTIONS },
    { key: "payment_gateway", label: "Payment gateway", options: PAYMENT_GATEWAY_OPTIONS },
    { key: "invoicing", label: "Invoicing / e-invoice", options: INVOICING_OPTIONS },
    { key: "dynamic_pricing", label: "Dynamic pricing", options: DYNAMIC_PRICING_OPTIONS },
    { key: "review_mgmt", label: "Review management", options: REVIEW_MGMT_OPTIONS },
    { key: "website_builder", label: "Website builder / CMS", options: WEBSITE_BUILDER_OPTIONS },
  ];

  return (
    <div className="rounded-xl border border-dashed bg-muted/20 p-4">
      <button
        type="button"
        onClick={() => setOpen((s) => !s)}
        className="flex w-full items-center justify-between text-left"
      >
        <div>
          <div className="text-sm font-medium text-foreground">
            Software stack <span className="text-muted-foreground">(optional)</span>
          </div>
          <p className="mt-0.5 text-xs text-muted-foreground">
            Tell us which systems you use — PMS, POS, channel manager, payments, invoicing, etc.
            We'll tailor recommendations and competitor benchmarks to your stack.
          </p>
        </div>
        <span className="text-xs font-medium text-brand">
          {filledCount > 0 ? `${filledCount} set · ${open ? "Hide" : "Edit"}` : open ? "Hide" : "Add"}
        </span>
      </button>

      {open ? (
        <div className="mt-4 grid gap-4 sm:grid-cols-2">
          {fields.map((f) => (
            <SoftwarePicker
              key={f.key}
              label={f.label}
              options={f.options}
              value={values[f.key]}
              onChange={(v) => onChange(f.key, v)}
            />
          ))}
        </div>
      ) : null}
    </div>
  );
}

function SoftwarePicker({
  label,
  options,
  value,
  onChange,
}: {
  label: string;
  options: readonly string[];
  value: string;
  onChange: (v: string) => void;
}) {
  const isCustom = value !== "" && !options.includes(value);
  const selectValue = isCustom ? "__custom__" : value || "__none__";

  return (
    <div className="grid gap-2">
      <Label className="text-xs">{label}</Label>
      <Select
        value={selectValue}
        onValueChange={(v) => {
          if (v === "__none__") onChange("");
          else if (v === "__custom__") onChange(value && !options.includes(value) ? value : " ");
          else onChange(v);
        }}
      >
        <SelectTrigger className="h-9 text-sm">
          <SelectValue placeholder="Select…" />
        </SelectTrigger>
        <SelectContent>
          <SelectItem value="__none__">— Not set —</SelectItem>
          {options.map((o) => (
            <SelectItem key={o} value={o}>
              {o}
            </SelectItem>
          ))}
          <SelectItem value="__custom__">Other (type below)</SelectItem>
        </SelectContent>
      </Select>
      {isCustom || selectValue === "__custom__" ? (
        <Input
          value={isCustom ? value : ""}
          onChange={(e) => onChange(e.target.value)}
          placeholder="Type the system you're using…"
          className="h-8 text-sm"
        />
      ) : null}
    </div>
  );
}
