"use client";

import { useState, useRef, useEffect } from "react";
import { motion, AnimatePresence } from "framer-motion";
import {
  Navigation,
  Share2,
  RefreshCw,
  Sparkles,
  ChevronRight,
  ChevronLeft,
  CornerDownLeft,
  Loader2,
} from "lucide-react";
import {
  DndContext,
  DragEndEvent,
  PointerSensor,
  TouchSensor,
  useSensor,
  useSensors,
} from "@dnd-kit/core";
import {
  SortableContext,
  verticalListSortingStrategy,
  arrayMove,
} from "@dnd-kit/sortable";
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
import Button from "@/components/Button";
import SortablePlanItem from "@/components/SortablePlanItem";
import PlanItemEditModal from "@/components/PlanItemEditModal";
import type { WeekendPlanData, PlanItem } from "@/types";

interface BlindboxPlanProps {
  days: WeekendPlanData[];
  onAccept: () => void;
  onRegenerate: () => void;
  onShare: () => void;
  onBack: () => void;
  accepted?: boolean;
  regenerating?: boolean;
  onDaysChange?: (newDays: WeekendPlanData[]) => void;
  location?: string;
  startLocationLabel?: string;
  onRefine?: (instruction: string) => Promise<void>;
}

export default function BlindboxPlan({
  days,
  onAccept,
  onRegenerate,
  onShare,
  onBack,
  accepted,
  regenerating,
  onDaysChange,
  location,
  startLocationLabel,
  onRefine,
}: BlindboxPlanProps) {
  const [dayIndex, setDayIndex] = useState(0);
  const scrollRef = useRef<HTMLDivElement>(null);
  const currentDay = days[dayIndex];
  const hasNext = dayIndex < days.length - 1;
  const hasPrev = dayIndex > 0;
  const canEdit = !!onDaysChange;

  const [editingItem, setEditingItem] = useState<{ dayIndex: number; itemIndex: number } | null>(null);
  const [draft, setDraft] = useState<PlanItem | null>(null);
  const [refineInput, setRefineInput] = useState("");
  const [refining, setRefining] = useState(false);

  useEffect(() => {
    scrollRef.current?.scrollTo({ top: 0, behavior: "smooth" });
  }, [dayIndex]);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),
    useSensor(TouchSensor, { activationConstraint: { delay: 200, tolerance: 5 } }),
  );

  function handleDragEnd(event: DragEndEvent) {
    const { active, over } = event;
    if (!over || active.id === over.id || !onDaysChange) return;
    const items = days[dayIndex].items;
    const ids = items.map((_, i) => `${dayIndex}-${i}`);
    const oldIndex = ids.indexOf(String(active.id));
    const newIndex = ids.indexOf(String(over.id));
    if (oldIndex === -1 || newIndex === -1) return;
    const newDays = days.map((day, di) =>
      di === dayIndex ? { ...day, items: arrayMove(day.items, oldIndex, newIndex) } : day,
    );
    onDaysChange(newDays);
  }

  function handleSaveDraft() {
    if (!draft || !editingItem || !onDaysChange) return;
    const newDays = days.map((day, di) =>
      di !== editingItem.dayIndex
        ? day
        : {
            ...day,
            items: day.items.map((item, ii) =>
              ii === editingItem.itemIndex ? draft : item,
            ),
          },
    );
    onDaysChange(newDays);
    setEditingItem(null);
    setDraft(null);
  }

  function handleMoveToDayIndex(targetDayIndex: number) {
    if (!draft || !editingItem || !onDaysChange) return;
    if (targetDayIndex === editingItem.dayIndex) return;
    const newDays = days.map((day, di) => {
      if (di === editingItem.dayIndex) {
        return { ...day, items: day.items.filter((_, ii) => ii !== editingItem.itemIndex) };
      }
      if (di === targetDayIndex) {
        return { ...day, items: [...day.items, draft] };
      }
      return day;
    });
    onDaysChange(newDays);
    setEditingItem(null);
    setDraft(null);
  }

  async function handleRefine() {
    if (!refineInput.trim() || refining || !onRefine) return;
    setRefining(true);
    try {
      await onRefine(refineInput.trim());
      setRefineInput("");
    } finally {
      setRefining(false);
    }
  }

  if (!currentDay) return null;

  return (
    <div className="flex min-h-0 flex-1 flex-col">
      {/* Day header */}
      <div className="shrink-0 pb-3 text-center">
        <motion.div
          className="inline-flex items-center gap-1.5 rounded-full bg-purple-600/15 px-3 py-1 text-xs font-bold text-purple-400"
          initial={{ scale: 0.8, opacity: 0 }}
          animate={{ scale: 1, opacity: 1 }}
          transition={{ delay: 0.2 }}
        >
          <Sparkles size={12} />
          {currentDay.date} · 行程规划
        </motion.div>

        {days.length > 1 && (
          <div className="mt-2 flex items-center justify-center gap-1.5">
            {days.map((day, i) => (
              <button
                key={day.date}
                onClick={() => setDayIndex(i)}
                aria-label={day.date}
                aria-pressed={i === dayIndex}
                className={`rounded-full transition-all ${
                  i === dayIndex
                    ? "h-1.5 w-5 bg-purple-400"
                    : "h-1.5 w-1.5 bg-purple-400/25"
                }`}
              />
            ))}
          </div>
        )}

        {currentDay.summary && (
          <motion.p
            className="mt-2 text-xs text-muted"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.4 }}
          >
            {currentDay.summary}
          </motion.p>
        )}
      </div>

      {/* Scrollable timeline */}
      <div ref={scrollRef} className="min-h-0 flex-1 overflow-y-auto scrollbar-none">
        <AnimatePresence mode="wait">
          <motion.div
            key={dayIndex}
            className="relative mx-auto max-w-sm px-4 pb-2 pl-9"
            initial={{ opacity: 0, x: 20 }}
            animate={{ opacity: 1, x: 0 }}
            exit={{ opacity: 0, x: -20 }}
            transition={{ duration: 0.25 }}
          >
            <div className="absolute left-[21px] top-2 bottom-2 w-px bg-purple-500/20" />

            <DndContext
              key={dayIndex}
              sensors={sensors}
              modifiers={[restrictToVerticalAxis]}
              onDragEnd={handleDragEnd}
            >
              <SortableContext
                items={currentDay.items.map((_, i) => `${dayIndex}-${i}`)}
                strategy={verticalListSortingStrategy}
              >
                {/* Transit from home */}
                {currentDay.transitFromStart != null && (
                  <div className="flex items-start gap-1.5 py-2 pl-1">
                    <Navigation size={9} className="mt-0.5 shrink-0 text-purple-400/40" />
                    <div className="flex flex-col gap-0.5">
                      <span className="text-[10px] font-medium text-dim">从{startLocationLabel ?? "出发地"}出发</span>
                      {currentDay.transitFromStartDescription && (
                        <span className="text-[10px] leading-snug text-dim">
                          {currentDay.transitFromStartDescription}
                        </span>
                      )}
                      <span className="text-[10px] text-dim/70">约 {currentDay.transitFromStart} 分钟</span>
                    </div>
                  </div>
                )}
                {currentDay.items.map((item, i) => (
                  <motion.div
                    key={`${dayIndex}-${i}`}
                    initial={{ opacity: 0, x: -10 }}
                    animate={{ opacity: 1, x: 0 }}
                    transition={{ delay: 0.1 + i * 0.08 }}
                  >
                    <SortablePlanItem
                      id={`${dayIndex}-${i}`}
                      item={item}
                      canEdit={canEdit}
                      onEdit={() => {
                        setEditingItem({ dayIndex, itemIndex: i });
                        setDraft({ ...item });
                      }}
                    />
                    {/* Transit connector */}
                    {item.transitToNext != null && i < currentDay.items.length - 1 && (
                      <div className="flex items-start gap-1.5 py-2 pl-1">
                        <Navigation size={9} className="mt-0.5 shrink-0 text-purple-400/40" />
                        <div className="flex flex-col gap-0.5">
                          {item.transitDescription && (
                            <span className="text-[10px] leading-snug text-dim">
                              {item.transitDescription}
                            </span>
                          )}
                          <span className="text-[10px] text-dim/70">约 {item.transitToNext} 分钟</span>
                        </div>
                      </div>
                    )}
                    {/* Transit back home */}
                    {i === currentDay.items.length - 1 && currentDay.transitToEnd != null && (
                      <div className="flex items-start gap-1.5 py-2 pl-1">
                        <Navigation size={9} className="mt-0.5 shrink-0 text-purple-400/40" />
                        <div className="flex flex-col gap-0.5">
                          <span className="text-[10px] font-medium text-dim">返回{startLocationLabel ?? "出发地"}</span>
                          {currentDay.transitToEndDescription && (
                            <span className="text-[10px] leading-snug text-dim">
                              {currentDay.transitToEndDescription}
                            </span>
                          )}
                          <span className="text-[10px] text-dim/70">约 {currentDay.transitToEnd} 分钟</span>
                        </div>
                      </div>
                    )}
                  </motion.div>
                ))}
              </SortableContext>
            </DndContext>
          </motion.div>
        </AnimatePresence>

        {/* Back to pool */}
        <div className="mt-6 flex justify-center pb-4">
          <button
            onClick={onBack}
            className="flex items-center gap-1.5 text-xs font-medium text-muted active:text-foreground"
          >
            <CornerDownLeft size={12} />
            返回想法池
          </button>
        </div>
      </div>

      {/* Fixed bottom bar */}
      <div className="shrink-0 border-t border-border/40 bg-background/80 pt-3 pb-[max(0.75rem,env(safe-area-inset-bottom))] backdrop-blur-lg">
        {onRefine && (
          <div className="mx-auto flex max-w-sm items-center gap-2 px-4 pb-2">
            <input
              value={refineInput}
              onChange={(e) => setRefineInput(e.target.value)}
              onKeyDown={(e) => { if (e.key === "Enter") handleRefine(); }}
              placeholder="告诉 AI 你想怎么改..."
              disabled={refining}
              className="h-9 flex-1 rounded-xl bg-surface px-3 text-sm outline-none ring-1 ring-border focus:ring-purple-600 disabled:opacity-50"
            />
            <button
              onClick={handleRefine}
              disabled={!refineInput.trim() || refining}
              className="flex h-9 w-9 items-center justify-center rounded-xl bg-purple-600/15 text-purple-400 disabled:opacity-30"
            >
              {refining ? <Loader2 size={15} className="animate-spin" /> : <Sparkles size={15} />}
            </button>
          </div>
        )}

        {days.length > 1 && (
          <div className="mx-auto mb-2.5 flex max-w-sm items-center justify-center gap-2 px-4">
            {hasPrev && (
              <motion.button
                initial={{ scale: 0, opacity: 0 }}
                animate={{ scale: 1, opacity: 1 }}
                onClick={() => setDayIndex(dayIndex - 1)}
                className="flex items-center gap-1 rounded-full bg-surface px-3 py-1.5 text-[11px] font-bold text-purple-400 ring-1 ring-border/60 active:bg-elevated"
              >
                <ChevronLeft size={12} />
                {days[dayIndex - 1].date}
              </motion.button>
            )}
            <span className="text-[10px] text-dim">
              {dayIndex + 1} / {days.length}
            </span>
            {hasNext && (
              <motion.button
                initial={{ scale: 0, opacity: 0 }}
                animate={{ scale: 1, opacity: 1 }}
                onClick={() => setDayIndex(dayIndex + 1)}
                className="flex items-center gap-1 rounded-full bg-purple-600/15 px-3 py-1.5 text-[11px] font-bold text-purple-400 active:bg-purple-600/25"
              >
                {days[dayIndex + 1].date}
                <ChevronRight size={12} />
              </motion.button>
            )}
          </div>
        )}

        <div className="mx-auto flex max-w-sm items-center justify-center gap-3 px-4">
          {accepted ? (
            <Button onClick={onShare} variant="purple" shape="pill" icon={<Share2 size={14} />}>
              分享计划
            </Button>
          ) : (
            <>
              <Button onClick={onAccept} variant="purple" shape="pill" icon={<Sparkles size={14} />}>
                接受契约
              </Button>
              <Button onClick={onRegenerate} variant="secondary" shape="pill" loading={regenerating} icon={<RefreshCw size={14} />}>
                换一个方案
              </Button>
            </>
          )}
        </div>
      </div>

      {/* Edit item modal */}
      <PlanItemEditModal
        open={!!editingItem && !!draft}
        editingItem={editingItem}
        draft={draft}
        days={days}
        location={location}
        onDraftChange={setDraft}
        onSave={handleSaveDraft}
        onClose={() => { setEditingItem(null); setDraft(null); }}
        onMoveToDayIndex={handleMoveToDayIndex}
      />
    </div>
  );
}
