"use client";

import { useState, useEffect, useMemo, useCallback, useRef } from "react";
import {
  Plus, X, Loader2, Calendar, Trash2, Ban, CheckCircle2, RotateCcw, Sparkles,
} from "lucide-react";
import { adminFetch } from "@/lib/csrf";
import { ParticipantLimits, SelectField } from "../_components/FormField";

// --- Types ---

interface OpenDayEvent {
  id: number;
  date: string;
  title: string;
  description?: string;
  pricePerClass: number;
  discountPrice: number;
  discountThreshold: number;
  minBookings: number;
  maxParticipants: number;
  active: boolean;
}

interface OpenDayClass {
  id: number;
  eventId: number;
  hall: string;
  startTime: string;
  endTime: string;
  trainer: string;
  style: string;
  cancelled: boolean;
  sortOrder: number;
  bookingCount: number;
  maxParticipants: number;
}


// --- Helpers ---

function generateTimeSlots(startHour: number, endHour: number): string[] {
  const slots: string[] = [];
  for (let h = startHour; h < endHour; h++) {
    slots.push(`${h.toString().padStart(2, "0")}:00`);
  }
  return slots;
}

function addHour(time: string): string {
  const [h, m] = time.split(":").map(Number);
  return `${(h + 1).toString().padStart(2, "0")}:${m.toString().padStart(2, "0")}`;
}

// --- Event Settings ---

function EventSettings({
  event,
  onChange,
}: {
  event: OpenDayEvent;
  onChange: (patch: Partial<OpenDayEvent>) => void;
}) {
  return (
    <div className="rounded-xl border border-white/10 bg-neutral-900 p-5 space-y-4">
      <h2 className="text-lg font-bold flex items-center gap-2">
        <Calendar size={18} className="text-gold" />
        Настройки мероприятия
      </h2>

      <div className="grid gap-4 sm:grid-cols-2">
        <div>
          <label className="block text-sm text-neutral-400 mb-1.5">Название</label>
          <input
            type="text"
            value={event.title}
            onChange={(e) => onChange({ title: e.target.value })}
            className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white placeholder-neutral-500 outline-none focus:border-gold transition-colors"
          />
        </div>
        <div>
          <label className="block text-sm text-neutral-400 mb-1.5">Дата</label>
          <input
            type="date"
            value={event.date}
            onChange={(e) => onChange({ date: e.target.value })}
            className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors [color-scheme:dark]"
          />
        </div>
      </div>

      <div>
        <label className="block text-sm text-neutral-400 mb-1.5">Описание</label>
        <textarea
          value={event.description || ""}
          onChange={(e) => onChange({ description: e.target.value || undefined })}
          rows={2}
          className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white placeholder-neutral-500 outline-none focus:border-gold transition-colors resize-none"
          placeholder="Описание мероприятия..."
        />
      </div>

      <div>
        <label className="block text-sm text-neutral-400 mb-1.5">Цена за занятие (BYN)</label>
        <input
          type="number"
          value={event.pricePerClass}
          onChange={(e) => onChange({ pricePerClass: parseInt(e.target.value) || 0 })}
          className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors sm:max-w-xs"
        />
      </div>

      {/* Discount toggle + fields */}
      <div>
        <button
          type="button"
          onClick={() => {
            if (event.discountPrice > 0) onChange({ discountPrice: 0, discountThreshold: 0 });
            else onChange({ discountPrice: event.pricePerClass - 5, discountThreshold: 3 });
          }}
          className={`flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all ${
            event.discountPrice > 0
              ? "bg-gold/15 text-gold border border-gold/30"
              : "bg-neutral-800 text-neutral-400 border border-white/10 hover:text-white"
          }`}
        >
          <Sparkles size={14} />
          {event.discountPrice > 0 ? "Скидка включена" : "Добавить скидку"}
        </button>
        {event.discountPrice > 0 && (
          <div className="grid gap-4 sm:grid-cols-2 mt-3">
            <div>
              <label className="block text-sm text-neutral-400 mb-1.5">Цена со скидкой (BYN)</label>
              <input
                type="number"
                value={event.discountPrice}
                onChange={(e) => onChange({ discountPrice: parseInt(e.target.value) || 0 })}
                className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
              />
            </div>
            <div>
              <label className="block text-sm text-neutral-400 mb-1.5">От N занятий</label>
              <input
                type="number"
                value={event.discountThreshold}
                onChange={(e) => onChange({ discountThreshold: parseInt(e.target.value) || 1 })}
                className="w-full rounded-lg border border-white/10 bg-neutral-800 px-4 py-2.5 text-white outline-none focus:border-gold transition-colors"
              />
            </div>
          </div>
        )}
      </div>

      <ParticipantLimits
        min={event.minBookings}
        max={event.maxParticipants ?? 0}
        onMinChange={(v) => onChange({ minBookings: v })}
        onMaxChange={(v) => onChange({ maxParticipants: v })}
      />

      <div className="flex items-center gap-3 pt-1">
        <button
          type="button"
          onClick={() => onChange({ active: !event.active })}
          className={`relative flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium transition-all ${
            event.active
              ? "bg-emerald-500/15 text-emerald-400 border border-emerald-500/30"
              : "bg-neutral-800 text-neutral-400 border border-white/10"
          }`}
        >
          {event.active ? <CheckCircle2 size={14} /> : <Ban size={14} />}
          {event.active ? "Опубликовано" : "Черновик"}
        </button>
        <span className="text-xs text-neutral-500">
          {event.pricePerClass} BYN / занятие{event.discountPrice > 0 && event.discountThreshold > 0 && `, от ${event.discountThreshold} — ${event.discountPrice} BYN`}
        </span>
      </div>
    </div>
  );
}

// --- New Class Form (create only on save) ---

function NewClassForm({
  startTime,
  trainers,
  styles,
  onSave,
  onCancel,
}: {
  startTime: string;
  trainers: string[];
  styles: string[];
  onSave: (data: { trainer: string; style: string; endTime: string }) => void;
  onCancel: () => void;
}) {
  const [style, setStyle] = useState("");
  const [trainer, setTrainer] = useState("");
  const endTime = addHour(startTime);
  const formRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    formRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
  }, []);

  // Auto-save on click outside
  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      if (formRef.current && !formRef.current.contains(e.target as Node)) {
        if (style && trainer) onSave({ trainer, style, endTime });
        else onCancel();
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, [style, trainer, endTime, onSave, onCancel]);

  const canSave = style && trainer;

  return (
    <div ref={formRef} className="p-2 space-y-1.5 ring-1 ring-gold/30 rounded-lg">
      <SelectField label="" value={style} onChange={setStyle} options={styles.map((s) => ({ value: s, label: s }))} placeholder="Стиль..." />
      <SelectField label="" value={trainer} onChange={setTrainer} options={trainers.map((t) => ({ value: t, label: t }))} placeholder="Тренер..." />
      <div className="flex gap-1 justify-end">
        <button onClick={onCancel} className="text-[10px] text-neutral-500 hover:text-white px-1">Отмена</button>
        <button onClick={() => canSave && onSave({ trainer, style, endTime })} disabled={!canSave}
          className="text-[10px] text-gold hover:text-gold-light px-1 font-medium disabled:opacity-30 disabled:cursor-not-allowed">OK</button>
      </div>
    </div>
  );
}

// --- Class Grid Cell ---

function ClassCell({
  cls,
  minBookings,
  trainers,
  styles,
  onUpdate,
  onDelete,
  onCancel,
}: {
  cls: OpenDayClass;
  minBookings: number;
  trainers: string[];
  styles: string[];
  onUpdate: (id: number, data: Partial<OpenDayClass>) => void;
  onDelete: (id: number) => void;
  onCancel: (id: number) => void;
}) {
  const [editing, setEditing] = useState(false);
  const [trainer, setTrainer] = useState(cls.trainer);
  const [style, setStyle] = useState(cls.style);

  const atRisk = cls.bookingCount < minBookings && !cls.cancelled;

  function save() {
    if (trainer.trim() && style.trim()) {
      onUpdate(cls.id, { trainer: trainer.trim(), style: style.trim() });
      setEditing(false);
    }
  }

  if (editing) {
    return (
      <div className="p-2 space-y-1.5 rounded-lg">
        <SelectField label="" value={style} onChange={setStyle} options={styles.map((s) => ({ value: s, label: s }))} placeholder="Стиль..." />
        <SelectField label="" value={trainer} onChange={setTrainer} options={trainers.map((t) => ({ value: t, label: t }))} placeholder="Тренер..." />
        <div className="flex gap-1 justify-end">
          <button onClick={() => setEditing(false)} className="text-[10px] text-neutral-500 hover:text-white px-1">
            Отмена
          </button>
          <button onClick={save} className="text-[10px] text-gold hover:text-gold-light px-1 font-medium">
            OK
          </button>
        </div>
      </div>
    );
  }

  return (
    <div
      className={`group relative p-2 rounded-lg cursor-pointer transition-all ${
        cls.cancelled
          ? "bg-neutral-800/30 opacity-50"
          : atRisk
            ? "bg-red-500/5 border border-red-500/20"
            : "bg-gold/5 border border-gold/15 hover:border-gold/30"
      }`}
      onClick={() => setEditing(true)}
    >
      <div className="flex items-center gap-1.5">
        <span className="text-xs font-medium text-white truncate">{cls.style}</span>
        <span className="text-[10px] text-neutral-500">{cls.startTime}–{cls.endTime}</span>
      </div>
      <div className="text-[10px] text-neutral-400 truncate">{cls.trainer}</div>
      <div className="flex items-center gap-1 mt-1">
        <span className={`text-[10px] font-medium ${
          cls.cancelled
            ? "text-neutral-500 line-through"
            : atRisk
              ? "text-red-400"
              : "text-emerald-400"
        }`}>
          {cls.bookingCount} чел.
        </span>
        {atRisk && !cls.cancelled && (
          <span className="text-[9px] text-red-400">мин. {minBookings}</span>
        )}
        {cls.cancelled && <span className="text-[9px] text-neutral-500">отменено</span>}
      </div>
      {/* Actions */}
      <div className="absolute top-1 right-1 hidden group-hover:flex gap-0.5">
        <button
          onClick={(e) => { e.stopPropagation(); onCancel(cls.id); }}
          className={`rounded p-0.5 ${cls.cancelled ? "text-neutral-500 hover:text-emerald-400" : "text-neutral-500 hover:text-yellow-400"}`}
          title={cls.cancelled ? "Восстановить" : "Отменить"}
        >
          {cls.cancelled ? <RotateCcw size={10} /> : <Ban size={10} />}
        </button>
        <button
          onClick={(e) => { e.stopPropagation(); onDelete(cls.id); }}
          className="rounded p-0.5 text-neutral-500 hover:text-red-400"
          title="Удалить"
        >
          <Trash2 size={10} />
        </button>
      </div>
    </div>
  );
}

// --- Schedule Grid ---

function ScheduleGrid({
  eventId,
  minBookings,
  halls,
  classes,
  trainers,
  styles,
  onClassesChange,
}: {
  eventId: number;
  minBookings: number;
  halls: string[];
  classes: OpenDayClass[];
  trainers: string[];
  styles: string[];
  onClassesChange: () => void;
}) {
  const [selectedHall, setSelectedHall] = useState(halls[0] ?? "");
  const timeSlots = generateTimeSlots(10, 22);

  // Build lookup: time -> class for selected hall
  const hallClasses = useMemo(() => {
    const map: Record<string, OpenDayClass> = {};
    for (const cls of classes) {
      if (cls.hall === selectedHall) map[cls.startTime] = cls;
    }
    return map;
  }, [classes, selectedHall]);

  // Count classes per hall for the tab badges
  const hallCounts = useMemo(() => {
    const counts: Record<string, number> = {};
    for (const hall of halls) counts[hall] = 0;
    for (const cls of classes) counts[cls.hall] = (counts[cls.hall] || 0) + 1;
    return counts;
  }, [classes, halls]);

  const [creatingTime, setCreatingTime] = useState<string | null>(null);

  async function confirmCreate(startTime: string, data: { trainer: string; style: string; endTime: string }) {
    await adminFetch("/api/admin/open-day/classes", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ eventId, hall: selectedHall, startTime, endTime: data.endTime, trainer: data.trainer, style: data.style }),
    });
    setCreatingTime(null);
    onClassesChange();
  }

  async function updateClass(id: number, data: Partial<OpenDayClass>) {
    await adminFetch("/api/admin/open-day/classes", {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ id, ...data }),
    });
    onClassesChange();
  }

  async function deleteClass(id: number) {
    await adminFetch(`/api/admin/open-day/classes?id=${id}`, { method: "DELETE" });
    onClassesChange();
  }

  async function cancelClass(id: number) {
    const cls = classes.find((c) => c.id === id);
    if (!cls) return;
    await updateClass(id, { cancelled: !cls.cancelled });
  }

  return (
    <div className="rounded-xl border border-white/10 bg-neutral-900 p-5 space-y-3">
      <h2 className="text-lg font-bold">Расписание</h2>

      {halls.length === 0 ? (
        <p className="text-sm text-neutral-500">Нет залов в расписании. Добавьте локации в разделе «Расписание».</p>
      ) : (
        <>
          {/* Hall selector */}
          <div className="flex gap-2 flex-wrap">
            {halls.map((hall) => (
              <button
                key={hall}
                onClick={() => setSelectedHall(hall)}
                className={`rounded-lg px-3 py-1.5 text-xs font-medium transition-all ${
                  selectedHall === hall
                    ? "bg-gold/20 text-gold border border-gold/40"
                    : "bg-neutral-800 text-neutral-400 border border-white/10 hover:text-white"
                }`}
              >
                {hall}
                {hallCounts[hall] > 0 && (
                  <span className={`ml-1.5 ${selectedHall === hall ? "text-gold/60" : "text-neutral-600"}`}>
                    {hallCounts[hall]}
                  </span>
                )}
              </button>
            ))}
          </div>

          {/* Time slots for selected hall */}
          <div className="space-y-1">
            {timeSlots.map((time) => {
              const cls = hallClasses[time];
              return (
                <div key={time} className="flex items-start gap-3 border-t border-white/5 py-1.5">
                  <span className="text-xs text-neutral-500 w-12 pt-1.5 shrink-0">{time}</span>
                  <div className="flex-1">
                    {cls ? (
                      <ClassCell
                        cls={cls}
                        minBookings={minBookings}
                        trainers={trainers}
                        styles={styles}
                        onUpdate={updateClass}
                        onDelete={deleteClass}
                        onCancel={cancelClass}
                      />
                    ) : creatingTime === time ? (
                      <NewClassForm
                        startTime={time}
                        trainers={trainers}
                        styles={styles}
                        onSave={(data) => confirmCreate(time, data)}
                        onCancel={() => setCreatingTime(null)}
                      />
                    ) : (
                      <button
                        onClick={() => setCreatingTime(time)}
                        className="w-full rounded-lg border border-dashed border-white/5 p-2 text-neutral-600 hover:text-gold hover:border-gold/20 transition-colors"
                      >
                        <Plus size={12} className="mx-auto" />
                      </button>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        </>
      )}
    </div>
  );
}


// --- Main Page ---

export default function OpenDayAdminPage() {
  const [event, setEvent] = useState<OpenDayEvent | null>(null);
  const [classes, setClasses] = useState<OpenDayClass[]>([]);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [saveStatus, setSaveStatus] = useState<"idle" | "saved" | "error">("idle");
  const [trainers, setTrainers] = useState<string[]>([]);
  const [styles, setStyles] = useState<string[]>([]);
  const [halls, setHalls] = useState<string[]>([]);
  const saveTimerRef = { current: null as ReturnType<typeof setTimeout> | null };

  // Load data
  useEffect(() => {
    Promise.all([
      adminFetch("/api/admin/open-day").then((r) => r.json()),
      adminFetch("/api/admin/team").then((r) => r.json()),
      adminFetch("/api/admin/sections/classes").then((r) => r.json()),
      adminFetch("/api/admin/sections/schedule").then((r) => r.json()),
    ])
      .then(([events, members, classesData, scheduleData]: [OpenDayEvent[], { name: string }[], { items: { name: string }[] }, { locations: { name: string }[] }]) => {
        if (events.length > 0) {
          setEvent(events[0]);
          loadClasses(events[0].id);
        }
        setTrainers(members.map((m) => m.name));
        setStyles(classesData.items.map((c) => c.name));
        setHalls(scheduleData.locations.map((l) => l.name));
      })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, []);

  function loadClasses(eventId: number) {
    adminFetch(`/api/admin/open-day/classes?eventId=${eventId}`)
      .then((r) => r.json())
      .then((data: OpenDayClass[]) => setClasses(data))
      .catch(() => {});
  }

  // Auto-save event changes
  const saveEvent = useCallback(
    (updated: OpenDayEvent) => {
      if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
      saveTimerRef.current = setTimeout(async () => {
        setSaving(true);
        try {
          const res = await adminFetch("/api/admin/open-day", {
            method: "PUT",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(updated),
          });
          setSaveStatus(res.ok ? "saved" : "error");
        } catch {
          setSaveStatus("error");
        }
        setSaving(false);
        setTimeout(() => setSaveStatus("idle"), 2000);
      }, 800);
    },
    []
  );

  function handleEventChange(patch: Partial<OpenDayEvent>) {
    if (!event) return;
    const updated = { ...event, ...patch };
    setEvent(updated);
    saveEvent(updated);
  }

  async function createEvent() {
    const today = new Date().toISOString().split("T")[0];
    const res = await adminFetch("/api/admin/open-day", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ date: today }),
    });
    const { id } = await res.json();
    setEvent({
      id,
      date: today,
      title: "День открытых дверей",
      pricePerClass: 30,
      discountPrice: 20,
      discountThreshold: 3,
      minBookings: 4,
      maxParticipants: 0,
      active: true,
    });
  }

  async function deleteEvent() {
    if (!event) return;
    await adminFetch(`/api/admin/open-day?id=${event.id}`, { method: "DELETE" });
    setEvent(null);
    setClasses([]);
  }

  if (loading) {
    return (
      <div className="flex items-center gap-2 py-12 text-neutral-500 justify-center">
        <Loader2 size={18} className="animate-spin" />
        Загрузка...
      </div>
    );
  }

  if (!event) {
    return (
      <div className="text-center py-12">
        <h1 className="text-2xl font-bold">День открытых дверей</h1>
        <p className="mt-2 text-neutral-400">Создайте мероприятие, чтобы начать</p>
        <button
          onClick={createEvent}
          className="mt-6 inline-flex items-center gap-2 rounded-xl bg-gold px-6 py-3 text-sm font-semibold text-black hover:bg-gold-light transition-colors"
        >
          <Plus size={16} />
          Создать мероприятие
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      {saveStatus !== "idle" && (
        <div className={`fixed bottom-4 right-4 z-50 flex items-center gap-2 rounded-lg border px-3 py-2 text-sm shadow-lg animate-in slide-in-from-right ${
          saveStatus === "saved" ? "bg-emerald-950/90 border-emerald-500/30 text-emerald-200" : "bg-red-950/90 border-red-500/30 text-red-200"
        }`}>
          {saveStatus === "saved" ? "Сохранено" : "Ошибка сохранения"}
        </div>
      )}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">День открытых дверей</h1>
        </div>
        <button
          onClick={deleteEvent}
          className="flex items-center gap-1.5 rounded-lg border border-red-500/20 px-3 py-1.5 text-xs text-red-400 hover:bg-red-500/10 transition-colors"
        >
          <Trash2 size={12} />
          Удалить
        </button>
      </div>

      <EventSettings event={event} onChange={handleEventChange} />

      <ScheduleGrid
        eventId={event.id}
        minBookings={event.minBookings}
        halls={halls}
        classes={classes}
        trainers={trainers}
        styles={styles}
        onClassesChange={() => loadClasses(event.id)}
      />

    </div>
  );
}
