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

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

interface SidebarContentProps {
  fileTree: FileNode[];
  pathHeadings: Record<string, TocNode[]>;
  currentPath: string;
  onClose: () => void;
  isDesktop?: boolean;
}

/**
 * 侧边栏内容组件
 */
const SidebarContent: Component<SidebarContentProps> = (props) => {
  const location = useLocation();

  // 响应式获取当前文件的标题列表
  const currentFileHeadings = createMemo(() => {
    const pathname = decodeURIComponent(location.pathname);
    return props.pathHeadings[pathname] || props.pathHeadings[`${pathname}.md`] || [];
  });

  return (
    <div class="p-4">
      <div class="flex items-center justify-between mb-4">
        <h2 class="text-lg font-bold text-gray-900">目录</h2>
        <Show when={!props.isDesktop}>
          <button
            onClick={props.onClose}
            class="text-gray-500 hover:text-gray-700"
            title="关闭"
          >
            ✕
          </button>
        </Show>
      </div>

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

      {/* 当前文件标题 */}
      <Show when={currentFileHeadings().length > 0}>
        <div class="xl:fixed xl:top-20 xl:right-4 xl:bottom-4 xl:overflow-y-auto xl:max-w-30 2xl:max-w-60">
          <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>
  );
};

/**
 * 侧边栏组件（移动端抽屉）
 */
export const MobileSidebar: Component<SidebarProps> = (props) => {
  const location = useLocation();
  const [fileTree, setFileTree] = createSignal<FileNode[]>([]);
  const [pathHeadings, setPathHeadings] = createSignal<Record<string, TocNode[]>>({});

  // 加载目录数据
  onMount(async () => {
    const toc = await generateToc();
    setFileTree(toc.fileTree);
    setPathHeadings(toc.pathHeadings);
  });

  return (
    <>
      {/* 遮罩层 */}
      <div
        class={`fixed inset-0 bg-black/50 z-40 transition-opacity duration-300 ease-in-out md:hidden ${
          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 md:hidden ${
          props.isOpen ? "translate-x-0" : "-translate-x-full"
        }`}
      >
        <SidebarContent
          fileTree={fileTree()}
          pathHeadings={pathHeadings()}
          currentPath={location.pathname}
          onClose={props.onClose}
        />
      </aside>
    </>
  );
};

/**
 * 桌面端固定侧边栏
 */
export const DesktopSidebar: Component<{}> = () => {
  const location = useLocation();
  const [fileTree, setFileTree] = createSignal<FileNode[]>([]);
  const [pathHeadings, setPathHeadings] = createSignal<Record<string, TocNode[]>>({});

  // 加载目录数据
  onMount(async () => {
    const toc = await generateToc();
    setFileTree(toc.fileTree);
    setPathHeadings(toc.pathHeadings);
  });

  return (
    <aside class="hidden md:block fixed top-0 left-0 h-full w-64 bg-white shadow-lg z-30 overflow-y-auto pt-16">
      <SidebarContent
        fileTree={fileTree()}
        pathHeadings={pathHeadings()}
        currentPath={location.pathname}
        onClose={() => {}}
        isDesktop
      />
    </aside>
  );
};
