"use client";
import React, { useState, useEffect, useRef, useCallback } from "react";
import { useRouter } from "next/navigation";
import { signOut } from "next-auth/react";
import { useI18n } from "@/lib/i18n";
import { useTheme } from "@/app/providers";
import { LanguageSelector } from "@/components/ui/LanguageSelector";
import { ContextMenu, MenuItem } from "@/components/ui/ContextMenu";
import { SettingsModal } from "@/components/settings/SettingsModal";
import { getCustomTags, MockTag, getAllTrashTasks, getDemoStore } from "@/lib/mockData";

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

const LIST_COLORS = ["#5B8DEF", "#E05252", "#3DAD84", "#E8931A", "#8B6CF7", "#E4609B", "#0ABAD1", "#F17A3B", "#6875F5", "#14B8A6"];

interface SidebarProps {
  user: User;
  lists: List[];
  setLists: React.Dispatch<React.SetStateAction<List[]>>;
  selectedListId: string | null;
  onListSelect: (id: string) => void;
  selectedTag: string | null;
  onTagSelect: (tag: string | null) => void;
  isTrashActive: boolean;
  onTrashSelect: () => void;
  mobileOpen: boolean;
  onClose: () => void;
  isDemo?: boolean;
  onDemoCreateList?: (name: string, color: string) => void;
  onDemoDeleteList?: (id: string) => void;
}

/* ===================== UNDO TOAST ===================== */
interface UndoToastState {
  message: string;
  onUndo: () => void;
  timeoutId: ReturnType<typeof setTimeout> | null;
}

export function Sidebar({
  user,
  lists,
  setLists,
  selectedListId,
  onListSelect,
  selectedTag,
  onTagSelect,
  isTrashActive,
  onTrashSelect,
  mobileOpen,
  onClose: _onClose,
  isDemo = false,
  onDemoCreateList,
  onDemoDeleteList,
}: SidebarProps) {
  const router = useRouter();
  const { t } = useI18n();
  const { theme, toggleTheme } = useTheme();

  const [showNewList, setShowNewList] = useState(false);
  const [newListName, setNewListName] = useState("");
  const [newListColor, setNewListColor] = useState(LIST_COLORS[0]);
  const [userMenuOpen, setUserMenuOpen] = useState(false);
  const [showImport, setShowImport] = useState(false);
  const [showExport, setShowExport] = useState(false);
  const [showSettings, setShowSettings] = useState(false);
  const [importListId, setImportListId] = useState("");
  const [importing, setImporting] = useState(false);
  const [importResult, setImportResult] = useState("");
  const [exportFormat, setExportFormat] = useState<"csv" | "ics">("csv");
  const [exportListId, setExportListId] = useState<string>("all");
  const [exportIncludeCompleted, setExportIncludeCompleted] = useState<boolean>(true);
  const [exporting, setExporting] = useState(false);
  const [tags, setTags] = useState<MockTag[]>(() => (typeof window !== "undefined" ? getCustomTags() : []));
  const [trashCount, setTrashCount] = useState(() => {
    if (typeof window !== "undefined") {
      const store = getDemoStore();
      return getAllTrashTasks(store.tasks).length;
    }
    return 0;
  });

  // Context Menu for Lists
  const [contextMenu, setContextMenu] = useState<{ x: number; y: number; listId: string } | null>(null);

  // Undo Toast for deleted list
  const [undoToast, setUndoToast] = useState<UndoToastState | null>(null);

  // Inline rename
  const [renamingListId, setRenamingListId] = useState<string | null>(null);
  const [renameValue, setRenameValue] = useState("");

  // Search expansion
  const [searchExpanded, setSearchExpanded] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const searchInputRef = useRef<HTMLInputElement>(null);

  const inputRef = useRef<HTMLInputElement>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    setTags(getCustomTags());
    const store = getDemoStore();
    const trashed = getAllTrashTasks(store.tasks);
    setTrashCount(trashed.length);
  }, [lists]);

  useEffect(() => {
    if (!isDemo) {
      fetch("/api/lists")
        .then((r) => (r.ok ? r.json() : []))
        .then((data) => {
          if (Array.isArray(data)) {
            setLists(data);
            if (!selectedListId && data.length > 0) onListSelect(data[0].id);
          }
        })
        .catch((err) => console.error("Failed to load lists", err));
    }
  }, [isDemo, onListSelect, selectedListId, setLists]);

  useEffect(() => {
    if (showNewList) setTimeout(() => inputRef.current?.focus(), 50);
  }, [showNewList]);

  useEffect(() => {
    if (searchExpanded) {
      setTimeout(() => searchInputRef.current?.focus(), 60);
    }
  }, [searchExpanded]);

  // Dismiss undo toast on unmount
  useEffect(() => {
    return () => {
      if (undoToast?.timeoutId) clearTimeout(undoToast.timeoutId);
    };
  }, [undoToast]);

  const showUndoToast = useCallback((message: string, onUndo: () => void) => {
    if (undoToast?.timeoutId) clearTimeout(undoToast.timeoutId);
    const tid = setTimeout(() => setUndoToast(null), 5000);
    setUndoToast({ message, onUndo, timeoutId: tid });
  }, [undoToast]);

  const createList = async () => {
    const name = newListName.trim();
    if (!name) return;
    if (isDemo) {
      if (onDemoCreateList) onDemoCreateList(name, newListColor);
      setNewListName("");
      setShowNewList(false);
      return;
    }
    try {
      const res = await fetch("/api/lists", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name, color: newListColor }),
      });
      if (res.ok) {
        const list = await res.json();
        setLists((prev) => [...prev, list]);
        setNewListName("");
        setShowNewList(false);
        onListSelect(list.id);
      }
    } catch (err) {
      console.error("Failed to create list", err);
    }
  };

  const deleteList = async (id: string) => {
    // Store list for undo
    const listToDelete = lists.find((l) => l.id === id);
    if (!listToDelete) return;

    // Optimistic: remove from UI immediately
    setLists((prev) => {
      const updated = prev.filter((l) => l.id !== id);
      if (selectedListId === id && updated.length > 0) onListSelect(updated[0].id);
      return updated;
    });

    if (isDemo) {
      if (onDemoDeleteList) onDemoDeleteList(id);
      showUndoToast(t("listDeleted"), () => {
        // Undo: re-add the list (demo mode — restore optimistically)
        setLists((prev) => {
          if (prev.find((l) => l.id === id)) return prev;
          return [...prev, listToDelete].sort((a, b) => a.name.localeCompare(b.name));
        });
        onListSelect(id);
      });
      return;
    }

    try {
      await fetch(`/api/lists/${id}`, { method: "DELETE" });
    } catch (err) {
      console.error("Failed to delete list", err);
      // Rollback
      setLists((prev) => [...prev, listToDelete]);
    }
    showUndoToast(t("listDeleted"), () => {
      // For API mode, re-fetch (simplest undo simulation)
      fetch("/api/lists")
        .then((r) => r.ok ? r.json() : [])
        .then((data) => { if (Array.isArray(data)) setLists(data); })
        .catch(() => {});
    });
  };

  const renameList = async (id: string, newName: string) => {
    const trimmed = newName.trim();
    if (!trimmed) return;
    setLists((prev) => prev.map((l) => l.id === id ? { ...l, name: trimmed } : l));
    setRenamingListId(null);
    if (!isDemo) {
      try {
        await fetch(`/api/lists/${id}`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ name: trimmed }),
        });
      } catch (err) {
        console.error("Failed to rename list", err);
      }
    }
  };

  const handleExport = () => {
    setExporting(true);
    const timestamp = new Date().toISOString().split("T")[0];

    if (isDemo) {
      try {
        const store = getDemoStore();
        let targetTasks = store.tasks.filter((t) => !t.deletedAt && !t.parentId);
        if (exportListId !== "all") {
          targetTasks = targetTasks.filter((t) => t.listId === exportListId);
        }
        if (!exportIncludeCompleted) {
          targetTasks = targetTasks.filter((t) => !t.completed);
        }

        let content = "";
        let mimeType = "text/csv;charset=utf-8;";
        let filename = `checkflow-demo-export-${timestamp}.csv`;

        if (exportFormat === "ics") {
          mimeType = "text/calendar;charset=utf-8;";
          filename = `checkflow-demo-export-${timestamp}.ics`;
          const priorityMap: Record<number, number> = { 0: 0, 1: 9, 2: 5, 3: 1 };
          const now = new Date().toISOString().replace(/[-:]/g, "").split(".")[0] + "Z";
          const vtodos = targetTasks.map((t) => {
            const listObj = store.lists.find((l) => l.id === t.listId);
            const lines = [
              "BEGIN:VTODO",
              `UID:${t.id}@checkflow`,
              `DTSTAMP:${now}`,
              `CREATED:${t.createdAt ? new Date(t.createdAt).toISOString().replace(/[-:]/g, "").split(".")[0] + "Z" : now}`,
              `SUMMARY:${t.title.replace(/\n/g, "\\n")}`,
              `STATUS:${t.completed ? "COMPLETED" : "NEEDS-ACTION"}`,
              `PRIORITY:${priorityMap[t.priority] ?? 0}`,
            ];
            if (listObj?.name) lines.push(`CATEGORIES:${listObj.name.replace(/\n/g, "\\n")}`);
            if (t.note) lines.push(`DESCRIPTION:${t.note.replace(/\n/g, "\\n")}`);
            if (t.dueDate) lines.push(`DUE:${new Date(t.dueDate).toISOString().replace(/[-:]/g, "").split(".")[0] + "Z"}`);
            if (t.completedAt) lines.push(`COMPLETED:${new Date(t.completedAt).toISOString().replace(/[-:]/g, "").split(".")[0] + "Z"}`);
            lines.push("END:VTODO");
            return lines.join("\r\n");
          });

          content = [
            "BEGIN:VCALENDAR",
            "VERSION:2.0",
            "PRODID:-//CheckFlow//Demo Tasks Export//EN",
            "CALSCALE:GREGORIAN",
            "METHOD:PUBLISH",
            ...vtodos,
            "END:VCALENDAR",
          ].join("\r\n");
        } else {
          // CSV Export
          const escapeCsv = (val: string | null | undefined) => {
            if (!val) return '""';
            const s = String(val).replace(/"/g, '""');
            return `"${s}"`;
          };
          const priorityLabels: Record<number, string> = { 0: "None", 1: "Low", 2: "Medium", 3: "High" };
          const headers = [
            "Folder Name",
            "List Name",
            "Title",
            "Tags",
            "Content",
            "Is Check list",
            "Start Date",
            "Due Date",
            "Reminder",
            "Repeat",
            "Priority",
            "Status",
            "Created Time",
            "Completed Time",
            "Order",
            "Timezone",
          ];
          const rows = [headers.map((h) => `"${h}"`).join(",")];
          targetTasks.forEach((t, i) => {
            const listObj = store.lists.find((l) => l.id === t.listId);
            rows.push([
              escapeCsv(""),
              escapeCsv(listObj?.name || "Inbox"),
              escapeCsv(t.title),
              escapeCsv(""),
              escapeCsv(t.note || ""),
              escapeCsv("0"),
              escapeCsv(""),
              escapeCsv(t.dueDate ? new Date(t.dueDate).toISOString() : ""),
              escapeCsv(""),
              escapeCsv(""),
              escapeCsv(priorityLabels[t.priority] || "None"),
              escapeCsv(t.completed ? "Completed" : "Normal"),
              escapeCsv(t.createdAt ? new Date(t.createdAt).toISOString() : new Date().toISOString()),
              escapeCsv(t.completedAt ? new Date(t.completedAt).toISOString() : ""),
              escapeCsv(String(i)),
              escapeCsv(Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC"),
            ].join(","));
          });
          content = "\uFEFF" + rows.join("\r\n");
        }

        const blob = new Blob([content], { type: mimeType });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        setShowExport(false);
      } catch (e) {
        console.error("Demo export error", e);
      } finally {
        setExporting(false);
      }
      return;
    }

    // Authenticated API Export
    const url = `/api/export?format=${exportFormat}&listId=${exportListId}&includeCompleted=${exportIncludeCompleted}`;
    const a = document.createElement("a");
    a.href = url;
    a.download = `checkflow-export-${timestamp}.${exportFormat}`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    setExporting(false);
    setShowExport(false);
  };

  const handleImport = async () => {
    const file = fileRef.current?.files?.[0];
    if (!file || !importListId) return;
    if (isDemo) {
      setImportResult("✓ Demo Mode: Import simulated successfully");
      setTimeout(() => { setShowImport(false); setImportResult(""); }, 1500);
      return;
    }
    setImporting(true);
    try {
      const formData = new FormData();
      formData.append("file", file);
      formData.append("listId", importListId);
      const res = await fetch("/api/import", { method: "POST", body: formData });
      const data = await res.json().catch(() => ({}));
      if (res.ok) {
        setImportResult(`✓ Imported ${data.imported} tasks`);
        if (fileRef.current) fileRef.current.value = "";
        const listsRes = await fetch("/api/lists");
        if (listsRes.ok) {
          const updated = await listsRes.json();
          if (Array.isArray(updated)) setLists(updated);
        }
        setTimeout(() => { setShowImport(false); setImportResult(""); }, 2000);
      } else {
        setImportResult(`Error: ${data.error || "Import failed"}`);
      }
    } catch (err) {
      console.error("[Sidebar] import failed", err);
      setImportResult("Error: Network error");
    } finally {
      setImporting(false);
    }
  };

  const initials = user.name?.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2) || "?";

  // Context menu items for list (right-click)
  const getListContextMenuItems = (listId: string): MenuItem[] => [
    {
      label: t("renameList"),
      icon: "✏️",
      onClick: () => {
        const list = lists.find((l) => l.id === listId);
        if (list) {
          setRenamingListId(listId);
          setRenameValue(list.name);
        }
      },
    },
    {
      label: t("deleteList"),
      icon: "🗑️",
      danger: true,
      onClick: () => deleteList(listId),
    },
  ];

  return (
    <aside className={`sidebar${mobileOpen ? " mobile-open" : ""}`}>
      {/* Header with Logo & Controls */}
      <div className="sidebar-header" style={{ padding: "12px 12px 8px", gap: 6 }}>
        <div className="sidebar-logo">✓</div>
        <div style={{ display: "flex", flexDirection: "column", minWidth: 0, flex: 1 }}>
          <span className="sidebar-title" style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
            {t("appName")}
          </span>
          {isDemo && (
            <span style={{ fontSize: 10, color: "var(--accent)", fontWeight: 700, letterSpacing: 0.3 }}>
              {t("demoBadge")}
            </span>
          )}
        </div>

        {/* Top Controls: Hover-expand Search, Language & Theme */}
        <div style={{ display: "flex", alignItems: "center", gap: 2, flexShrink: 0 }}>
          {/* Hover-expand Search */}
          <div
            style={{
              position: "relative",
              display: "flex",
              alignItems: "center",
              transition: "all var(--dur-normal) var(--ease-out)",
            }}
            onMouseEnter={() => setSearchExpanded(true)}
            onMouseLeave={() => {
              if (!searchQuery) setSearchExpanded(false);
            }}
          >
            {searchExpanded ? (
              <div
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 6,
                  background: "var(--bg-primary)",
                  border: "1.5px solid var(--accent)",
                  borderRadius: "var(--radius-sm)",
                  padding: "3px 8px",
                  animation: "expandSearch var(--dur-normal) var(--ease-out)",
                  width: 180,
                  boxShadow: "0 0 0 3px var(--accent-light)",
                }}
              >
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" strokeWidth="2.5">
                  <circle cx="11" cy="11" r="8" /><line x1="21" y1="21" x2="16.65" y2="16.65" />
                </svg>
                <input
                  ref={searchInputRef}
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter" || e.key === "Escape") {
                      document.dispatchEvent(new CustomEvent("checkflow:openCommandPalette"));
                      setSearchExpanded(false);
                      setSearchQuery("");
                    }
                  }}
                  placeholder={t("searchPlaceholder")}
                  style={{
                    background: "transparent",
                    border: "none",
                    outline: "none",
                    fontSize: 12,
                    color: "var(--text-primary)",
                    width: "100%",
                  }}
                />
              </div>
            ) : (
              <button
                className="icon-btn"
                id="quick-search-btn"
                onClick={() => document.dispatchEvent(new CustomEvent("checkflow:openCommandPalette"))}
                title={t("searchPlaceholder")}
                style={{ width: 28, height: 28, flexShrink: 0 }}
                type="button"
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                  <circle cx="11" cy="11" r="8" /><line x1="21" y1="21" x2="16.65" y2="16.65" />
                </svg>
              </button>
            )}
          </div>

          <LanguageSelector />

          {/* Theme 3-Way Toggle Button */}
          <button
            className="icon-btn"
            id="theme-toggle"
            onClick={toggleTheme}
            title={`${t("theme")}: ${theme === "system" ? t("themeSystem") : theme === "light" ? t("themeLight") : t("themeDark")}`}
            style={{ width: 28, height: 28, flexShrink: 0 }}
            type="button"
          >
            {theme === "system" ? (
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <rect x="2" y="3" width="20" height="14" rx="2" ry="2" />
                <line x1="8" y1="21" x2="16" y2="21" /><line x1="12" y1="17" x2="12" y2="21" />
              </svg>
            ) : theme === "light" ? (
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <circle cx="12" cy="12" r="5" /><line x1="12" y1="1" x2="12" y2="3" /><line x1="12" y1="21" x2="12" y2="23" />
                <line x1="4.22" y1="4.22" x2="5.64" y2="5.64" /><line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
                <line x1="1" y1="12" x2="3" y2="12" /><line x1="21" y1="12" x2="23" y2="12" />
                <line x1="4.22" y1="19.78" x2="5.64" y2="18.36" /><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
              </svg>
            ) : (
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
              </svg>
            )}
          </button>
        </div>
      </div>

      {/* Nav List */}
      <nav className="sidebar-nav">
        {/* Lists Section */}
        <div className="sidebar-section">
          <div className="sidebar-section-label">{t("lists")}</div>
          {lists.map((list) => (
            <div
              key={list.id}
              className={`sidebar-item${!isTrashActive && !selectedTag && selectedListId === list.id ? " active" : ""}`}
              onClick={() => {
                if (renamingListId === list.id) return;
                onTagSelect(null);
                onListSelect(list.id);
              }}
              onContextMenu={(e) => {
                e.preventDefault();
                setContextMenu({ x: e.clientX, y: e.clientY, listId: list.id });
              }}
              id={`list-item-${list.id}`}
              style={{ overflow: "visible" }}
            >
              <div className="list-dot" style={{ background: list.color, flexShrink: 0 }} />

              {renamingListId === list.id ? (
                <input
                  className="form-input"
                  value={renameValue}
                  onChange={(e) => setRenameValue(e.target.value)}
                  onKeyDown={(e) => {
                    if (e.key === "Enter") renameList(list.id, renameValue);
                    if (e.key === "Escape") setRenamingListId(null);
                  }}
                  onBlur={() => renameList(list.id, renameValue)}
                  autoFocus
                  onClick={(e) => e.stopPropagation()}
                  style={{ flex: 1, fontSize: 12.5, padding: "2px 6px", height: 24 }}
                />
              ) : (
                <span className="item-label">{list.name}</span>
              )}

              <span className="item-count">{list._count?.tasks || ""}</span>
              <button
                className="icon-btn"
                style={{ width: 20, height: 20, opacity: 0, transition: "opacity var(--dur-fast)", flexShrink: 0 }}
                onMouseEnter={(e) => { (e.currentTarget as HTMLButtonElement).style.opacity = "1"; }}
                onMouseLeave={(e) => { (e.currentTarget as HTMLButtonElement).style.opacity = "0"; }}
                onClick={(e) => {
                  e.stopPropagation();
                  setContextMenu({ x: e.clientX, y: e.clientY, listId: list.id });
                }}
                title="More options"
                type="button"
              >
                <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
                  <circle cx="12" cy="5" r="1.5" /><circle cx="12" cy="12" r="1.5" /><circle cx="12" cy="19" r="1.5" />
                </svg>
              </button>
            </div>
          ))}
        </div>

        {/* Custom Tags Section */}
        {tags.length > 0 && (
          <div className="sidebar-section">
            <div className="sidebar-section-label">🏷️ {t("tags") || "Tags"}</div>
            {tags.map((tag) => (
              <div
                key={tag.id}
                className={`sidebar-item${selectedTag === tag.name ? " active" : ""}`}
                onClick={() => onTagSelect(selectedTag === tag.name ? null : tag.name)}
              >
                <span style={{ color: tag.color, fontSize: 13, fontWeight: 700 }}>#</span>
                <span className="item-label">{tag.name}</span>
              </div>
            ))}
          </div>
        )}

        {/* Trash Smart List */}
        <div className="sidebar-section">
          <div
            className={`sidebar-item${isTrashActive ? " active" : ""}`}
            id="trash-menu-btn"
            onClick={onTrashSelect}
            style={{ color: isTrashActive ? "var(--danger)" : "var(--text-secondary)" }}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ opacity: 0.7 }}>
              <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>
            <span className="item-label">{t("trash") || "Trash"}</span>
            {trashCount > 0 && <span className="item-count" style={{ color: "var(--danger)" }}>{trashCount}</span>}
          </div>
        </div>

        {/* New list form */}
        {showNewList ? (
          <div style={{ padding: "4px 10px" }}>
            <div style={{ display: "flex", flexWrap: "wrap", gap: 5, padding: "6px 4px 8px" }}>
              {LIST_COLORS.map((c) => (
                <div
                  key={c}
                  className={`color-swatch${newListColor === c ? " selected" : ""}`}
                  style={{ background: c, color: c }}
                  onClick={() => setNewListColor(c)}
                />
              ))}
            </div>
            <input
              ref={inputRef}
              className="form-input"
              placeholder={t("listNamePlaceholder")}
              value={newListName}
              onChange={(e) => setNewListName(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") createList();
                if (e.key === "Escape") setShowNewList(false);
              }}
              style={{ marginBottom: 6 }}
            />
            <div style={{ display: "flex", gap: 6 }}>
              <button className="btn btn-primary btn-sm" style={{ flex: 1 }} onClick={createList} type="button">
                {t("create")}
              </button>
              <button className="btn btn-ghost btn-sm" onClick={() => setShowNewList(false)} type="button">
                {t("cancel")}
              </button>
            </div>
          </div>
        ) : (
          <button id="new-list-btn" className="sidebar-add-btn" onClick={() => setShowNewList(true)} type="button">
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" />
            </svg>
            {t("newList")}
          </button>
        )}
      </nav>

      {/* User footer */}
      <div className="sidebar-footer">
        <div className="user-card" id="user-menu-btn" onClick={() => setUserMenuOpen((p) => !p)} style={{ position: "relative" }}>
          <div className="user-avatar" style={{ background: "var(--accent)" }}>{initials}</div>
          <div className="user-info">
            <div className="user-name">{user.name || (isDemo ? "Demo User" : "User")}</div>
            <div className="user-email">{user.email || (isDemo ? "demo@checkflow.local" : "")}</div>
          </div>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ opacity: 0.4 }}>
            <polyline points="6 9 12 15 18 9" />
          </svg>

          {/* User Popover Menu */}
          {userMenuOpen && (
            <div className="dropdown" style={{ bottom: "calc(100% + 6px)", left: 0, right: 0 }}>
              <div
                className="dropdown-item"
                id="sidebar-settings-menu-item"
                onClick={(e) => {
                  e.stopPropagation();
                  setShowSettings(true);
                  setUserMenuOpen(false);
                }}
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                  <circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
                </svg>
                {t("settingsModalTitle") || "Settings"}
              </div>

              <div
                className="dropdown-item"
                id="sidebar-import-menu-item"
                onClick={(e) => {
                  e.stopPropagation();
                  setShowImport(true);
                  setImportListId(lists[0]?.id || "");
                  setUserMenuOpen(false);
                }}
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" y1="15" x2="12" y2="3" />
                </svg>
                {t("importTasks")}
              </div>

              <div
                className="dropdown-item"
                id="sidebar-export-menu-item"
                onClick={(e) => {
                  e.stopPropagation();
                  setShowExport(true);
                  setUserMenuOpen(false);
                }}
              >
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                  <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="17 8 12 3 7 8" /><line x1="12" y1="3" x2="12" y2="15" />
                </svg>
                {t("exportTasks")}
              </div>

              <div className="dropdown-divider" />

              {isDemo ? (
                <div className="dropdown-item" onClick={() => { router.push("/login"); }}>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" /><polyline points="10 17 15 12 10 7" /><line x1="15" y1="12" x2="3" y2="12" />
                  </svg>
                  {t("signIn")}
                </div>
              ) : (
                <div className="dropdown-item danger" id="signout-btn" onClick={() => signOut({ callbackUrl: "/login" })}>
                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" /><polyline points="16 17 21 12 16 7" /><line x1="21" y1="12" x2="9" y2="12" />
                  </svg>
                  {t("signOut")}
                </div>
              )}
            </div>
          )}
        </div>
      </div>

      {/* Context Menu on List */}
      {contextMenu && (
        <ContextMenu
          x={contextMenu.x}
          y={contextMenu.y}
          items={getListContextMenuItems(contextMenu.listId)}
          onClose={() => setContextMenu(null)}
        />
      )}

      {/* Settings Modal */}
      <SettingsModal
        isOpen={showSettings}
        onClose={() => setShowSettings(false)}
        user={user}
        isDemo={isDemo}
      />

      {/* Import modal */}
      {showImport && (
        <div className="modal-overlay" onClick={() => setShowImport(false)}>
          <div className="modal" onClick={(e) => e.stopPropagation()}>
            <h2 className="modal-title">{t("importModalTitle")}</h2>
            <div className="form-group">
              <label className="form-label">{t("targetList")}</label>
              <select className="form-input" value={importListId} onChange={(e) => setImportListId(e.target.value)}>
                {lists.map((l) => <option key={l.id} value={l.id}>{l.name}</option>)}
              </select>
            </div>
            <div className="form-group">
              <label className="form-label">{t("fileSelectLabel")}</label>
              <input ref={fileRef} type="file" accept=".csv,.ics" className="form-input" />
            </div>
            <p style={{ fontSize: 12, color: "var(--text-tertiary)", marginBottom: 12 }}>
              {t("tickTickExportHint")}
            </p>
            {importResult && (
              <p style={{ fontSize: 13, color: importResult.startsWith("✓") ? "var(--success)" : "var(--danger)", marginBottom: 12 }}>
                {importResult}
              </p>
            )}
            <div className="modal-footer">
              <button className="btn btn-ghost" onClick={() => setShowImport(false)} type="button">{t("cancel")}</button>
              <button id="import-submit-btn" className="btn btn-primary" onClick={handleImport} disabled={importing} type="button">
                {importing ? t("importing") : t("importBtn")}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Export modal */}
      {showExport && (
        <div className="modal-overlay" onClick={() => setShowExport(false)}>
          <div className="modal" onClick={(e) => e.stopPropagation()} style={{ maxWidth: 440 }}>
            <h2 className="modal-title">📤 {t("exportModalTitle")}</h2>

            <div className="form-group">
              <label className="form-label">{t("exportFormat")}</label>
              <div style={{ display: "flex", gap: 8 }}>
                <button
                  type="button"
                  className={`btn btn-sm ${exportFormat === "csv" ? "btn-primary" : "btn-ghost"}`}
                  onClick={() => setExportFormat("csv")}
                  style={{ flex: 1 }}
                >
                  📄 CSV (TickTick/Excel)
                </button>
                <button
                  type="button"
                  className={`btn btn-sm ${exportFormat === "ics" ? "btn-primary" : "btn-ghost"}`}
                  onClick={() => setExportFormat("ics")}
                  style={{ flex: 1 }}
                >
                  📅 ICS (iCalendar VTODO)
                </button>
              </div>
            </div>

            <div className="form-group">
              <label className="form-label">{t("exportScope")}</label>
              <select className="form-input" value={exportListId} onChange={(e) => setExportListId(e.target.value)}>
                <option value="all">{t("allLists")}</option>
                {lists.map((l) => (
                  <option key={l.id} value={l.id}>
                    {l.name}
                  </option>
                ))}
              </select>
            </div>

            <div className="form-group" style={{ marginBottom: 16 }}>
              <label style={{ display: "flex", alignItems: "center", gap: 8, cursor: "pointer", fontSize: 13, color: "var(--text-primary)" }}>
                <input
                  type="checkbox"
                  checked={exportIncludeCompleted}
                  onChange={(e) => setExportIncludeCompleted(e.target.checked)}
                  style={{ accentColor: "var(--accent)" }}
                />
                <span>{t("includeCompleted")}</span>
              </label>
            </div>

            <div className="modal-footer">
              <button className="btn btn-ghost" onClick={() => setShowExport(false)} type="button">
                {t("cancel")}
              </button>
              <button
                id="export-submit-btn"
                className="btn btn-primary"
                onClick={handleExport}
                disabled={exporting}
                type="button"
              >
                {exporting ? "..." : `📥 ${t("exportBtn")}`}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Undo Toast */}
      {undoToast && (
        <div
          style={{
            position: "fixed",
            bottom: 24,
            left: "50%",
            transform: "translateX(-50%)",
            zIndex: 300,
            display: "flex",
            alignItems: "center",
            gap: 10,
            background: "var(--text-primary)",
            color: "var(--bg-primary)",
            padding: "10px 16px",
            borderRadius: "var(--radius-full)",
            fontSize: 13,
            fontWeight: 500,
            boxShadow: "var(--shadow-lg)",
            animation: "toastIn var(--dur-normal) var(--ease-out)",
            whiteSpace: "nowrap",
          }}
        >
          <span>{undoToast.message}</span>
          <button
            type="button"
            onClick={() => {
              undoToast.onUndo();
              if (undoToast.timeoutId) clearTimeout(undoToast.timeoutId);
              setUndoToast(null);
            }}
            style={{
              background: "var(--accent)",
              color: "#fff",
              border: "none",
              borderRadius: "var(--radius-sm)",
              padding: "3px 10px",
              fontSize: 12,
              fontWeight: 700,
              cursor: "pointer",
            }}
          >
            {t("undoDelete")}
          </button>
          <button
            type="button"
            onClick={() => {
              if (undoToast.timeoutId) clearTimeout(undoToast.timeoutId);
              setUndoToast(null);
            }}
            style={{
              background: "transparent",
              color: "inherit",
              border: "none",
              opacity: 0.6,
              cursor: "pointer",
              fontSize: 14,
              padding: "0 2px",
            }}
          >
            ✕
          </button>
        </div>
      )}
    </aside>
  );
}