"use client";

import { useState, useEffect, useRef } from "react";
import { createPortal } from "react-dom";
import { X, ChevronDown } from "lucide-react";
import { adminFetch } from "@/lib/csrf";

type Tab = "classes" | "events";
type EventType = "master-class" | "open-day";

interface McOption { title: string; date: string }
interface OdClass { id: number; style: string; start_time: string; hall: string; trainer: string }
interface OdEvent { id: number; date: string; title?: string }
interface ScheduleClass { type: string; trainer: string; time: string; day: string; hall: string }

function shortName(fullName: string) {
  const parts = fullName.trim().split(/\s+/);
  // Names stored as "Имя Фамилия" → show "Фамилия И."
  return parts.length > 1 ? `${parts[1]} ${parts[0][0]}.` : parts[0];
}

const SHORT_DAYS: Record<string, string> = {
  "Понедельник": "Пн", "Вторник": "Вт", "Среда": "Ср",
  "Четверг": "Чт", "Пятница": "Пт", "Суббота": "Сб", "Воскресенье": "Вс",
};

// --- Searchable dropdown ---

interface SearchSelectOption { value: string; label: string }

function SearchSelect({ options, value, onChange, placeholder }: {
  options: SearchSelectOption[];
  value: string;
  onChange: (v: string) => void;
  placeholder: string;
}) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState("");
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const selected = options.find((o) => o.value === value);

  const filtered = search
    ? options.filter((o) => o.label.toLowerCase().includes(search.toLowerCase()))
    : options;

  useEffect(() => {
    if (!open) return;
    function handle(e: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setOpen(false);
        setSearch("");
      }
    }
    document.addEventListener("mousedown", handle);
    return () => document.removeEventListener("mousedown", handle);
  }, [open]);

  return (
    <div ref={containerRef} className="relative">
      <div
        onClick={() => { setOpen(true); setTimeout(() => inputRef.current?.focus(), 0); }}
        className={`flex items-center gap-2 w-full rounded-lg border px-3 py-2 text-sm cursor-text transition-colors ${
          open ? "border-gold/40 bg-white/[0.06]" : "border-white/[0.08] bg-white/[0.04]"
        }`}
      >
        {open ? (
          <input
            ref={inputRef}
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder={selected ? selected.label : placeholder}
            className="flex-1 bg-transparent text-white placeholder-neutral-500 outline-none text-sm"
            onKeyDown={(e) => {
              if (e.key === "Escape") { setOpen(false); setSearch(""); }
              if (e.key === "Backspace" && !search && value) { onChange(""); }
            }}
          />
        ) : (
          <span className={`flex-1 truncate ${selected ? "text-white" : "text-neutral-500"}`}>
            {selected ? selected.label : placeholder}
          </span>
        )}
        {value && !open ? (
          <button
            type="button"
            onClick={(e) => { e.stopPropagation(); onChange(""); }}
            className="text-neutral-500 hover:text-white transition-colors shrink-0"
          >
            <X size={14} />
          </button>
        ) : (
          <ChevronDown size={14} className={`text-neutral-500 shrink-0 transition-transform ${open ? "rotate-180" : ""}`} />
        )}
      </div>

      {open && (
        <div className="absolute z-20 mt-1 w-full rounded-lg border border-white/[0.08] shadow-xl overflow-hidden" style={{ backgroundColor: "#141414" }}>
          <div className="max-h-48 overflow-y-auto styled-scrollbar">
            {filtered.length === 0 && (
              <p className="px-3 py-2 text-xs text-neutral-500">Ничего не найдено</p>
            )}
            {filtered.map((o) => (
              <button
                key={o.value}
                type="button"
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => { onChange(o.value); setOpen(false); setSearch(""); }}
                className={`w-full px-3 py-2 text-left text-sm transition-colors ${
                  o.value === value ? "bg-gold/10 text-gold" : "text-white hover:bg-white/[0.05]"
                }`}
              >
                {o.label}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

// --- Modal ---

export function AddBookingModal({
  open,
  onClose,
  onAdded,
}: {
  open: boolean;
  onClose: () => void;
  onAdded: () => void;
}) {
  const [tab, setTab] = useState<Tab>("classes");
  const [eventType, setEventType] = useState<EventType>("master-class");
  const [name, setName] = useState("");
  const [phone, setPhone] = useState("+375 ");
  const [instagram, setInstagram] = useState("");
  const [telegram, setTelegram] = useState("");
  const [mcTitle, setMcTitle] = useState("");
  const [mcOptions, setMcOptions] = useState<McOption[]>([]);
  const [odClasses, setOdClasses] = useState<OdClass[]>([]);
  const [odEventId, setOdEventId] = useState<number | null>(null);
  const [odClassId, setOdClassId] = useState("");
  const [scheduleClasses, setScheduleClasses] = useState<ScheduleClass[]>([]);
  const [classInfo, setClassInfo] = useState("");
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    if (!open) return;
    setName(""); setPhone("+375 "); setInstagram(""); setTelegram(""); setMcTitle(""); setOdClassId(""); setClassInfo("");

    // Fetch schedule classes
    adminFetch("/api/admin/sections/schedule").then((r) => r.json()).then((data: { locations?: { name: string; days: { day: string; classes: { type: string; trainer: string; time: string }[] }[] }[] }) => {
      const classes: ScheduleClass[] = [];
      for (const loc of data.locations || []) {
        for (const day of loc.days) {
          for (const cls of day.classes) {
            classes.push({ type: cls.type, trainer: cls.trainer, time: cls.time, day: day.day, hall: loc.name });
          }
        }
      }
      // Deduplicate by type+trainer+time+day+hall
      const seen = new Set<string>();
      const unique = classes.filter((c) => {
        const key = `${c.type}|${c.trainer}|${c.time}|${c.day}|${c.hall}`;
        if (seen.has(key)) return false;
        seen.add(key);
        return true;
      });
      setScheduleClasses(unique);
    }).catch(() => {});

    // Fetch upcoming MCs
    adminFetch("/api/admin/sections/masterClasses").then((r) => r.json()).then((data: { items?: { title: string; slots: { date: string }[] }[] }) => {
      const today = new Date().toISOString().split("T")[0];
      const upcoming = (data.items || [])
        .filter((mc) => {
          const earliest = mc.slots?.reduce((min, s) => s.date < min ? s.date : min, mc.slots[0]?.date ?? "");
          return earliest && earliest >= today;
        })
        .map((mc) => ({
          title: mc.title,
          date: mc.slots.reduce((min, s) => s.date < min ? s.date : min, mc.slots[0]?.date ?? ""),
        }));
      setMcOptions(upcoming);
      if (upcoming.length === 0 && tab === "events") setEventType("open-day");
    }).catch(() => {});

    // Fetch active Open Day event + classes
    adminFetch("/api/admin/open-day").then((r) => r.json()).then(async (events: OdEvent[]) => {
      const today = new Date().toISOString().split("T")[0];
      const active = events.find((e) => e.date >= today);
      if (!active) { setOdEventId(null); setOdClasses([]); return; }
      setOdEventId(active.id);
      const classes = await adminFetch(`/api/admin/open-day/classes?eventId=${active.id}`).then((r) => r.json());
      setOdClasses(classes);
    }).catch(() => {});
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  useEffect(() => {
    if (!open) return;
    function onKey(e: KeyboardEvent) { if (e.key === "Escape") onClose(); }
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);

  function handlePhoneChange(raw: string) {
    let digits = raw.replace(/\D/g, "");
    if (!digits.startsWith("375")) digits = "375" + digits.replace(/^375?/, "");
    digits = digits.slice(0, 12);
    let formatted = "+375";
    const rest = digits.slice(3);
    if (rest.length > 0) formatted += " (" + rest.slice(0, 2);
    if (rest.length >= 2) formatted += ") ";
    if (rest.length > 2) formatted += rest.slice(2, 5);
    if (rest.length > 5) formatted += "-" + rest.slice(5, 7);
    if (rest.length > 7) formatted += "-" + rest.slice(7, 9);
    setPhone(formatted);
  }

  const hasUpcomingMc = mcOptions.length > 0;
  const hasOpenDay = odEventId !== null && odClasses.length > 0;

  // Build options for each dropdown
  const classOptions: SearchSelectOption[] = scheduleClasses.map((c, i) => ({
    value: String(i),
    label: `${shortName(c.trainer)} — ${c.type} · ${SHORT_DAYS[c.day] || c.day} ${c.time} · ${c.hall}`,
  }));

  const mcSelectOptions: SearchSelectOption[] = mcOptions.map((mc) => ({
    value: mc.title,
    label: mc.title,
  }));

  const odSelectOptions: SearchSelectOption[] = odClasses.map((c) => ({
    value: String(c.id),
    label: `${shortName(c.trainer)} — ${c.start_time} · ${c.hall}`,
  }));

  async function handleSubmit() {
    if (!name.trim() || !phone.trim()) return;
    setSaving(true);
    try {
      if (tab === "classes") {
        const selectedClass = classInfo ? scheduleClasses[Number(classInfo)] : null;
        const groupInfo = selectedClass
          ? `${selectedClass.type}, ${shortName(selectedClass.trainer)}, ${SHORT_DAYS[selectedClass.day] || selectedClass.day} ${selectedClass.time}, ${selectedClass.hall}`
          : undefined;
        await adminFetch("/api/admin/group-bookings", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            name: name.trim(),
            phone: phone.trim(),
            ...(groupInfo && { groupInfo }),
            ...(instagram.trim() && { instagram: instagram.trim() }),
            ...(telegram.trim() && { telegram: telegram.trim() }),
          }),
        });
      } else if (eventType === "master-class") {
        const title = mcTitle || mcOptions[0]?.title || "Мастер-класс";
        await adminFetch("/api/admin/mc-registrations", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ masterClassTitle: title, name: name.trim(), instagram: "-", phone: phone.trim() }),
        });
      } else if (eventType === "open-day" && odClassId && odEventId) {
        await adminFetch("/api/open-day-register", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ classId: Number(odClassId), eventId: odEventId, name: name.trim(), phone: phone.trim() }),
        });
      }
      onAdded();
      onClose();
    } finally {
      setSaving(false);
    }
  }

  if (!open) return null;

  const inputClass = "w-full rounded-lg border border-white/[0.08] bg-white/[0.04] px-3 py-2 text-sm text-white outline-none focus:border-gold/40 placeholder-neutral-500";

  const canSubmit = name.trim() && phone.trim() && !saving
    && (tab === "classes" || (tab === "events" && eventType === "master-class" && hasUpcomingMc)
    || (tab === "events" && eventType === "open-day" && odClassId));

  return createPortal(
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4" onClick={onClose}>
      <div className="absolute inset-0 bg-black/70 backdrop-blur-sm" />
      <div className="relative w-full max-w-sm rounded-2xl border border-white/[0.08] bg-[#0a0a0a] p-6 shadow-2xl" onClick={(e) => e.stopPropagation()}>
        <button onClick={onClose} className="absolute right-3 top-3 flex h-7 w-7 items-center justify-center rounded-full text-neutral-500 hover:bg-white/[0.06] hover:text-white">
          <X size={16} />
        </button>

        <h3 className="text-base font-bold text-white">Добавить запись</h3>
        <p className="mt-1 text-xs text-neutral-400">Ручная запись (Instagram, звонок, лично)</p>

        <div className="mt-4 space-y-3">
          {/* Type selector — single row */}
          <div className="flex rounded-lg border border-white/[0.08] bg-white/[0.03] p-0.5">
            <button
              onClick={() => setTab("classes")}
              className={`flex-1 rounded-md py-2 text-xs font-medium transition-all ${
                tab === "classes" ? "bg-gold/20 text-gold shadow-sm" : "text-neutral-400 hover:text-white"
              }`}
            >
              Занятие
            </button>
            {hasUpcomingMc && (
              <button
                onClick={() => { setTab("events"); setEventType("master-class"); }}
                className={`flex-1 rounded-md py-2 text-xs font-medium transition-all ${
                  tab === "events" && eventType === "master-class" ? "bg-purple-500/15 text-purple-400 shadow-sm" : "text-neutral-400 hover:text-white"
                }`}
              >
                Мастер-класс
              </button>
            )}
            {hasOpenDay && (
              <button
                onClick={() => { setTab("events"); setEventType("open-day"); }}
                className={`flex-1 rounded-md py-2 text-xs font-medium transition-all ${
                  tab === "events" && eventType === "open-day" ? "bg-blue-500/15 text-blue-400 shadow-sm" : "text-neutral-400 hover:text-white"
                }`}
              >
                Open Day
              </button>
            )}
          </div>

          {/* Class selector (optional for Занятие) */}
          {tab === "classes" && classOptions.length > 0 && (
            <SearchSelect
              options={classOptions}
              value={classInfo}
              onChange={setClassInfo}
              placeholder="Выберите занятие (необязательно)"
            />
          )}

          {/* MC selector */}
          {tab === "events" && eventType === "master-class" && mcSelectOptions.length > 0 && (
            <SearchSelect
              options={mcSelectOptions}
              value={mcTitle}
              onChange={setMcTitle}
              placeholder="Выберите мастер-класс"
            />
          )}

          {/* Open Day class selector */}
          {tab === "events" && eventType === "open-day" && odSelectOptions.length > 0 && (
            <SearchSelect
              options={odSelectOptions}
              value={odClassId}
              onChange={setOdClassId}
              placeholder="Выберите занятие"
            />
          )}

          <input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder="Имя" className={inputClass} />
          <input type="tel" value={phone} onChange={(e) => handlePhoneChange(e.target.value)} placeholder="+375 (__) ___-__-__" className={inputClass} />
          <div className="flex gap-2">
            <input type="text" value={instagram} onChange={(e) => setInstagram(e.target.value)} placeholder="Instagram" className={inputClass} />
            <input type="text" value={telegram} onChange={(e) => setTelegram(e.target.value)} placeholder="Telegram" className={inputClass} />
          </div>
        </div>

        <button
          onClick={handleSubmit}
          disabled={!canSubmit}
          className="mt-5 w-full rounded-lg bg-gold py-2.5 text-sm font-semibold text-black transition-all hover:bg-gold-light disabled:opacity-30 disabled:cursor-not-allowed"
        >
          {saving ? "Сохраняю..." : "Добавить"}
        </button>
      </div>
    </div>,
    document.body
  );
}
