"use client";
import { useState, useCallback, useEffect } from "react";
import { Sidebar } from "./Sidebar";
import { TaskList, Task, List, User } from "../tasks/TaskList";
import { TaskDetail } from "../tasks/TaskDetail";
import { getDemoStore, saveDemoStore, MockList, MockTask } from "@/lib/mockData";

interface AppShellProps {
  user: User;
  isDemo?: boolean;
}

export function AppShell({ user, isDemo = false }: AppShellProps) {
  const [lists, setLists] = useState<List[]>([]);
  const [selectedListId, setSelectedListId] = useState<string | null>(null);
  const [selectedTask, setSelectedTask] = useState<Task | null>(null);
  const [tasks, setTasks] = useState<Task[]>([]);
  const [sidebarOpen, setSidebarOpen] = useState(false);
  const [showCompleted, setShowCompleted] = useState(false);
  const [refreshKey, setRefreshKey] = useState(0);

  // Demo store loading
  useEffect(() => {
    if (isDemo) {
      const store = getDemoStore();
      setLists(store.lists);
      if (store.lists.length > 0) {
        setSelectedListId(store.lists[0].id);
      }
    }
  }, [isDemo]);

  // Demo tasks filter & reconstruct hierarchical structure
  useEffect(() => {
    if (isDemo && selectedListId) {
      const store = getDemoStore();
      const listTasks = (store.tasks as Task[]).filter(
        (t) => t.listId === selectedListId && (showCompleted ? true : !t.completed)
      );
      setTasks(listTasks);
    }
  }, [isDemo, selectedListId, showCompleted, refreshKey]);

  const refresh = useCallback(() => setRefreshKey((k) => k + 1), []);

  const handleTaskSelect = useCallback((task: Task | null) => {
    setSelectedTask(task);
  }, []);

  // Update a task and sync with main list and selected panel
  const handleTaskUpdate = useCallback((updated: Task) => {
    setTasks((prev) =>
      prev.map((t) => {
        if (t.id === updated.id) {
          return { ...updated, children: updated.children || t.children || [] };
        }
        // If a sub-task was updated directly, update parent's children
        if (t.children && t.children.some((c) => c.id === updated.id)) {
          const newChildren = t.children.map((c) => (c.id === updated.id ? updated : c));
          return { ...t, children: newChildren };
        }
        return t;
      })
    );

    setSelectedTask((prev) => {
      if (prev && prev.id === updated.id) {
        return { ...updated, children: updated.children || prev.children || [] };
      }
      return prev;
    });
  }, []);

  const handleListSelect = useCallback((id: string) => {
    setSelectedListId(id);
    setSelectedTask(null);
    setSidebarOpen(false);
  }, []);

  // Update List Name (Inline edit on header or sidebar)
  const handleUpdateListName = async (id: string, newName: string) => {
    const trimmed = newName.trim();
    if (!trimmed) return;

    if (isDemo) {
      const store = getDemoStore();
      const newLists = store.lists.map((l) => (l.id === id ? { ...l, name: trimmed } : l));
      saveDemoStore(newLists, store.tasks);
      setLists(newLists);
      return;
    }

    try {
      const res = await fetch(`/api/lists/${id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: trimmed }),
      });
      if (res.ok) {
        const updated = await res.json();
        setLists((prev) => prev.map((l) => (l.id === id ? { ...l, name: updated.name } : l)));
      }
    } catch (err) {
      console.error("Failed to update list name", err);
    }
  };

  // Demo Handlers
  const handleDemoCreateList = (name: string, color: string) => {
    const newList: MockList = {
      id: "demo-list-" + Date.now(),
      name,
      color,
      icon: "list",
    };
    const store = getDemoStore();
    const newLists = [...store.lists, newList];
    saveDemoStore(newLists, store.tasks);
    setLists(newLists);
    setSelectedListId(newList.id);
  };

  const handleDemoDeleteList = (id: string) => {
    const store = getDemoStore();
    const newLists = store.lists.filter((l) => l.id !== id);
    const newTasks = store.tasks.filter((t) => t.listId !== id);
    saveDemoStore(newLists, newTasks);
    setLists(newLists);
    if (selectedListId === id) {
      setSelectedListId(newLists[0]?.id || null);
    }
    refresh();
  };

  const handleDemoAddTask = (title: string, listId: string, parentId: string | null = null) => {
    const newTask: Task = {
      id: "demo-task-" + Date.now(),
      listId,
      parentId: parentId || null,
      title,
      note: null,
      completed: false,
      completedAt: null,
      dueDate: null,
      priority: 0,
      sortOrder: tasks.length,
      createdAt: new Date().toISOString(),
      updatedAt: new Date().toISOString(),
      children: [],
      tags: [],
    };
    const store = getDemoStore();

    if (parentId) {
      // Add as subtask to parent
      const newTasks = store.tasks.map((t) => {
        if (t.id === parentId) {
          const currentChildren = t.children || [];
          return { ...t, children: [...currentChildren, newTask as MockTask] };
        }
        return t;
      });
      saveDemoStore(store.lists, newTasks);
      setTasks((prev) =>
        prev.map((t) => (t.id === parentId ? { ...t, children: [...(t.children || []), newTask] } : t))
      );
      if (selectedTask && selectedTask.id === parentId) {
        setSelectedTask((prev) => (prev ? { ...prev, children: [...(prev.children || []), newTask] } : prev));
      }
    } else {
      // Top-level task
      const newTasks = [...store.tasks, newTask as MockTask];
      saveDemoStore(store.lists, newTasks);
      setTasks((prev) => [...prev, newTask]);
    }
    refresh();
  };

  const handleDemoToggleTask = (id: string, completed: boolean) => {
    const store = getDemoStore();
    const newTasks = store.tasks.map((t) => {
      if (t.id === id) {
        return { ...t, completed, completedAt: completed ? new Date().toISOString() : null };
      }
      if (t.children && t.children.some((c) => c.id === id)) {
        const newChildren = t.children.map((c) =>
          c.id === id ? { ...c, completed, completedAt: completed ? new Date().toISOString() : null } : c
        );
        return { ...t, children: newChildren };
      }
      return t;
    });
    saveDemoStore(store.lists, newTasks);

    setTasks((prev) =>
      prev
        .map((t) => {
          if (t.id === id) {
            return { ...t, completed, completedAt: completed ? new Date().toISOString() : null };
          }
          if (t.children && t.children.some((c) => c.id === id)) {
            const newChildren = t.children.map((c) =>
              c.id === id ? { ...c, completed, completedAt: completed ? new Date().toISOString() : null } : c
            );
            return { ...t, children: newChildren };
          }
          return t;
        })
        .filter((t) => showCompleted || !t.completed)
    );

    if (selectedTask) {
      if (selectedTask.id === id) {
        setSelectedTask((prev) => (prev ? { ...prev, completed, completedAt: completed ? new Date().toISOString() : null } : prev));
      } else if (selectedTask.children && selectedTask.children.some((c) => c.id === id)) {
        setSelectedTask((prev) =>
          prev
            ? {
                ...prev,
                children: prev.children.map((c) =>
                  c.id === id ? { ...c, completed, completedAt: completed ? new Date().toISOString() : null } : c
                ),
              }
            : prev
        );
      }
    }
    refresh();
  };

  const handleDemoUpdateTask = (updated: Task) => {
    const store = getDemoStore();
    const newTasks = store.tasks.map((t) => (t.id === updated.id ? (updated as MockTask) : t));
    saveDemoStore(store.lists, newTasks);
    handleTaskUpdate(updated);
  };

  const handleDemoDeleteTask = (id: string) => {
    const store = getDemoStore();
    // Remove if main task or remove from parent children
    const newTasks = store.tasks
      .filter((t) => t.id !== id)
      .map((t) => {
        if (t.children && t.children.some((c) => c.id === id)) {
          return { ...t, children: t.children.filter((c) => c.id !== id) };
        }
        return t;
      });
    saveDemoStore(store.lists, newTasks);
    setTasks((prev) =>
      prev
        .filter((t) => t.id !== id)
        .map((t) => (t.children ? { ...t, children: t.children.filter((c) => c.id !== id) } : t))
    );
    if (selectedTask?.id === id) {
      setSelectedTask(null);
    } else if (selectedTask?.children?.some((c) => c.id === id)) {
      setSelectedTask((prev) => (prev ? { ...prev, children: prev.children.filter((c) => c.id !== id) } : prev));
    }
    refresh();
  };

  // Inline update task title from main list
  const handleUpdateTaskTitle = async (taskId: string, newTitle: string) => {
    const trimmed = newTitle.trim();
    if (!trimmed) return;

    if (isDemo) {
      const store = getDemoStore();
      const newTasks = store.tasks.map((t) => {
        if (t.id === taskId) return { ...t, title: trimmed };
        if (t.children && t.children.some((c) => c.id === taskId)) {
          return { ...t, children: t.children.map((c) => (c.id === taskId ? { ...c, title: trimmed } : c)) };
        }
        return t;
      });
      saveDemoStore(store.lists, newTasks);
      setTasks((prev) =>
        prev.map((t) => {
          if (t.id === taskId) return { ...t, title: trimmed };
          if (t.children && t.children.some((c) => c.id === taskId)) {
            return { ...t, children: t.children.map((c) => (c.id === taskId ? { ...c, title: trimmed } : c)) };
          }
          return t;
        })
      );
      if (selectedTask?.id === taskId) {
        setSelectedTask((prev) => (prev ? { ...prev, title: trimmed } : prev));
      }
      return;
    }

    try {
      const res = await fetch(`/api/tasks/${taskId}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ title: trimmed }),
      });
      if (res.ok) {
        const updated = await res.json();
        handleTaskUpdate(updated);
      }
    } catch (err) {
      console.error("Failed to update task title", err);
    }
  };

  return (
    <div className="app-layout">
      {/* Mobile overlay */}
      {sidebarOpen && (
        <div
          className="modal-overlay"
          style={{ zIndex: 25 }}
          onClick={() => setSidebarOpen(false)}
        />
      )}

      <Sidebar
        user={user}
        lists={lists}
        setLists={setLists}
        selectedListId={selectedListId}
        onListSelect={handleListSelect}
        mobileOpen={sidebarOpen}
        onClose={() => setSidebarOpen(false)}
        isDemo={isDemo}
        onDemoCreateList={handleDemoCreateList}
        onDemoDeleteList={handleDemoDeleteList}
      />

      <div className="main-content">
        <TaskList
          key={`${selectedListId}-${refreshKey}`}
          user={user}
          listId={selectedListId}
          lists={lists}
          tasks={tasks}
          setTasks={setTasks}
          selectedTaskId={selectedTask?.id ?? null}
          onTaskSelect={handleTaskSelect}
          showCompleted={showCompleted}
          onToggleCompleted={() => setShowCompleted((p) => !p)}
          onMenuOpen={() => setSidebarOpen(true)}
          onRefresh={refresh}
          isDemo={isDemo}
          onDemoAddTask={handleDemoAddTask}
          onDemoToggleTask={handleDemoToggleTask}
          onUpdateTaskTitle={handleUpdateTaskTitle}
          onUpdateListName={handleUpdateListName}
        />
      </div>

      {selectedTask && (
        <TaskDetail
          task={selectedTask}
          onClose={() => setSelectedTask(null)}
          onUpdate={handleTaskUpdate}
          onDelete={() => {
            setSelectedTask(null);
            refresh();
          }}
          listId={selectedTask.listId}
          isDemo={isDemo}
          onDemoUpdateTask={handleDemoUpdateTask}
          onDemoDeleteTask={handleDemoDeleteTask}
        />
      )}

      {/* Mobile FAB */}
      <button
        className="fab"
        id="mobile-add-task"
        aria-label="Add task"
        onClick={() => {
          document.dispatchEvent(new CustomEvent("checkflow:addTask"));
        }}
      >
        <svg width="22" height="22" 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>
      </button>
    </div>
  );
}