"use client";
import React, { useState, useEffect, useCallback, useRef } from "react";
import { useI18n } from "@/lib/i18n";
import { Task, Tag } from "./TaskList";
import { MarkdownNoteEditor } from "./MarkdownNoteEditor";
import { getCustomTags, MockTag } from "@/lib/mockData";

interface Props {
  task: Task;
  listId: string;
  listName?: string;
  onClose: () => void;
  onUpdate: (t: Task) => void;
  onDelete: () => void;
  isDemo?: boolean;
  onDemoUpdateTask?: (updated: Task) => void;
  onDemoDeleteTask?: (id: string) => void;
}

export function TaskDetail({
  task,
  listId,
  listName,
  onClose,
  onUpdate,
  onDelete,
  isDemo = false,
  onDemoUpdateTask,
  onDemoDeleteTask,
}: Props) {
  const { t, lang } = useI18n();

  const [title, setTitle] = useState(task.title);
  const [note, setNote] = useState(task.note || "");
  const [dueDate, setDueDate] = useState(task.dueDate ? task.dueDate.split("T")[0] : "");
  const [priority, setPriority] = useState(task.priority);
  const [tags, setTags] = useState<{ tag: Tag }[]>(task.tags || []);
  const [allAvailableTags, setAllAvailableTags] = useState<MockTag[]>([]);
  const [showTagPicker, setShowTagPicker] = useState(false);
  const [newTagName, setNewTagName] = useState("");

  const [newSubtitle, setNewSubtitle] = useState("");
  const [subtasks, setSubtasks] = useState(task.children || []);
  const [showSubtasks, setShowSubtasks] = useState(true);
  const [saving, setSaving] = useState(false);

  // Mobile Bottom-Sheet: swipe down to close
  const touchStartY = useRef<number | null>(null);
  const touchStartX = useRef<number | null>(null);
  const gestureDirection = useRef<"vertical" | "horizontal" | null>(null);
  const [panelTranslateY, setPanelTranslateY] = useState(0);
  const [isMobile, setIsMobile] = useState(false);

  useEffect(() => {
    const check = () => setIsMobile(window.innerWidth <= 768);
    check();
    window.addEventListener("resize", check);
    return () => window.removeEventListener("resize", check);
  }, []);

  const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
  const currentTaskId = useRef(task.id);

  const priorityMap = [
    { label: t("priorityNone"), color: "var(--text-tertiary)", icon: "" },
    { label: t("priorityLow"), color: "var(--priority-low)", icon: "▼" },
    { label: t("priorityMedium"), color: "var(--priority-medium)", icon: "▶" },
    { label: t("priorityHigh"), color: "var(--priority-high)", icon: "▲" },
  ];

  // Sync state when switching task
  useEffect(() => {
    if (saveTimer.current) {
      clearTimeout(saveTimer.current);
      saveTimer.current = null;
    }
    currentTaskId.current = task.id;
    setTitle(task.title);
    setNote(task.note || "");
    setDueDate(task.dueDate ? task.dueDate.split("T")[0] : "");
    setPriority(task.priority);
    setTags(task.tags || []);
    setSubtasks(task.children || []);
    setAllAvailableTags(getCustomTags());
  }, [task.id, task.title, task.note, task.dueDate, task.priority, task.children, task.tags]);

  useEffect(() => {
    return () => {
      if (saveTimer.current) clearTimeout(saveTimer.current);
    };
  }, []);

  const save = useCallback(
    async (taskId: string, data: Record<string, unknown>) => {
      if (taskId !== currentTaskId.current) return;
      setSaving(true);

      if (isDemo) {
        const updatedTask: Task = {
          ...task,
          ...data,
          children: subtasks,
          tags,
          updatedAt: new Date().toISOString(),
        } as Task;
        if (onDemoUpdateTask) onDemoUpdateTask(updatedTask);
        onUpdate(updatedTask);
        setSaving(false);
        return;
      }

      try {
        const res = await fetch(`/api/tasks/${taskId}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(data),
        });
        if (res.ok) {
          const updated = await res.json();
          if (taskId === currentTaskId.current) {
            onUpdate({ ...updated, children: subtasks, tags });
          }
        }
      } catch (err) {
        console.error("[TaskDetail] save failed", err);
      } finally {
        setSaving(false);
      }
    },
    [isDemo, onDemoUpdateTask, onUpdate, subtasks, tags, task]
  );

  const debounceSave = useCallback(
    (data: Record<string, unknown>) => {
      if (saveTimer.current) clearTimeout(saveTimer.current);
      saveTimer.current = setTimeout(() => {
        save(task.id, data);
      }, 500);
    },
    [save, task.id]
  );

  const handleNoteChange = (newNote: string) => {
    setNote(newNote);
    debounceSave({ note: newNote });
  };

  const handleToggleComplete = useCallback(async () => {
    const nextCompleted = !task.completed;
    save(task.id, {
      completed: nextCompleted,
      completedAt: nextCompleted ? new Date().toISOString() : null,
    });
  }, [save, task.id, task.completed]);

  const handleDelete = useCallback(async () => {
    if (!confirm(t("deleteTaskConfirm"))) return;
    if (isDemo) {
      if (onDemoDeleteTask) onDemoDeleteTask(task.id);
      onDelete();
      return;
    }

    try {
      await fetch(`/api/tasks/${task.id}`, { method: "DELETE" });
      onDelete();
    } catch (err) {
      console.error("[TaskDetail] delete failed", err);
    }
  }, [t, isDemo, onDemoDeleteTask, task.id, onDelete]);

  // Tag Management
  const toggleTag = (tag: MockTag) => {
    const exists = tags.some((tItem) => tItem.tag.id === tag.id);
    let nextTags: { tag: Tag }[];
    if (exists) {
      nextTags = tags.filter((tItem) => tItem.tag.id !== tag.id);
    } else {
      nextTags = [...tags, { tag }];
    }
    setTags(nextTags);
    save(task.id, { tags: nextTags });
  };

  const addCustomTag = () => {
    const trimmed = newTagName.trim().replace(/^#/, "");
    if (!trimmed) return;
    const newTag: MockTag = {
      id: "tag-" + Date.now(),
      name: trimmed,
      color: ["#4B7BF5", "#10B981", "#EF4444", "#F59E0B", "#8B5CF6"][Math.floor(Math.random() * 5)],
    };
    setAllAvailableTags((p) => [...p, newTag]);
    toggleTag(newTag);
    setNewTagName("");
  };

  const addSubtask = useCallback(async () => {
    const tTitle = newSubtitle.trim();
    if (!tTitle) return;

    if (isDemo) {
      const newSub: Task = {
        id: "demo-sub-" + Date.now(),
        listId,
        parentId: task.id,
        title: tTitle,
        note: null,
        completed: false,
        completedAt: null,
        dueDate: null,
        priority: 0,
        sortOrder: subtasks.length,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString(),
        children: [],
        tags: [],
      };
      const nextSubs = [...subtasks, newSub];
      setSubtasks(nextSubs);
      setNewSubtitle("");
      const updatedParent = { ...task, children: nextSubs };
      if (onDemoUpdateTask) onDemoUpdateTask(updatedParent);
      onUpdate(updatedParent);
      return;
    }

    try {
      const res = await fetch("/api/tasks", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ title: tTitle, listId, parentId: task.id }),
      });
      if (res.ok) {
        const sub = await res.json();
        setSubtasks((prev) => {
          const next = [...prev, sub];
          onUpdate({ ...task, children: next });
          return next;
        });
        setNewSubtitle("");
      }
    } catch (err) {
      console.error("[TaskDetail] addSubtask failed", err);
    }
  }, [newSubtitle, isDemo, listId, task, subtasks, onDemoUpdateTask, onUpdate]);

  const toggleSubtask = useCallback(
    async (sub: Task) => {
      const newCompleted = !sub.completed;

      if (isDemo) {
        const nextSubs = subtasks.map((s) =>
          s.id === sub.id
            ? { ...s, completed: newCompleted, completedAt: newCompleted ? new Date().toISOString() : null }
            : s
        );
        setSubtasks(nextSubs);
        const updatedParent = { ...task, children: nextSubs };
        if (onDemoUpdateTask) onDemoUpdateTask(updatedParent);
        onUpdate(updatedParent);
        return;
      }

      try {
        const res = await fetch(`/api/tasks/${sub.id}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ completed: newCompleted }),
        });
        if (res.ok) {
          const updated = await res.json();
          setSubtasks((prev) => {
            const next = prev.map((s) => (s.id === sub.id ? updated : s));
            onUpdate({ ...task, children: next });
            return next;
          });
        }
      } catch (err) {
        console.error("[TaskDetail] toggleSubtask failed", err);
      }
    },
    [isDemo, onDemoUpdateTask, onUpdate, subtasks, task]
  );

  const deleteSubtask = useCallback(
    async (subId: string) => {
      if (isDemo) {
        const nextSubs = subtasks.filter((s) => s.id !== subId);
        setSubtasks(nextSubs);
        const updatedParent = { ...task, children: nextSubs };
        if (onDemoUpdateTask) onDemoUpdateTask(updatedParent);
        onUpdate(updatedParent);
        return;
      }

      try {
        await fetch(`/api/tasks/${subId}`, { method: "DELETE" });
        setSubtasks((prev) => {
          const next = prev.filter((s) => s.id !== subId);
          onUpdate({ ...task, children: next });
          return next;
        });
      } catch (err) {
        console.error("[TaskDetail] deleteSubtask failed", err);
      }
    },
    [isDemo, onDemoUpdateTask, onUpdate, subtasks, task]
  );

  // Touch handlers: 모바일에서 아래로 스와이프 → 패널 닫기 (스크롤과 충돌 방지)
  const handleTouchStart = (e: React.TouchEvent) => {
    // 스와이프 핸들 또는 detail-header 영역에서만 드래그 닫기 허용
    const target = e.target as HTMLElement;
    const isHandle = target.closest(".mobile-swipe-handle") || target.closest(".detail-header");
    if (!isHandle || !isMobile) return;
    touchStartY.current = e.touches[0].clientY;
    touchStartX.current = e.touches[0].clientX;
    gestureDirection.current = null;
  };

  const handleTouchMove = (e: React.TouchEvent) => {
    if (touchStartY.current === null || touchStartX.current === null) return;
    const deltaY = e.touches[0].clientY - touchStartY.current;
    const deltaX = e.touches[0].clientX - touchStartX.current;

    // 초기 제스처 방향 결정 (첫 10px 이동 기준)
    if (gestureDirection.current === null && (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10)) {
      gestureDirection.current = Math.abs(deltaY) > Math.abs(deltaX) ? "vertical" : "horizontal";
    }

    // 수직 드래그일 때만 패널 이동
    if (gestureDirection.current === "vertical" && deltaY > 0) {
      e.preventDefault();
      setPanelTranslateY(deltaY);
    }
  };

  const handleTouchEnd = () => {
    if (panelTranslateY > 120) {
      onClose();
    }
    setPanelTranslateY(0);
    touchStartY.current = null;
    touchStartX.current = null;
    gestureDirection.current = null;
  };

  const completedCount = subtasks.filter((s) => s.completed).length;

  return (
    <aside
      className="detail-panel mobile-open"
      onTouchStart={handleTouchStart}
      onTouchMove={handleTouchMove}
      onTouchEnd={handleTouchEnd}
      style={{
        transform: isMobile && panelTranslateY > 0 ? `translateY(${panelTranslateY}px)` : undefined,
        transition: panelTranslateY === 0 ? "transform 0.3s cubic-bezier(0.16, 1, 0.3, 1)" : "none",
      }}
    >
      {/* Mobile Swipe Handle Indicator */}
      <div className="mobile-swipe-handle mobile-only" style={{ width: 36, height: 4, background: "var(--border)", borderRadius: 2, margin: "6px auto 0" }} />

      {/* Top action bar */}
      <div className="detail-header" style={{ padding: "10px 16px 8px" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
          <button
            className={`task-check-btn${task.completed ? " checked" : ""}`}
            onClick={handleToggleComplete}
            aria-label={task.completed ? "Mark incomplete" : "Mark complete"}
            type="button"
          />
          <span style={{ fontSize: 11, color: "var(--text-tertiary)" }}>
            {saving ? t("saving") : t("autoSaved")}
          </span>
        </div>

        <div className="detail-actions">
          <button
            className="icon-btn"
            id="delete-task-btn"
            onClick={handleDelete}
            title={t("deleteTaskConfirm").split("?")[0]}
            type="button"
          >
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <polyline points="3 6 5 6 21 6" /><path d="M19 6l-1 14H6L5 6" /><path d="M10 11v6M14 11v6" /><path d="M9 6V4h6v2" />
            </svg>
          </button>
          <button
            className="icon-btn"
            id="close-detail-btn"
            onClick={onClose}
            aria-label="Close"
            type="button"
          >
            <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" />
            </svg>
          </button>
        </div>
      </div>

      {/* Main scrollable body */}
      <div className="detail-scroll" style={{ display: "flex", flexDirection: "column", height: "calc(100% - 48px)", padding: "8px 16px 12px", gap: 10 }}>
        {/* Title input */}
        <textarea
          id="task-title-input"
          className="detail-title-input"
          value={title}
          onChange={(e) => {
            setTitle(e.target.value);
            debounceSave({ title: e.target.value });
          }}
          placeholder={t("taskTitlePlaceholder")}
          rows={1}
          style={{
            textDecoration: task.completed ? "line-through" : "none",
            color: task.completed ? "var(--text-tertiary)" : "var(--text-primary)",
            fontSize: 20,
            fontWeight: 700,
          }}
        />

        {/* Compact Metadata Strip (Priority, Due Date & Tags) */}
        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", paddingBottom: 6, borderBottom: "1px solid var(--border)" }}>
          {/* Priority */}
          <div style={{ display: "flex", alignItems: "center", gap: 4 }}>
            <span style={{ fontSize: 11, fontWeight: 600, color: "var(--text-tertiary)", textTransform: "uppercase" }}>{t("priority")}:</span>
            <div className="priority-selector" style={{ gap: 4 }}>
              {priorityMap.map((p, i) => (
                <button
                  key={i}
                  id={`priority-${i}`}
                  className={`priority-btn${priority === i ? ` active-${["none", "low", "medium", "high"][i]}` : ""}`}
                  style={{ color: priority === i ? p.color : undefined, padding: "3px 8px", fontSize: 11 }}
                  onClick={() => {
                    setPriority(i);
                    debounceSave({ priority: i });
                  }}
                  type="button"
                >
                  {p.icon && <span style={{ color: p.color }}>{p.icon}</span>}
                  {p.label}
                </button>
              ))}
            </div>
          </div>

          {/* Due Date */}
          <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
            <input
              id="due-date-input"
              type="date"
              className="form-input"
              value={dueDate}
              onChange={(e) => {
                setDueDate(e.target.value);
                debounceSave({ dueDate: e.target.value || null });
              }}
              style={{ width: "auto", padding: "3px 8px", fontSize: 12 }}
            />
            {dueDate && (
              <button
                className="btn btn-ghost btn-sm"
                style={{ padding: "2px 6px", fontSize: 11 }}
                onClick={() => {
                  setDueDate("");
                  debounceSave({ dueDate: null });
                }}
                type="button"
              >
                {t("clear")}
              </button>
            )}
          </div>

          {/* Tags Trigger Chip & Popover */}
          <div style={{ position: "relative", marginLeft: "auto" }}>
            <button
              className="tick-meta-chip"
              type="button"
              onClick={() => setShowTagPicker((p) => !p)}
              style={{ padding: "3px 8px", fontSize: 11 }}
            >
              🏷️ {tags.length > 0 ? `${tags.length} tags` : "+ Tag"}
            </button>

            {showTagPicker && (
              <div
                className="dropdown"
                style={{ right: 0, top: "calc(100% + 4px)", minWidth: 200, padding: 8, zIndex: 100 }}
                onClick={(e) => e.stopPropagation()}
              >
                <div style={{ fontSize: 11, fontWeight: 700, color: "var(--text-tertiary)", marginBottom: 6 }}>CUSTOM TAGS</div>
                <div style={{ display: "flex", flexWrap: "wrap", gap: 4, marginBottom: 8 }}>
                  {allAvailableTags.map((at) => {
                    const active = tags.some((tg) => tg.tag.id === at.id);
                    return (
                      <span
                        key={at.id}
                        className="badge"
                        style={{
                          background: active ? at.color : "var(--bg-primary)",
                          color: active ? "#fff" : at.color,
                          border: `1px solid ${at.color}`,
                          cursor: "pointer",
                          fontSize: 11,
                          padding: "2px 8px",
                          borderRadius: 4,
                          fontWeight: 600,
                        }}
                        onClick={() => toggleTag(at)}
                      >
                        #{at.name} {active ? "✓" : ""}
                      </span>
                    );
                  })}
                </div>
                {/* Create custom tag input */}
                <div style={{ display: "flex", gap: 4 }}>
                  <input
                    className="form-input"
                    placeholder="New tag..."
                    value={newTagName}
                    onChange={(e) => setNewTagName(e.target.value)}
                    onKeyDown={(e) => { if (e.key === "Enter") addCustomTag(); }}
                    style={{ fontSize: 11, height: 26, padding: "2px 6px" }}
                  />
                  <button className="btn btn-primary btn-sm" type="button" onClick={addCustomTag} style={{ fontSize: 11, padding: "2px 8px" }}>
                    +
                  </button>
                </div>
              </div>
            )}
          </div>
        </div>

        {/* Selected Tags Display */}
        {tags.length > 0 && (
          <div style={{ display: "flex", flexWrap: "wrap", gap: 6, paddingBottom: 4 }}>
            {tags.map((tg) => (
              <span
                key={tg.tag.id}
                className="badge"
                style={{
                  background: tg.tag.color + "22",
                  color: tg.tag.color,
                  fontSize: 11,
                  padding: "2px 8px",
                  borderRadius: 4,
                  fontWeight: 600,
                  display: "inline-flex",
                  alignItems: "center",
                  gap: 4,
                }}
              >
                #{tg.tag.name}
                <button
                  type="button"
                  onClick={() => toggleTag(tg.tag as MockTag)}
                  style={{ background: "none", border: "none", color: "inherit", cursor: "pointer", padding: 0, fontSize: 10, opacity: 0.7 }}
                >
                  ✕
                </button>
              </span>
            ))}
          </div>
        )}

        {/* The Wide Adaptive Markdown Note Editor */}
        <div style={{ flex: 1, display: "flex", flexDirection: "column", minHeight: 0 }}>
          <MarkdownNoteEditor
            value={note}
            onChange={handleNoteChange}
            onSave={() => save(task.id, { note })}
          />
        </div>

        {/* Sub-tasks Section (Collapsible Accordion at Bottom) */}
        <div style={{ borderTop: "1px solid var(--border)", paddingTop: 10 }}>
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-between",
              cursor: "pointer",
              userSelect: "none",
              marginBottom: showSubtasks ? 8 : 0,
            }}
            onClick={() => setShowSubtasks((p) => !p)}
          >
            <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
              <svg
                width="12"
                height="12"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2.5"
                style={{ transform: showSubtasks ? "rotate(90deg)" : "rotate(0deg)", transition: "transform 0.15s" }}
              >
                <polyline points="9 18 15 12 9 6" />
              </svg>
              <span className="detail-section-label" style={{ marginBottom: 0 }}>{t("subtasks")}</span>
            </div>

            {subtasks.length > 0 && (
              <span style={{ fontSize: 11, color: "var(--text-tertiary)", fontWeight: 600 }}>
                {completedCount}/{subtasks.length}
              </span>
            )}
          </div>

          {showSubtasks && (
            <div>
              {/* Progress bar */}
              {subtasks.length > 0 && (
                <div style={{ height: 3, background: "var(--bg-hover)", borderRadius: 2, marginBottom: 10, overflow: "hidden" }}>
                  <div
                    style={{
                      height: "100%",
                      width: `${(completedCount / subtasks.length) * 100}%`,
                      background: "var(--accent)",
                      borderRadius: 2,
                      transition: "width var(--dur-normal) var(--ease-out)",
                    }}
                  />
                </div>
              )}

              {/* Sub-tasks list */}
              <div style={{ display: "flex", flexDirection: "column", gap: 4, maxHeight: 180, overflowY: "auto" }}>
                {subtasks.map((sub) => (
                  <div
                    key={sub.id}
                    style={{
                      display: "flex",
                      alignItems: "center",
                      gap: 8,
                      padding: "4px 8px",
                      borderRadius: "var(--radius-sm)",
                      background: "var(--bg-secondary)",
                    }}
                  >
                    <button
                      className={`task-check-btn${sub.completed ? " checked" : ""}`}
                      style={{ width: 15, height: 15, flexShrink: 0 }}
                      onClick={() => toggleSubtask(sub)}
                      aria-label="Toggle subtask"
                      type="button"
                    />
                    <span
                      style={{
                        flex: 1,
                        fontSize: 12.5,
                        textDecoration: sub.completed ? "line-through" : "none",
                        color: sub.completed ? "var(--text-tertiary)" : "var(--text-primary)",
                      }}
                    >
                      {sub.title}
                    </span>
                    <button
                      className="icon-btn"
                      style={{ width: 20, height: 20, opacity: 0.4 }}
                      onClick={() => deleteSubtask(sub.id)}
                      title="Delete subtask"
                      type="button"
                    >
                      ✕
                    </button>
                  </div>
                ))}

                {/* Add Subtask Input */}
                <div style={{ display: "flex", gap: 6, marginTop: 4 }}>
                  <input
                    className="form-input"
                    id="add-subtask-input"
                    placeholder={t("addSubtaskPlaceholder")}
                    style={{ flex: 1, background: "none", fontSize: 12.5, color: "var(--text-primary)" }}
                    value={newSubtitle}
                    onChange={(e) => setNewSubtitle(e.target.value)}
                    onKeyDown={(e) => {
                      if (e.key === "Enter") {
                        e.preventDefault();
                        addSubtask();
                      }
                    }}
                  />
                  {newSubtitle.trim() && (
                    <button className="btn btn-primary btn-sm" id="add-subtask-btn" onClick={addSubtask} type="button">
                      {t("add")}
                    </button>
                  )}
                </div>
              </div>
            </div>
          )}
        </div>

        {/* Footer Info: Project Badge, Created & Edited Timestamps */}
        <div style={{ fontSize: 11, color: "var(--text-tertiary)", display: "flex", justifyContent: "space-between", alignItems: "center", borderTop: "1px solid var(--border)", paddingTop: 8, flexWrap: "wrap", gap: 6 }}>
          {listName && (
            <span className="tick-meta-chip" style={{ fontSize: 11, padding: "2px 8px" }}>
              📁 {listName}
            </span>
          )}
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginLeft: "auto", flexWrap: "wrap" }}>
            <span>
              {t("created")}:{" "}
              {new Date(task.createdAt).toLocaleDateString(lang === "ko" ? "ko-KR" : lang === "ja" ? "ja-JP" : "en-US", {
                year: "numeric",
                month: "short",
                day: "numeric",
              })}
            </span>
            {task.updatedAt && (
              <span>
                {t("edited")}:{" "}
                {new Date(task.updatedAt).toLocaleTimeString(lang === "ko" ? "ko-KR" : lang === "ja" ? "ja-JP" : "en-US", {
                  month: "short",
                  day: "numeric",
                  hour: "2-digit",
                  minute: "2-digit",
                })}
              </span>
            )}
          </div>
        </div>
      </div>
    </aside>
  );
}