import { customElement, noShadowDOM } from 'solid-element';
import { createSignal, For, Show, createEffect, createMemo, createResource } from 'solid-js';
import { marked } from '../markdown';
import { resolvePath } from '../utils';
import { loadCSV } from './utils/csv-loader';

export interface TableProps {
  roll?: boolean;
  remix?: boolean;
}

interface TableRow {
  label: string;
  body: string;
  [key: string]: string;
}

customElement('md-table', { roll: false, remix: false }, (props, { element }) => {
  noShadowDOM();
  const [rows, setRows] = createSignal<TableRow[]>([]);
  const [activeTab, setActiveTab] = createSignal(0);
  const [activeGroup, setActiveGroup] = createSignal<string | null>(null);
  const [bodyHtml, setBodyHtml] = createSignal('');
  let tabsContainer: HTMLDivElement | undefined;

  // 从 element 的 textContent 获取 CSV 路径
  const src = element?.textContent?.trim() || '';

  // 隐藏原始文本内容
  if (element) {
    element.textContent = '';
  }

  // 从父节点 article 的 data-src 获取当前 markdown 文件完整路径
  const articleEl = element?.closest('article[data-src]');
  const articlePath = articleEl?.getAttribute('data-src') || '';

  // 解析相对路径
  const resolvedSrc = resolvePath(articlePath, src);

  // 使用 createResource 加载 CSV，自动响应路径变化并避免重复加载
  const [csvData] = createResource(() => resolvedSrc, loadCSV);

  // 当数据加载完成后更新 rows
  createEffect(() => {
    const data = csvData();
    if (data) {
      setRows(data);
    }
  });

  // 检测是否有 group 列
  const hasGroup = createMemo(() => {
    const allRows = rows();
    return allRows.length > 0 && 'group' in allRows[0];
  });

  // 获取所有分组
  const groups = createMemo(() => {
    if (!hasGroup()) return [];
    const allRows = rows();
    const groupSet = new Set<string>();
    for (const row of allRows) {
      if (row.group) {
        groupSet.add(row.group);
      }
    }
    return Array.from(groupSet).sort();
  });

  // 根据当前选中的分组过滤行
  const filteredRows = createMemo(() => {
    const allRows = rows();
    const group = activeGroup();
    if (!group) return allRows;
    return allRows.filter(row => row.group === group);
  });

  // 处理 body 内容中的 {{prop}} 语法并解析 markdown
  const processBody = (body: string, currentRow: TableRow): string => {
    let processedBody = body;

    if (!props.remix) {
      // 不启用 remix 时，只替换当前行的引用
      processedBody = body.replace(/\{\{(\w+)\}\}/g, (_, key) => currentRow[key] || '');
    } else {
      // 启用 remix 时，每次引用使用随机行的内容
      processedBody = body.replace(/\{\{(\w+)\}\}/g, (_, key) => {
        const randomRow = rows()[Math.floor(Math.random() * rows().length)];
        return randomRow?.[key] || '';
      });
    }

    // 使用 marked 解析 markdown
    return marked.parse(processedBody) as string;
  };

  // 更新 body 内容
  const updateBodyContent = () => {
    const filtered = filteredRows();
    if (!csvData.loading && filtered.length > 0) {
      const index = Math.min(activeTab(), filtered.length - 1);
      const currentRow = filtered[index];
      setBodyHtml(processBody(currentRow.body, currentRow));
    }
  };

  // 监听 activeTab 和 activeGroup 变化并更新内容
  createEffect(() => {
    activeTab();
    activeGroup();
    updateBodyContent();
  });

  // 切换分组时重置 tab 索引
  const handleGroupChange = (group: string | null) => {
    setActiveGroup(group);
    setActiveTab(0);
  };

  // 随机切换 tab
  const handleRoll = () => {
    const randomIndex = Math.floor(Math.random() * filteredRows().length);
    setActiveTab(randomIndex);
    // 滚动到可视区域
    setTimeout(() => {
      const activeButton = tabsContainer?.querySelector('.border-blue-600');
      activeButton?.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
    }, 50);
  };

  return (
    <div class="ttrpg-table">
      <div class="flex items-center gap-2 border-b border-gray-200">
        <div class="flex flex-col overflow-x-auto">
          {/* 分组 tabs */}
          <Show when={hasGroup()}>
            <div class="flex gap-2 border-b border-gray-100 pb-2">
              <button
                onClick={() => handleGroupChange(null)}
                class={`font-medium transition-colors ${
                  activeGroup() === null
                    ? 'text-blue-600 border-b-2 border-blue-600'
                    : 'text-gray-500 hover:text-gray-700'
                }`}
              >
                全部
              </button>
              <For each={groups()}>
                {(group) => (
                  <button
                    onClick={() => handleGroupChange(group)}
                    class={`font-medium transition-colors ${
                      activeGroup() === group
                        ? 'text-blue-600 border-b-2 border-blue-600'
                        : 'text-gray-500 hover:text-gray-700'
                    }`}
                  >
                    {group}
                  </button>
                )}
              </For>
            </div>
          </Show>
          {/* 内容 tabs */}
          <div class="flex items-center gap-2">
            <Show when={props.roll}>
              <button
                onClick={handleRoll}
                class="text-gray-500 hover:text-gray-700 flex-shrink-0 cursor-pointer"
                title="随机切换"
              >
                🎲
              </button>
            </Show>
            <div ref={tabsContainer} class="flex gap-1 overflow-x-auto flex-1 min-w-0">
              <For each={filteredRows()}>
                {(row, index) => (
                  <button
                    onClick={() => setActiveTab(index())}
                    class={`font-medium transition-colors flex-shrink-0 min-w-[1.6em] cursor-pointer ${
                      activeTab() === index()
                        ? 'text-blue-600 border-b-2 border-blue-600'
                        : 'text-gray-500 hover:text-gray-700'
                    }`}
                  >
                    {row.label}
                  </button>
                )}
              </For>
            </div>
          </div>
        </div>
      </div>
      <div class="p-1 prose max-w-none">
        <Show when={!csvData.loading && filteredRows().length > 0}>
          <div innerHTML={bodyHtml()} />
        </Show>
      </div>
    </div>
  );
});
