import { defineStore } from 'pinia';

const FILE_STORE_DEBUG_LOGS = false;
function fileDebugLog(...args: unknown[]) {
  if (!FILE_STORE_DEBUG_LOGS) {
    return;
  }
  console.log(...args);
}

interface FileNode {
  type: 'folder' | 'file';
  name: string;
  path: string;
  annotation?: string;
  children?: FileNode[];
}

interface TodoTask {
  index: number;
  title: string;
  status: string;
}

interface TodoList {
  instruction?: string;
  tasks?: TodoTask[];
}

interface ContextMenuState {
  visible: boolean;
  x: number;
  y: number;
  node: FileNode | null;
}

interface FileState {
  fileTree: FileNode[];
  expandedFolders: Record<string, boolean>;
  todoList: TodoList | null;
  fileTreeUnavailable: boolean;
  fileTreeMessage: string;
  contextMenu: ContextMenuState;
}

function buildNodes(treeMap: Record<string, any> | undefined): FileNode[] {
  if (!treeMap) {
    return [];
  }
  const entries = Object.keys(treeMap).map((name) => {
    const node = treeMap[name] || {};
    if (node.type === 'folder') {
      return {
        type: 'folder' as const,
        name,
        path: node.path || name,
        children: buildNodes(node.children)
      };
    }
    return {
      type: 'file' as const,
      name,
      path: node.path || name,
      annotation: node.annotation || ''
    };
  });
  entries.sort((a, b) => {
    if (a.type !== b.type) {
      return a.type === 'folder' ? -1 : 1;
    }
    return a.name.localeCompare(b.name, 'zh-CN');
  });
  return entries;
}

export const useFileStore = defineStore('file', {
  state: (): FileState => ({
    fileTree: [],
    expandedFolders: {},
    todoList: null,
    fileTreeUnavailable: false,
    fileTreeMessage: '',
    contextMenu: {
      visible: false,
      x: 0,
      y: 0,
      node: null
    }
  }),
  actions: {
    async fetchFileTree() {
      try {
        const response = await fetch('/api/files');
        const data = await response.json();
        fileDebugLog('[FileTree] fetch result', data);
        this.setFileTreeFromResponse(data);
      } catch (error) {
        console.error('获取文件树失败:', error);
      }
    },
    markFileTreeUnavailable(message: string) {
      this.fileTreeUnavailable = true;
      this.fileTreeMessage = message || '宿主机模式下文件树不可用';
      this.fileTree = [];
      this.expandedFolders = {};
    },
    setFileTreeFromResponse(payload: any) {
      if (!payload) {
        console.warn('[FileTree] 空 payload');
        return;
      }
      if (payload.unavailable) {
        this.markFileTreeUnavailable(payload.message || payload.error);
        return;
      }
      const structure = payload.structure || payload;
      if (structure && structure.unavailable) {
        this.markFileTreeUnavailable(structure.message || structure.error);
        return;
      }
      if (!structure || !structure.tree) {
        console.warn('[FileTree] 缺少 structure.tree', structure);
        return;
      }
      this.fileTreeUnavailable = false;
      this.fileTreeMessage = '';
      const nodes = buildNodes(structure.tree);
      const expanded = { ...this.expandedFolders };
      const validFolderPaths = new Set<string>();

      const ensureExpansion = (list: FileNode[]) => {
        list.forEach((item) => {
          if (item.type === 'folder') {
            validFolderPaths.add(item.path);
            if (expanded[item.path] === undefined) {
              expanded[item.path] = false;
            }
            ensureExpansion(item.children || []);
          }
        });
      };

      ensureExpansion(nodes);
      Object.keys(expanded).forEach((path) => {
        if (!validFolderPaths.has(path)) {
          delete expanded[path];
        }
      });

      this.expandedFolders = expanded;
      this.fileTree = nodes;
    },
    toggleFolder(path: string) {
      if (!path) {
        return;
      }
      const current = !!this.expandedFolders[path];
      fileDebugLog('[FileTree] toggle folder', path, '=>', !current);
      this.expandedFolders = {
        ...this.expandedFolders,
        [path]: !current
      };
    },
    async fetchTodoList() {
      try {
        const response = await fetch('/api/todo-list');
        const data = await response.json();
        if (data && data.success) {
          this.todoList = data.data || null;
        }
      } catch (error) {
        console.error('获取待办列表失败:', error);
      }
    },
    setTodoList(payload: TodoList | null) {
      this.todoList = payload;
    },
    showContextMenu(payload: { node: FileNode; event: MouseEvent }) {
      if (!payload || !payload.node) {
        return;
      }
      const { node, event } = payload;
      if (!node.path && node.path !== '') {
        this.hideContextMenu();
        return;
      }
      if (node.type !== 'file' && node.type !== 'folder') {
        this.hideContextMenu();
        return;
      }

      if (event && typeof event.preventDefault === 'function') {
        event.preventDefault();
      }
      if (event && typeof event.stopPropagation === 'function') {
        event.stopPropagation();
      }

      const menuWidth = 200;
      const menuHeight = 50;
      const viewportWidth = window.innerWidth;
      const viewportHeight = window.innerHeight;
      let x = (event && event.clientX) || 0;
      let y = (event && event.clientY) || 0;

      if (x + menuWidth > viewportWidth) {
        x = viewportWidth - menuWidth - 8;
      }
      if (y + menuHeight > viewportHeight) {
        y = viewportHeight - menuHeight - 8;
      }

      this.contextMenu = {
        visible: true,
        x: Math.max(8, x),
        y: Math.max(8, y),
        node
      };
    },
    hideContextMenu() {
      if (!this.contextMenu.visible) {
        return;
      }
      this.contextMenu = {
        visible: false,
        x: 0,
        y: 0,
        node: null
      };
    }
  }
});
