import { Component, createSignal, onMount, Show } from "solid-js";
import { generateToc, type FileNode, type TocNode } from "../data-loader";
import { useLocation, useNavigate } from "@solidjs/router";

interface SidebarProps {
  isOpen: boolean;
  onClose: () => void;
}

/**
 * 文件树节点组件
 */
const FileTreeNode: Component<{
  node: FileNode;
  currentPath: string;
  pathHeadings: Record<string, TocNode[]>;
  depth: number;
}> = (props) => {
  const navigate = useNavigate();
  const [isExpanded, setIsExpanded] = createSignal(true);
  const isDir = !!props.node.children;
  const isActive = props.currentPath === props.node.path;

  const handleClick = () => {
    if (isDir) {
      setIsExpanded(!isExpanded());
    } else {
      navigate(props.node.path);
      props.onClose();
    }
  };

  const indent = props.depth * 12;

  return (
    <div>
      <div
        class={`flex items-center py-1 px-2 cursor-pointer hover:bg-gray-100 rounded ${
          isActive ? "bg-blue-50 text-blue-700" : "text-gray-700"
        }`}
        style={{ "padding-left": `${indent + 8}px` }}
        onClick={handleClick}
      >
        <Show when={isDir}>
          <span class="mr-1 text-gray-400">{isExpanded() ? "📂" : "📁"}</span>
        </Show>
        <Show when={!isDir}>
          <span class="mr-1 text-gray-400">📄</span>
        </Show>
        <span class="text-sm truncate">{props.node.name}</span>
      </div>
      <Show when={isDir && isExpanded() && props.node.children}>
        <div>
          {props.node.children!.map((child) => (
            <FileTreeNode
              node={child}
              currentPath={props.currentPath}
              pathHeadings={props.pathHeadings}
              depth={props.depth + 1}
              onClose={props.onClose}
            />
          ))}
        </div>
      </Show>
    </div>
  );
};

/**
 * 标题节点组件
 */
const HeadingNode: Component<{
  node: TocNode;
  basePath: string;
  depth: number;
}> = (props) => {
  const navigate = useNavigate();
  const anchor = props.node.title.toLowerCase().replace(/\s+/g, "-");
  const href = `${props.basePath}#${anchor}`;

  const handleClick = (e: MouseEvent) => {
    e.preventDefault();
    navigate(href);
  };

  const indent = props.depth * 12;

  return (
    <div>
      <a
        href={href}
        class="block py-0.5 px-2 text-sm text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded truncate"
        style={{ "padding-left": `${indent + 8}px` }}
        onClick={handleClick}
      >
        {props.node.title}
      </a>
      <Show when={props.node.children}>
        <div>
          {props.node.children!.map((child) => (
            <HeadingNode
              node={child}
              basePath={props.basePath}
              depth={props.depth + 1}
            />
          ))}
        </div>
      </Show>
    </div>
  );
};

/**
 * 侧边栏组件
 */
export const Sidebar: Component<SidebarProps> = (props) => {
  const location = useLocation();
  const [fileTree, setFileTree] = createSignal<FileNode[]>([]);
  const [pathHeadings, setPathHeadings] = createSignal<
    Record<string, TocNode[]>
  >({});
  const [currentFileHeadings, setCurrentFileHeadings] = createSignal<TocNode[]>(
    [],
  );

  onMount(async () => {
    const toc = await generateToc();
    setFileTree(toc.fileTree);
    setPathHeadings(toc.pathHeadings);
  });

  // 根据当前路径更新当前文件的标题列表
  onMount(() => {
    const updateHeadings = () => {
      const pathname = location.pathname;
      const headings =
        pathHeadings()[pathname] || pathHeadings()[`${pathname}.md`];
      setCurrentFileHeadings(headings || []);
    };
    updateHeadings();
  });

  return (
    <>
      {/* 遮罩层 */}
      <div
        class={`fixed inset-0 bg-black/50 z-40 transition-opacity duration-300 ease-in-out ${
          props.isOpen ? "opacity-100" : "opacity-0 pointer-events-none"
        }`}
        onClick={props.onClose}
      />
      {/* 侧边栏 */}
      <aside
        class={`fixed top-0 left-0 h-full w-64 bg-white shadow-lg z-50 overflow-y-auto transform transition-transform duration-300 ease-in-out ${
          props.isOpen ? "translate-x-0" : "-translate-x-full"
        }`}
      >
        <div class="p-4">
          <div class="flex items-center justify-between mb-4">
            <h2 class="text-lg font-bold text-gray-900">目录</h2>
            <button
              onClick={props.onClose}
              class="text-gray-500 hover:text-gray-700"
              title="关闭"
            >
              ✕
            </button>
          </div>

          {/* 文件树 */}
          <div class="mb-4">
            <h3 class="text-xs font-semibold text-gray-500 uppercase mb-2 px-2">
              文件
            </h3>
            {fileTree().map((node) => (
              <FileTreeNode
                node={node}
                currentPath={location.pathname}
                pathHeadings={pathHeadings()}
                depth={0}
                onClose={props.onClose}
              />
            ))}
          </div>

          {/* 当前文件标题 */}
          <Show when={currentFileHeadings().length > 0}>
            <div>
              <h3 class="text-xs font-semibold text-gray-500 uppercase mb-2 px-2">
                本页
              </h3>
              {currentFileHeadings().map((node) => (
                <HeadingNode
                  node={node}
                  basePath={location.pathname}
                  depth={0}
                />
              ))}
            </div>
          </Show>
        </div>
      </aside>
    </>
  );
};
