"use client";
import React, { useState, useEffect, useRef, useCallback } from "react";
import { useI18n } from "@/lib/i18n";
import { ContextMenu, MenuItem } from "@/components/ui/ContextMenu";

export interface Task {
  id: string;
  listId: string;
  parentId: string | null;
  title: string;
  note: string | null;
  completed: boolean;
  completedAt: string | null;
  dueDate: string | null;
  priority: number;
  sortOrder: number;
  createdAt: string;
  updatedAt: string;
  children: Task[];
  tags: { tag: { id: string; name: string; color: string } }[];
}

export interface List { id: string; name: string; color: string; icon: string }
export interface User { id: string; name?: string | null; email?: string | null }

const PRIORITY_COLORS = ["transparent", "var(--priority-low)", "var(--priority-medium)", "var(--priority-high)"];

function isOverdue(d: string | null) {
  if (!d) return false;
  return new Date(d) < new Date() && new Date(d).toDateString() !== new Date().toDateString();
}

interface TaskItemProps {
  task: Task;
  isSelected: boolean;
  onSelect: (t: Task) => void;
  onToggle: (id: string, completed: boolean) => void;
  onUpdateTitle: (id: string, title: string) => void;
  onAddSubtask: (title: string, parentId: string) => void;
  onContextMenu: (x: number, y: number, task: Task) => void;
  onDeleteTask?: (id: string) => void;
}

function TaskItem({
  task,
  isSelected,
  onSelect,
  onToggle,
  onUpdateTitle,
  onAddSubtask,
  onContextMenu,
}: TaskItemProps) {
  const { t, lang } = useI18n();
  const [expanded, setExpanded] = useState(true);
  const [editingTitle, setEditingTitle] = useState(false);
  const [tempTitle, setTempTitle] = useState(task.title);

  const [addingSubtask, setAddingSubtask] = useState(false);
  const [subtaskInput, setSubtaskInput] = useState("");

  const editInputRef = useRef<HTMLInputElement>(null);
  const subInputRef = useRef<HTMLInputElement>(null);

  const completedChildren = task.children?.filter((c) => c.completed).length || 0;

  useEffect(() => {
    setTempTitle(task.title);
  }, [task.title]);

  useEffect(() => {
    if (editingTitle) {
      editInputRef.current?.focus();
      editInputRef.current?.select();
    }
  }, [editingTitle]);

  useEffect(() => {
    if (addingSubtask) {
      subInputRef.current?.focus();
    }
  }, [addingSubtask]);

  const formatDate = (d: string | null) => {
    if (!d) return null;
    const date = new Date(d);
    const now = new Date();
    const isToday = date.toDateString() === now.toDateString();
    const isTomorrow = date.toDateString() === new Date(now.getTime() + 86400000).toDateString();
    if (isToday) return t("today");
    if (isTomorrow) return t("tomorrow");
    return date.toLocaleDateString(lang === "ko" ? "ko-KR" : lang === "ja" ? "ja-JP" : "en-US", { month: "short", day: "numeric" });
  };

  const priorityLabels = [t("priorityNone"), t("priorityLow"), t("priorityMedium"), t("priorityHigh")];

  const handleSaveTitle = () => {
    const trimmed = tempTitle.trim();
    if (trimmed && trimmed !== task.title) {
      onUpdateTitle(task.id, trimmed);
    } else {
      setTempTitle(task.title);
    }
    setEditingTitle(false);
  };

  const handleCreateSubtask = (e: React.FormEvent) => {
    e.preventDefault();
    const trimmed = subtaskInput.trim();
    if (trimmed) {
      onAddSubtask(trimmed, task.id);
      setSubtaskInput("");
      setAddingSubtask(false);
      setExpanded(true);
    }
  };

  return (
    <div style={{ position: "relative" }}>
      <div
        className={`task-item${task.completed ? " completed" : ""}${isSelected ? " selected" : ""}`}
        onClick={() => onSelect(task)}
        onContextMenu={(e) => {
          e.preventDefault();
          onContextMenu(e.clientX, e.clientY, task);
        }}
        id={`task-${task.id}`}
        style={{ group: "item" } as React.CSSProperties}
      >
        <button
          className={`task-check-btn${task.completed ? " checked" : ""}`}
          onClick={(e) => {
            e.stopPropagation();
            onToggle(task.id, !task.completed);
          }}
          aria-label={task.completed ? "Mark incomplete" : "Mark complete"}
          type="button"
        />

        <div className="task-body">
          {editingTitle ? (
            <input
              ref={editInputRef}
              className="form-input"
              value={tempTitle}
              onChange={(e) => setTempTitle(e.target.value)}
              onBlur={handleSaveTitle}
              onKeyDown={(e) => {
                if (e.key === "Enter") handleSaveTitle();
                if (e.key === "Escape") {
                  setTempTitle(task.title);
                  setEditingTitle(false);
                }
              }}
              onClick={(e) => e.stopPropagation()}
              style={{ padding: "2px 6px", fontSize: 14, fontWeight: 500, height: 26, width: "100%" }}
            />
          ) : (
            <div
              className="task-title"
              onDoubleClick={(e) => {
                e.stopPropagation();
                setEditingTitle(true);
              }}
              title="Double click to edit"
              style={{ cursor: "text" }}
            >
              {task.title}
            </div>
          )}

          <div className="task-meta">
            {task.priority > 0 && (
              <div
                className="task-priority-dot"
                style={{ background: PRIORITY_COLORS[task.priority] }}
                title={priorityLabels[task.priority]}
              />
            )}
            {task.dueDate && (
              <span className={`task-due${isOverdue(task.dueDate) && !task.completed ? " overdue" : ""}`}>
                <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                  <rect x="3" y="4" width="18" height="18" rx="2" /><line x1="16" y1="2" x2="16" y2="6" /><line x1="8" y1="2" x2="8" y2="6" /><line x1="3" y1="10" x2="21" y2="10" />
                </svg>
                {formatDate(task.dueDate)}
              </span>
            )}
            {task.children && task.children.length > 0 && (
              <span
                className="task-sub-count"
                onClick={(e) => {
                  e.stopPropagation();
                  setExpanded((p) => !p);
                }}
                title="Toggle subtasks"
                style={{ cursor: "pointer" }}
              >
                <svg
                  width="10"
                  height="10"
                  viewBox="0 0 24 24"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                  style={{ transform: expanded ? "rotate(90deg)" : "rotate(0deg)", transition: "transform 0.15s" }}
                >
                  <polyline points="9 18 15 12 9 6" />
                </svg>
                {completedChildren}/{task.children.length}
              </span>
            )}

            {/* Quick Add Subtask Button */}
            <button
              className="badge badge-neutral"
              style={{ cursor: "pointer", fontSize: 10, padding: "1px 6px", border: "1px solid var(--border)", background: "transparent" }}
              onClick={(e) => {
                e.stopPropagation();
                setAddingSubtask(true);
                setExpanded(true);
              }}
              title="Add subtask"
              type="button"
            >
              + {t("subtasks")}
            </button>
          </div>

          {task.note && !task.completed && (
            <div className="task-note-preview">{task.note.replace(/[#*`]/g, "").slice(0, 80)}</div>
          )}
        </div>

        {/* Quick Edit icon on hover */}
        <button
          className="icon-btn"
          style={{ width: 22, height: 22, opacity: 0.4, flexShrink: 0 }}
          onClick={(e) => {
            e.stopPropagation();
            setEditingTitle(true);
          }}
          title="Edit title"
          type="button"
        >
          <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M12 20h9" /><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z" />
          </svg>
        </button>
      </div>

      {/* Sub-tasks List */}
      {((task.children && task.children.length > 0) || addingSubtask) && expanded && (
        <div className="subtask-list" style={{ paddingLeft: 38 }}>
          {task.children?.map((child) => (
            <SubTaskItem
              key={child.id}
              child={child}
              onToggle={onToggle}
              onSelect={onSelect}
              onUpdateTitle={onUpdateTitle}
            />
          ))}

          {/* Inline Add Subtask input */}
          {addingSubtask && (
            <form onSubmit={handleCreateSubtask} style={{ display: "flex", gap: 6, padding: "4px 0" }}>
              <span style={{ color: "var(--accent)", fontSize: 14, lineHeight: "24px" }}>↳</span>
              <input
                ref={subInputRef}
                className="form-input"
                placeholder={t("addSubtaskPlaceholder")}
                value={subtaskInput}
                onChange={(e) => setSubtaskInput(e.target.value)}
                onBlur={() => {
                  if (!subtaskInput.trim()) setAddingSubtask(false);
                }}
                onKeyDown={(e) => {
                  if (e.key === "Escape") setAddingSubtask(false);
                }}
                style={{ height: 26, fontSize: 12.5, padding: "2px 8px", flex: 1 }}
              />
              <button className="btn btn-primary btn-sm" type="submit" style={{ padding: "2px 8px", fontSize: 11 }}>
                {t("add")}
              </button>
            </form>
          )}
        </div>
      )}
    </div>
  );
}

// Sub-task Item with Inline Rename
function SubTaskItem({
  child,
  onToggle,
  onSelect,
  onUpdateTitle,
}: {
  child: Task;
  onToggle: (id: string, completed: boolean) => void;
  onSelect: (t: Task) => void;
  onUpdateTitle: (id: string, title: string) => void;
}) {
  const [editing, setEditing] = useState(false);
  const [temp, setTemp] = useState(child.title);
  const ref = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (editing) {
      ref.current?.focus();
      ref.current?.select();
    }
  }, [editing]);

  const handleSave = () => {
    const trimmed = temp.trim();
    if (trimmed && trimmed !== child.title) {
      onUpdateTitle(child.id, trimmed);
    } else {
      setTemp(child.title);
    }
    setEditing(false);
  };

  return (
    <div
      className={`subtask-item${child.completed ? " completed" : ""}`}
      onClick={() => onSelect(child)}
      id={`subtask-${child.id}`}
    >
      <button
        className={`subtask-check-btn${child.completed ? " checked" : ""}`}
        onClick={(e) => {
          e.stopPropagation();
          onToggle(child.id, !child.completed);
        }}
        aria-label={child.completed ? "Mark incomplete" : "Mark complete"}
        type="button"
      />
      {editing ? (
        <input
          ref={ref}
          className="form-input"
          value={temp}
          onChange={(e) => setTemp(e.target.value)}
          onBlur={handleSave}
          onKeyDown={(e) => {
            if (e.key === "Enter") handleSave();
            if (e.key === "Escape") {
              setTemp(child.title);
              setEditing(false);
            }
          }}
          onClick={(e) => e.stopPropagation()}
          style={{ padding: "1px 6px", fontSize: 12.5, height: 22, flex: 1 }}
        />
      ) : (
        <span
          className="subtask-title"
          onDoubleClick={(e) => {
            e.stopPropagation();
            setEditing(true);
          }}
          title="Double click to edit"
          style={{ cursor: "text" }}
        >
          {child.title}
        </span>
      )}
    </div>
  );
}

interface Props {
  user: User;
  listId: string | null;
  lists: List[];
  tasks: Task[];
  setTasks: React.Dispatch<React.SetStateAction<Task[]>>;
  selectedTaskId: string | null;
  onTaskSelect: (t: Task | null) => void;
  showCompleted: boolean;
  onToggleCompleted: () => void;
  onMenuOpen: () => void;
  onRefresh: () => void;
  isDemo?: boolean;
  onDemoAddTask?: (title: string, listId: string, parentId?: string | null) => void;
  onDemoToggleTask?: (id: string, completed: boolean) => void;
  onUpdateTaskTitle?: (id: string, title: string) => void;
  onUpdateListName?: (id: string, name: string) => void;
}

export function TaskList({
  user,
  listId,
  lists,
  tasks,
  setTasks,
  selectedTaskId,
  onTaskSelect,
  showCompleted,
  onToggleCompleted,
  onMenuOpen,
  onRefresh,
  isDemo = false,
  onDemoAddTask,
  onDemoToggleTask,
  onUpdateTaskTitle,
  onUpdateListName,
}: Props) {
  const { t } = useI18n();
  const [newTaskTitle, setNewTaskTitle] = useState("");
  const [loading, setLoading] = useState(false);
  const [editingHeader, setEditingHeader] = useState(false);
  const [headerTitle, setHeaderTitle] = useState("");
  const [contextMenu, setContextMenu] = useState<{ x: number; y: number; task: Task } | null>(null);

  const inputRef = useRef<HTMLInputElement>(null);
  const headerInputRef = useRef<HTMLInputElement>(null);
  const currentList = lists.find((l) => l.id === listId);

  useEffect(() => {
    if (currentList) setHeaderTitle(currentList.name);
  }, [currentList]);

  useEffect(() => {
    if (editingHeader) {
      headerInputRef.current?.focus();
      headerInputRef.current?.select();
    }
  }, [editingHeader]);

  const fetchTasks = useCallback(async () => {
    if (!listId || isDemo) return;
    setLoading(true);
    try {
      const res = await fetch(`/api/tasks?listId=${listId}&showCompleted=${showCompleted}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      setTasks(Array.isArray(data) ? data : []);
    } catch (err) {
      console.error("[TaskList] fetchTasks failed", err);
    } finally {
      setLoading(false);
    }
  }, [listId, showCompleted, isDemo, setTasks]);

  useEffect(() => {
    fetchTasks();
  }, [fetchTasks]);

  useEffect(() => {
    const handler = () => inputRef.current?.focus();
    document.addEventListener("checkflow:addTask", handler);
    return () => document.removeEventListener("checkflow:addTask", handler);
  }, []);

  const handleToggle = useCallback(
    async (id: string, completed: boolean) => {
      if (isDemo) {
        if (onDemoToggleTask) onDemoToggleTask(id, completed);
        return;
      }

      try {
        const res = await fetch(`/api/tasks/${id}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ completed }),
        });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const updated = await res.json();
        setTasks((prev) =>
          prev
            .map((t) => {
              if (t.id === id) return { ...t, completed, completedAt: updated.completedAt };
              if (t.children && t.children.some((c) => c.id === id)) {
                return {
                  ...t,
                  children: t.children.map((c) => (c.id === id ? { ...c, completed } : c)),
                };
              }
              return t;
            })
            .filter((t) => showCompleted || !t.completed)
        );
        onRefresh();
      } catch (err) {
        console.error("[TaskList] handleToggle failed", err);
      }
    },
    [isDemo, onDemoToggleTask, showCompleted, onRefresh, setTasks]
  );

  const handleAddTask = async (e: React.FormEvent) => {
    e.preventDefault();
    const title = newTaskTitle.trim();
    if (!title || !listId) return;

    if (isDemo) {
      if (onDemoAddTask) onDemoAddTask(title, listId, null);
      setNewTaskTitle("");
      return;
    }

    try {
      const res = await fetch("/api/tasks", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ title, listId }),
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const task = await res.json();
      setTasks((prev) => [...prev, task]);
      setNewTaskTitle("");
      onRefresh();
    } catch (err) {
      console.error("[TaskList] handleAddTask failed", err);
    }
  };

  const handleAddSubtaskInline = async (title: string, parentId: string) => {
    if (!listId) return;
    if (isDemo) {
      if (onDemoAddTask) onDemoAddTask(title, listId, parentId);
      return;
    }

    try {
      const res = await fetch("/api/tasks", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ title, listId, parentId }),
      });
      if (res.ok) {
        const sub = await res.json();
        setTasks((prev) =>
          prev.map((t) => (t.id === parentId ? { ...t, children: [...(t.children || []), sub] } : t))
        );
        onRefresh();
      }
    } catch (err) {
      console.error("Failed to add subtask inline", err);
    }
  };

  const handleSaveHeaderTitle = () => {
    const trimmed = headerTitle.trim();
    if (trimmed && listId && onUpdateListName && trimmed !== currentList?.name) {
      onUpdateListName(listId, trimmed);
    } else if (currentList) {
      setHeaderTitle(currentList.name);
    }
    setEditingHeader(false);
  };

  if (!listId) {
    return (
      <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", height: "100%", color: "var(--text-tertiary)" }}>
        <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" style={{ opacity: 0.3, marginBottom: 12 }}>
          <path d="M9 11l3 3L22 4" /><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
        </svg>
        <p>{t("selectListToStart")}</p>
      </div>
    );
  }

  const incompleteTasks = tasks.filter((t) => !t.completed);
  const completedTasks = tasks.filter((t) => t.completed);

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
      {/* Header */}
      <div className="main-header">
        <button className="icon-btn mobile-only" id="menu-btn" onClick={onMenuOpen} aria-label="Menu">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <line x1="3" y1="6" x2="21" y2="6" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="18" x2="21" y2="18" />
          </svg>
        </button>

        {/* Inline Editable List Title */}
        {editingHeader ? (
          <input
            ref={headerInputRef}
            id="header-rename-input"
            className="form-input"
            value={headerTitle}
            onChange={(e) => setHeaderTitle(e.target.value)}
            onBlur={handleSaveHeaderTitle}
            onKeyDown={(e) => {
              if (e.key === "Enter") handleSaveHeaderTitle();
              if (e.key === "Escape") {
                if (currentList) setHeaderTitle(currentList.name);
                setEditingHeader(false);
              }
            }}
            onClick={(e) => e.stopPropagation()}
            autoFocus
            style={{ fontSize: 18, fontWeight: 700, height: 36, padding: "2px 10px", maxWidth: 360 }}
          />
        ) : (
          <div
            className="main-header-title"
            id="main-header-title"
            style={{
              color: currentList?.color,
              cursor: "pointer",
              display: "flex",
              alignItems: "center",
              gap: 8,
              padding: "4px 8px",
              borderRadius: "var(--radius-sm)",
              transition: "background var(--dur-fast)",
            }}
            onClick={(e) => {
              e.stopPropagation();
              setEditingHeader(true);
            }}
            title="Click to rename list"
          >
            <span>{currentList?.name || t("tasks")}</span>
            <span style={{ fontSize: 13, opacity: 0.5 }}>✏️</span>
          </div>
        )}

        <div className="main-header-actions">
          <button
            id="toggle-completed-btn"
            className="btn btn-ghost btn-sm"
            onClick={onToggleCompleted}
            title={showCompleted ? t("hideDone") : t("showDone")}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
              <polyline points="20 6 9 17 4 12" />
            </svg>
            {showCompleted ? t("hideDone") : t("showDone")}
          </button>
        </div>
      </div>

      {/* Task list */}
      <div className="task-list-container">
        {loading && (
          <div style={{ padding: "20px", textAlign: "center", color: "var(--text-tertiary)" }}>{t("loading")}</div>
        )}
        {!loading && incompleteTasks.length === 0 && completedTasks.length === 0 && (
          <div className="task-list-empty">
            <svg width="56" height="56" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
              <path d="M9 11l3 3L22 4" /><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
            </svg>
            <p>{t("noTasksYet")}</p>
          </div>
        )}
        {incompleteTasks.map((task) => (
          <TaskItem
            key={task.id}
            task={task}
            isSelected={selectedTaskId === task.id}
            onSelect={onTaskSelect}
            onToggle={handleToggle}
            onUpdateTitle={(id, title) => onUpdateTaskTitle && onUpdateTaskTitle(id, title)}
            onAddSubtask={handleAddSubtaskInline}
            onContextMenu={(x, y, tItem) => setContextMenu({ x, y, task: tItem })}
          />
        ))}
        {showCompleted && completedTasks.length > 0 && (
          <div>
            <div
              style={{
                padding: "12px 20px 4px",
                fontSize: 11,
                fontWeight: 600,
                color: "var(--text-tertiary)",
                textTransform: "uppercase",
                letterSpacing: "0.5px",
              }}
            >
              {t("completedSection")} ({completedTasks.length})
            </div>
            {completedTasks.map((task) => (
              <TaskItem
                key={task.id}
                task={task}
                isSelected={selectedTaskId === task.id}
                onSelect={onTaskSelect}
                onToggle={handleToggle}
                onUpdateTitle={(id, title) => onUpdateTaskTitle && onUpdateTaskTitle(id, title)}
                onAddSubtask={handleAddSubtaskInline}
                onContextMenu={(x, y, tItem) => setContextMenu({ x, y, task: tItem })}
              />
            ))}
          </div>
        )}
      </div>

      {/* Context Menu on Task */}
      {contextMenu && (
        <ContextMenu
          x={contextMenu.x}
          y={contextMenu.y}
          items={[
            {
              label: contextMenu.task.completed ? t("showDone") : t("completedSection"),
              icon: contextMenu.task.completed ? "↩️" : "✅",
              onClick: () => handleToggle(contextMenu.task.id, !contextMenu.task.completed),
            },
            {
              label: t("taskTitlePlaceholder"),
              icon: "✏️",
              onClick: () => onTaskSelect(contextMenu.task),
            },
            {
              label: t("subtasks"),
              icon: "↳",
              onClick: () => {
                onTaskSelect(contextMenu.task);
              },
            },
            { divider: true, label: "" },
            {
              label: t("deleteTaskConfirm").split("?")[0],
              icon: "🗑️",
              danger: true,
              onClick: async () => {
                if (isDemo) {
                  setTasks((prev) => prev.filter((t) => t.id !== contextMenu.task.id));
                } else {
                  await fetch(`/api/tasks/${contextMenu.task.id}`, { method: "DELETE" });
                  onRefresh();
                }
              },
            },
          ]}
          onClose={() => setContextMenu(null)}
        />
      )}

      {/* Add task bar */}
      <div className="add-task-bar">
        <button className="task-check-btn" style={{ opacity: 0.4, flexShrink: 0 }} aria-hidden="true" />
        <form onSubmit={handleAddTask} style={{ flex: 1, display: "flex", gap: 8 }}>
          <input
            ref={inputRef}
            id="add-task-input"
            className="add-task-input"
            placeholder={t("addTaskPlaceholder")}
            value={newTaskTitle}
            onChange={(e) => setNewTaskTitle(e.target.value)}
          />
          {newTaskTitle.trim() && (
            <button type="submit" className="btn btn-primary btn-sm" id="add-task-btn">
              {t("add")}
            </button>
          )}
        </form>
      </div>
    </div>
  );
}