import { useRouter } from "expo-router";
import { useRef, useState } from "react";
import { Pressable, StyleSheet, Text, TextInput, View } from "react-native";
import { Gesture, GestureDetector } from "react-native-gesture-handler";
import Animated, {
  runOnJS,
  useAnimatedStyle,
  useSharedValue,
  withSpring,
  withTiming,
} from "react-native-reanimated";
import { haptic } from "../lib/haptics";
import { PRIORITY_COLOR } from "../lib/priority";
import { parseQuickAdd } from "../lib/quickadd";
import { activeProjects, createTask, tasksByStatus, todayTasks, updateTask } from "../lib/store";
import { C } from "../lib/theme";
import { useStore } from "../lib/useStore";
import type { Task, TaskStatus } from "../lib/types";

const Q = {
  next: { title: "Next up", color: "#3DBF77", bg: "#15301F", border: "#1E4D33" },
  waiting: { title: "Waiting for", color: "#E0A93E", bg: "#33270F", border: "#544019" },
  someday: { title: "Someday", color: "#9D8FE8", bg: "#221E38", border: "#38315C" },
  projects: { title: "Projects", color: "#5B9DE8", bg: "#152538", border: "#1F3D5C" },
};

type DropZone = Extract<TaskStatus, "inbox" | "next" | "waiting" | "someday">;
type Rect = { x: number; y: number; w: number; h: number };
type ZoneRects = Partial<Record<DropZone, Rect>>;

const SPRING = { damping: 18, stiffness: 260, mass: 0.6 };

/** Long-press-drag wrapper: spring transforms, haptics, window-coord drop. */
function Draggable({
  task,
  findZone,
  children,
}: {
  task: Task;
  findZone: (x: number, y: number) => DropZone | null;
  children: React.ReactNode;
}) {
  const tx = useSharedValue(0);
  const ty = useSharedValue(0);
  const active = useSharedValue(false);

  const drop = (x: number, y: number) => {
    const zone = findZone(x, y);
    if (zone && zone !== task.status) {
      haptic.success();
      updateTask(task.id, { status: zone });
    }
  };

  const pan = Gesture.Pan()
    .activateAfterLongPress(180)
    .onStart(() => {
      active.value = true;
      runOnJS(haptic.pickup)();
    })
    .onUpdate((e) => {
      tx.value = e.translationX;
      ty.value = e.translationY;
    })
    .onEnd((e) => {
      runOnJS(drop)(e.absoluteX, e.absoluteY);
    })
    .onFinalize(() => {
      active.value = false;
      tx.value = withSpring(0, SPRING);
      ty.value = withSpring(0, SPRING);
    });

  const style = useAnimatedStyle(() => ({
    transform: [
      { translateX: tx.value },
      { translateY: ty.value },
      { scale: withTiming(active.value ? 1.06 : 1, { duration: 120 }) },
    ],
    zIndex: active.value ? 100 : 0,
    elevation: active.value ? 8 : 0,
    opacity: withTiming(active.value ? 0.92 : 1, { duration: 120 }),
  }));

  return (
    <GestureDetector gesture={pan}>
      <Animated.View style={style}>{children}</Animated.View>
    </GestureDetector>
  );
}

function DragRow({ task, findZone }: { task: Task; findZone: (x: number, y: number) => DropZone | null }) {
  const router = useRouter();
  return (
    <Draggable task={task} findZone={findZone}>
      <Pressable style={s.dragRow} onPress={() => router.push(`/task/${task.id}`)}>
        <View style={[s.priorityDot, { backgroundColor: PRIORITY_COLOR[task.priority] }]} />
        <Text style={s.dragRowText} numberOfLines={1}>
          {task.title}
        </Text>
      </Pressable>
    </Draggable>
  );
}

export default function Home() {
  const router = useRouter();
  const store = useStore();
  const [draft, setDraft] = useState("");
  const zones = useRef<ZoneRects>({});
  const zoneRefs = useRef<Partial<Record<DropZone, View | null>>>({});

  const measureZone = (zone: DropZone) => () => {
    zoneRefs.current[zone]?.measureInWindow((x, y, w, h) => {
      zones.current[zone] = { x, y, w, h };
    });
  };

  const findZone = (x: number, y: number): DropZone | null => {
    for (const [zone, r] of Object.entries(zones.current) as [DropZone, Rect][]) {
      if (x >= r.x && x <= r.x + r.w && y >= r.y && y <= r.y + r.h) return zone;
    }
    return null;
  };

  const capture = () => {
    if (!draft.trim()) return;
    const parsed = parseQuickAdd(draft, store.projects);
    if (!parsed.title) return;
    setDraft("");
    haptic.tap();
    createTask({ ...parsed, status: "inbox" });
  };

  const inbox = tasksByStatus(store, "inbox");
  const next = tasksByStatus(store, "next");
  const waiting = tasksByStatus(store, "waiting");
  const someday = tasksByStatus(store, "someday");
  const projects = activeProjects(store).filter((p) => p.status === "active");
  const { overdue, today } = todayTasks(store);

  const quadrant = (zone: Exclude<DropZone, "inbox">, tasks: Task[], onOpen: () => void) => {
    const q = Q[zone];
    return (
      <View
        ref={(r) => {
          zoneRefs.current[zone] = r;
        }}
        onLayout={measureZone(zone)}
        style={[s.quad, { backgroundColor: q.bg, borderColor: q.border }]}
      >
        <Pressable style={s.quadHead} onPress={onOpen}>
          <Text style={[s.quadTitle, { color: q.color }]}>{q.title}</Text>
          <Text style={[s.quadCount, { color: q.color }]}>{tasks.length}</Text>
        </Pressable>
        {tasks.slice(0, 3).map((t) => (
          <DragRow key={t.id} task={t} findZone={findZone} />
        ))}
      </View>
    );
  };

  return (
    <View style={s.screen}>
      <TextInput
        style={s.capture}
        placeholder="Capture…  (tomorrow p1 @home #project ~30m)"
        placeholderTextColor={C.muted}
        value={draft}
        onChangeText={setDraft}
        onSubmitEditing={capture}
        submitBehavior="submit"
        returnKeyType="done"
      />
      <View style={s.pillRow}>
        <View
          ref={(r) => {
            zoneRefs.current.inbox = r;
          }}
          onLayout={measureZone("inbox")}
          style={s.pill}
        >
          <Pressable style={s.pillPress} onPress={() => router.push("/list/inbox")}>
            <Text style={s.pillText}>📥 Inbox</Text>
            <Text style={[s.pillText, { color: inbox.length ? C.text : C.muted }]}>{inbox.length}</Text>
          </Pressable>
        </View>
        <View style={s.pill}>
          <Pressable style={s.pillPress} onPress={() => router.push("/today")}>
            <Text style={s.pillText}>📅 Today</Text>
            <Text style={[s.pillText, { color: overdue.length ? C.danger : today.length ? C.text : C.muted }]}>
              {overdue.length ? `${overdue.length}!` : today.length}
            </Text>
          </Pressable>
        </View>
      </View>
      {inbox.slice(0, 3).map((t) => (
        <DragRow key={t.id} task={t} findZone={findZone} />
      ))}
      {store.syncError && <Text style={s.error}>{store.syncError}</Text>}
      <View style={s.grid}>
        <View style={s.gridRow}>
          {quadrant("next", next, () => router.push("/list/next"))}
          {quadrant("waiting", waiting, () => router.push("/list/waiting"))}
        </View>
        <View style={s.gridRow}>
          {quadrant("someday", someday, () => router.push("/list/someday"))}
          <View style={[s.quad, { backgroundColor: Q.projects.bg, borderColor: Q.projects.border }]}>
            <Pressable style={{ flex: 1 }} onPress={() => router.push("/projects")}>
              <View style={s.quadHead}>
                <Text style={[s.quadTitle, { color: Q.projects.color }]}>{Q.projects.title}</Text>
                <Text style={[s.quadCount, { color: Q.projects.color }]}>{projects.length}</Text>
              </View>
              {projects.slice(0, 3).map((p) => (
                <Text key={p.id} style={s.quadItem} numberOfLines={1}>
                  {p.name}
                </Text>
              ))}
            </Pressable>
          </View>
        </View>
      </View>
      <Pressable style={s.fab} onPress={() => { haptic.tap(); router.push("/add"); }}>
        <Text style={s.fabText}>＋</Text>
      </Pressable>
    </View>
  );
}

const s = StyleSheet.create({
  screen: { flex: 1, backgroundColor: C.bg, padding: 12 },
  capture: {
    padding: 14,
    borderRadius: 12,
    backgroundColor: C.surface,
    color: C.text,
    fontSize: 16,
    borderWidth: 1,
    borderColor: C.border,
  },
  pillRow: { flexDirection: "row", gap: 10, marginTop: 10 },
  pill: {
    flex: 1,
    borderRadius: 12,
    backgroundColor: C.surface,
    borderWidth: 1,
    borderColor: C.border,
  },
  pillPress: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    paddingVertical: 12,
    paddingHorizontal: 14,
  },
  pillText: { color: C.text, fontSize: 15, fontWeight: "600" },
  dragRow: {
    flexDirection: "row",
    alignItems: "center",
    gap: 8,
    marginTop: 6,
    paddingVertical: 9,
    paddingHorizontal: 12,
    borderRadius: 10,
    backgroundColor: C.surface2,
    borderWidth: 1,
    borderColor: C.border,
  },
  dragRowText: { color: C.text, fontSize: 14, flex: 1 },
  priorityDot: { width: 8, height: 8, borderRadius: 4 },
  grid: { flex: 1, marginTop: 10, gap: 10 },
  gridRow: { flex: 1, flexDirection: "row", gap: 10 },
  quad: { flex: 1, borderRadius: 16, borderWidth: 1, padding: 12, overflow: "visible" },
  quadHead: { flexDirection: "row", justifyContent: "space-between", marginBottom: 4 },
  quadTitle: { fontSize: 16, fontWeight: "700" },
  quadCount: { fontSize: 16, fontWeight: "700" },
  quadItem: { color: C.muted, fontSize: 13, marginBottom: 4 },
  error: { color: C.danger, marginTop: 8 },
  fab: {
    position: "absolute",
    right: 20,
    bottom: 24,
    width: 58,
    height: 58,
    borderRadius: 29,
    backgroundColor: C.accent,
    alignItems: "center",
    justifyContent: "center",
    elevation: 6,
    shadowColor: "#000",
    shadowOpacity: 0.35,
    shadowRadius: 8,
    shadowOffset: { width: 0, height: 4 },
  },
  fabText: { color: "#FFFFFF", fontSize: 28, lineHeight: 32, fontWeight: "600" },
});
