/* eslint-disable react-refresh/only-export-components */
/* eslint-disable react-hooks/exhaustive-deps */
import React, { createContext, useContext, useReducer, useEffect, useRef } from 'react';
import { readDirectoryTree, readMarkdownFile, NODE_TYPES } from '../utils/fileUtils';

// 将文件相对路径转换为浏览器 URL（/note/<编码后路径>）
function filePathToUrl(filePath) {
  if (!filePath) return '/';
  const encoded = filePath.split('/').map(encodeURIComponent).join('/');
  return `/note/${encoded}`;
}

// 从 pathname 中解析文件相对路径（/note/... → 相对路径）
function urlToFilePath(pathname) {
  if (!pathname.startsWith('/note/')) return null;
  const raw = pathname.slice('/note/'.length);
  if (!raw) return null;
  try {
    return raw.split('/').map(decodeURIComponent).join('/');
  } catch {
    return null;
  }
}

function getInitialSidebarOpen() {
  if (typeof window === 'undefined') return true;
  return window.matchMedia('(min-width: 769px)').matches;
}

const initialState = {
  directoryTree: [],
  currentFile: null,
  currentContent: '',
  currentMetadata: null,  // 添加元数据
  isLoading: false,
  error: null,
  sidebarOpen: getInitialSidebarOpen(),
};

export const ACTIONS = {
  SET_DIRECTORY_TREE: 'SET_DIRECTORY_TREE',
  SET_CURRENT_FILE: 'SET_CURRENT_FILE',
  SET_CURRENT_CONTENT: 'SET_CURRENT_CONTENT',
  SET_METADATA: 'SET_METADATA',
  SET_LOADING: 'SET_LOADING',
  SET_ERROR: 'SET_ERROR',
  TOGGLE_SIDEBAR: 'TOGGLE_SIDEBAR',
  TOGGLE_NODE_EXPANSION: 'TOGGLE_NODE_EXPANSION',
};

function appReducer(state, action) {
  switch (action.type) {
    case ACTIONS.SET_DIRECTORY_TREE:
      return {
        ...state,
        directoryTree: action.payload,
        isLoading: false,
      };

    case ACTIONS.SET_CURRENT_FILE:
      return {
        ...state,
        currentFile: action.payload,
      };

    case ACTIONS.SET_CURRENT_CONTENT:
      return {
        ...state,
        currentContent: action.payload,
        isLoading: false,
      };

    case ACTIONS.SET_METADATA:
      return {
        ...state,
        currentMetadata: action.payload,
      };

    case ACTIONS.SET_LOADING:
      return {
        ...state,
        isLoading: action.payload,
      };

    case ACTIONS.SET_ERROR:
      return {
        ...state,
        error: action.payload,
        isLoading: false,
      };

    case ACTIONS.TOGGLE_SIDEBAR:
      return {
        ...state,
        sidebarOpen: !state.sidebarOpen,
      };

    case ACTIONS.TOGGLE_NODE_EXPANSION:
      return {
        ...state,
        directoryTree: toggleNodeExpansion(state.directoryTree, action.payload),
      };

    default:
      return state;
  }
}

function toggleNodeExpansion(nodes, targetPath) {
  return nodes.map((node) => {
    if (node.path === targetPath) {
      return { ...node, isExpanded: !node.isExpanded };
    }
    if (node.children && node.children.length > 0) {
      return {
        ...node,
        children: toggleNodeExpansion(node.children, targetPath),
      };
    }
    return node;
  });
}

function findDefaultFilePath(nodes) {
  let defaultNotePath = null;
  let homepagePath = null;
  let firstFilePath = null;

  const traverse = (list) => {
    for (const node of list) {
      if (node.type === NODE_TYPES.FILE) {
        if (!firstFilePath) {
          firstFilePath = node.path;
        }
        if (!defaultNotePath && node.name === '📒萌芽笔记.md') {
          defaultNotePath = node.path;
        }
        if (!homepagePath && node.name === '首页.md') {
          homepagePath = node.path;
        }
      }
      if (node.children && node.children.length > 0) {
        traverse(node.children);
      }
    }
  };

  traverse(nodes);
  return defaultNotePath || homepagePath || firstFilePath || null;
}

function expandTreeForPath(nodes, targetPath) {
  if (!targetPath) {
    return nodes;
  }

  const pathSegments = targetPath.split('/');
  pathSegments.pop();

  if (pathSegments.length === 0) {
    return nodes;
  }

  const prefixSet = new Set();
  pathSegments.reduce((acc, segment) => {
    const next = acc ? `${acc}/${segment}` : segment;
    prefixSet.add(next);
    return next;
  }, '');

  const expand = (list) =>
    list.map((node) => {
      const shouldExpand = prefixSet.has(node.path);
      const children = node.children ? expand(node.children) : [];
      return {
        ...node,
        isExpanded: shouldExpand,
        children,
      };
    });

  return expand(nodes);
}

const AppContext = createContext();

export function AppProvider({ children }) {
  const [state, dispatch] = useReducer(appReducer, initialState);
  // 用 ref 避免在事件监听器闭包中捕获过期的 state
  const treeRef = useRef([]);

  const selectFile = async (filePath, { pushUrl = true } = {}) => {
    try {
      console.log('[MengyaNote] 选择文件:', filePath);
      dispatch({ type: ACTIONS.SET_LOADING, payload: true });
      dispatch({ type: ACTIONS.SET_CURRENT_FILE, payload: filePath });

      // 同步更新浏览器地址栏（不刷新页面）
      if (pushUrl) {
        const newUrl = filePathToUrl(filePath);
        if (window.location.pathname !== newUrl) {
          window.history.pushState({ filePath }, '', newUrl);
        }
      }

      const result = await readMarkdownFile(filePath);
      console.log('[MengyaNote] 文件内容加载成功');
      
      dispatch({ type: ACTIONS.SET_CURRENT_CONTENT, payload: result.content });
      dispatch({ type: ACTIONS.SET_METADATA, payload: result.metadata });
    } catch (error) {
      console.error('[MengyaNote] 加载文件失败:', error);
      dispatch({ type: ACTIONS.SET_ERROR, payload: error.message });
    }
  };

  // 根据文件路径展开目录树侧边栏对应节点
  const expandForPath = (filePath) => {
    if (!filePath || treeRef.current.length === 0) return;
    const expanded = expandTreeForPath(treeRef.current, filePath);
    dispatch({ type: ACTIONS.SET_DIRECTORY_TREE, payload: expanded });
  };

  const loadDirectoryTree = async () => {
    try {
      console.log('[MengyaNote] 开始加载目录树...');
      dispatch({ type: ACTIONS.SET_LOADING, payload: true });

      const urlFilePath = urlToFilePath(window.location.pathname);

      const [tree, preloadedFile] = await Promise.all([
        readDirectoryTree(),
        urlFilePath ? readMarkdownFile(urlFilePath) : Promise.resolve(null),
      ]);
      console.log('[MengyaNote] 目录树加载成功，节点数:', tree.length);

      const initialPath = urlFilePath || findDefaultFilePath(tree);
      console.log('[MengyaNote] 初始文件路径:', initialPath, urlFilePath ? '(来自URL)' : '(默认)');

      const enhancedTree = expandTreeForPath(tree, initialPath);
      treeRef.current = enhancedTree;
      dispatch({ type: ACTIONS.SET_DIRECTORY_TREE, payload: enhancedTree });

      if (urlFilePath) {
        dispatch({ type: ACTIONS.SET_CURRENT_FILE, payload: urlFilePath });
        dispatch({ type: ACTIONS.SET_CURRENT_CONTENT, payload: preloadedFile.content });
        dispatch({ type: ACTIONS.SET_METADATA, payload: preloadedFile.metadata });
        dispatch({ type: ACTIONS.SET_LOADING, payload: false });
      } else if (initialPath && !state.currentFile) {
        await selectFile(initialPath, { pushUrl: true });
      } else {
        dispatch({ type: ACTIONS.SET_LOADING, payload: false });
      }

      console.log('[MengyaNote] 初始化完成');
    } catch (error) {
      console.error('[MengyaNote] 加载目录树失败:', error);
      dispatch({ type: ACTIONS.SET_ERROR, payload: error.message });
    }
  };

  const toggleSidebar = () => {
    dispatch({ type: ACTIONS.TOGGLE_SIDEBAR });
  };

  const toggleNodeExpansion = (nodePath) => {
    dispatch({ type: ACTIONS.TOGGLE_NODE_EXPANSION, payload: nodePath });
  };

  // 监听浏览器前进/后退
  useEffect(() => {
    const handlePopState = (e) => {
      const filePath = e.state?.filePath || urlToFilePath(window.location.pathname);
      if (filePath) {
        selectFile(filePath, { pushUrl: false });
        expandForPath(filePath);
      }
    };
    window.addEventListener('popstate', handlePopState);
    return () => window.removeEventListener('popstate', handlePopState);
  }, []);

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

  // 保持 treeRef 与 state.directoryTree 同步
  useEffect(() => {
    treeRef.current = state.directoryTree;
  }, [state.directoryTree]);

  const value = {
    ...state,
    loadDirectoryTree,
    selectFile,
    toggleSidebar,
    toggleNodeExpansion,
  };

  return <AppContext.Provider value={value}>{children}</AppContext.Provider>;
}

export function useApp() {
  const context = useContext(AppContext);
  if (!context) {
    throw new Error('useApp must be used within an AppProvider');
  }
  return context;
}

