#!/usr/bin/env python3
"""
列出知识库中的信息（支持标准分类和自定义分类）

用法:
    uv run list_info.py --all                      # 列出所有分类概览
    uv run list_info.py <类型>                     # 列出该类型下所有文件名
    uv run list_info.py <类型> <名称1> <名称2>...  # 检查指定条目是否存在
    uv run list_info.py <类型> <名称1> --brief     # 显示元数据
    uv run list_info.py <类型> <名称1> --detail    # 显示完整信息

参数:
    类型: 角色/物品/场景/事件（标准分类）或自定义分类名称
    名称: (可选) 要列出的条目名称，可以指定多个

选项:
    --all: 显示所有分类概览（标准 + 自定义）
    --brief: 显示 YAML 元数据（仅在指定名称时可用）
    --detail: 显示完整信息（仅在指定名称时可用）

示例:
    uv run list_info.py --all                      # 显示所有分类概览
    uv run list_info.py 角色                       # 列出所有角色文件名
    uv run list_info.py 系统数据                   # 列出自定义分类下的文件
    uv run list_info.py 角色 张三 --brief          # 显示张三的元数据
    uv run list_info.py 系统数据 技能树 --detail   # 显示技能树的完整信息
"""

import re
import sys
from pathlib import Path


# 标准分类
STANDARD_TYPES = ['角色', '物品', '场景', '事件']


def extract_yaml_frontmatter(content: str):
    """提取 YAML frontmatter"""
    lines = content.split('\n')
    if not lines or lines[0].strip() != '---':
        return None

    yaml_lines = []
    for i in range(1, len(lines)):
        if lines[i].strip() == '---':
            return '\n'.join(yaml_lines)
        yaml_lines.append(lines[i])

    return None


def parse_info_structure():
    """
    解析 现有信息/信息结构.md 获取自定义分类信息

    返回: dict, 格式为 {分类名: {'type': 'directory'|'single_file', 'path': 路径}}
    """
    structure_file = Path.cwd() / "现有信息" / "信息结构.md"
    custom_categories = {}

    if not structure_file.exists():
        return custom_categories

    try:
        content = structure_file.read_text(encoding='utf-8')

        # 查找 "## 自定义分类" 部分
        custom_section_match = re.search(r'## 自定义分类\s*\n(.*?)(?=\n## |\Z)', content, re.DOTALL)
        if not custom_section_match:
            return custom_categories

        custom_section = custom_section_match.group(1)

        # 如果自定义分类部分只有"无"，则返回空
        if custom_section.strip() == '无' or '无自定义分类' in custom_section:
            return custom_categories

        # 查找所有 ### 开头的分类定义
        category_pattern = r'### ([^\n]+)\s*\n(.*?)(?=\n### |\Z)'
        categories = re.findall(category_pattern, custom_section, re.DOTALL)

        for name, details in categories:
            name = name.strip()
            if not name or name.startswith('['):  # 跳过模板占位符
                continue

            # 解析路径和结构类型
            path_match = re.search(r'\*\*路径\*\*:\s*`([^`]+)`', details)
            type_match = re.search(r'\*\*结构类型\*\*:\s*(目录|单文件)', details)

            if path_match:
                path = path_match.group(1)
                structure_type = 'single_file' if (type_match and type_match.group(1) == '单文件') else 'directory'

                # 确定实际路径
                if path.endswith('/'):
                    structure_type = 'directory'
                    actual_path = path.rstrip('/')
                elif path.endswith('.md'):
                    structure_type = 'single_file'
                    actual_path = path
                else:
                    actual_path = path

                custom_categories[name] = {
                    'type': structure_type,
                    'path': actual_path
                }

    except Exception:
        pass

    return custom_categories


def get_all_types():
    """获取所有有效的类型（标准 + 自定义）"""
    custom_categories = parse_info_structure()
    return STANDARD_TYPES + list(custom_categories.keys())


def get_category_info(info_type: str):
    """
    获取分类信息

    返回: {'type': 'standard'|'custom_directory'|'custom_single_file', 'path': Path对象}
    """
    base_path = Path.cwd() / "现有信息"

    if info_type in STANDARD_TYPES:
        return {
            'type': 'standard',
            'path': base_path / info_type
        }

    custom_categories = parse_info_structure()
    if info_type in custom_categories:
        cat_info = custom_categories[info_type]
        if cat_info['type'] == 'single_file':
            # 单文件结构
            return {
                'type': 'custom_single_file',
                'path': base_path / f"{info_type}.md"
            }
        else:
            # 目录结构
            return {
                'type': 'custom_directory',
                'path': base_path / info_type
            }

    # 尝试作为目录查找
    dir_path = base_path / info_type
    if dir_path.is_dir():
        return {
            'type': 'custom_directory',
            'path': dir_path
        }

    # 尝试作为单文件查找
    file_path = base_path / f"{info_type}.md"
    if file_path.is_file():
        return {
            'type': 'custom_single_file',
            'path': file_path
        }

    return None


def list_all_files(info_type: str):
    """列出所有文件名"""
    cat_info = get_category_info(info_type)

    if not cat_info:
        print(f"错误: 未找到分类 '{info_type}'")
        print(f"标准分类: {', '.join(STANDARD_TYPES)}")
        custom = parse_info_structure()
        if custom:
            print(f"自定义分类: {', '.join(custom.keys())}")
        return

    if cat_info['type'] == 'custom_single_file':
        # 单文件结构
        if cat_info['path'].exists():
            print(f"【{info_type}】(单文件结构)")
            print(f"  文件: {cat_info['path'].name}")
        else:
            print(f"未找到{info_type}信息")
        return

    # 目录结构
    info_dir = cat_info['path']

    if not info_dir.exists():
        print(f"目录不存在: 现有信息/{info_type}/")
        return

    files = sorted(info_dir.glob("*.md"))

    if not files:
        print(f"未找到{info_type}信息")
        return

    print(f"找到 {len(files)} 个{info_type}:\n")
    for file in files:
        name = file.stem
        print(f"- {name}")


def list_all_types():
    """列出所有类型的所有文件（标准 + 自定义）"""
    base_path = Path.cwd() / "现有信息"

    if not base_path.exists():
        print("未找到 '现有信息/' 目录")
        print("请先使用 /init 初始化项目")
        return

    print("📚 知识库分类概览\n")

    # 标准分类
    print("【标准分类】")
    total = 0
    for info_type in STANDARD_TYPES:
        type_path = base_path / info_type
        if type_path.exists():
            files = sorted(type_path.glob("*.md"))
            count = len(files)
            total += count
            print(f"  - {info_type}: {count} 个条目")
        else:
            print(f"  - {info_type}: 0 个条目")

    print()

    # 自定义分类
    custom_categories = parse_info_structure()

    if custom_categories:
        print("【自定义分类】")
        for name, info in custom_categories.items():
            if info['type'] == 'single_file':
                file_path = base_path / f"{name}.md"
                if file_path.exists():
                    print(f"  - {name}: 1 个条目 (单文件)")
                    total += 1
                else:
                    print(f"  - {name}: 0 个条目 (单文件，未创建)")
            else:
                dir_path = base_path / name
                if dir_path.exists():
                    files = sorted(dir_path.glob("*.md"))
                    count = len(files)
                    total += count
                    print(f"  - {name}: {count} 个条目 (目录)")
                else:
                    print(f"  - {name}: 0 个条目 (目录，未创建)")
    else:
        print("【自定义分类】")
        print("  无自定义分类")

    print()
    print(f"总计: {total} 个档案")


def check_files_exist(info_type: str, names: list):
    """检查指定文件是否存在"""
    cat_info = get_category_info(info_type)

    if not cat_info:
        print(f"错误: 未找到分类 '{info_type}'")
        return

    if cat_info['type'] == 'custom_single_file':
        # 单文件结构，检查文件是否存在
        print(f"【{info_type}】是单文件结构")
        if cat_info['path'].exists():
            print(f"✓ 文件存在: {cat_info['path'].name}")
        else:
            print(f"✗ 文件不存在")
        return

    print(f"检查 {len(names)} 个{info_type}:\n")
    for name in names:
        file_path = cat_info['path'] / f"{name}.md"
        if file_path.exists():
            print(f"✓ {name}")
        else:
            print(f"✗ {name} (不存在)")


def show_brief(info_type: str, names: list):
    """显示指定条目的元数据"""
    cat_info = get_category_info(info_type)

    if not cat_info:
        print(f"错误: 未找到分类 '{info_type}'")
        return

    if cat_info['type'] == 'custom_single_file':
        # 单文件结构
        file_path = cat_info['path']
        if not file_path.exists():
            print(f"✗ 未找到: {info_type}")
            return

        try:
            content = file_path.read_text(encoding='utf-8')
            yaml_content = extract_yaml_frontmatter(content)

            print(f"=== {info_type} (单文件) ===")
            if yaml_content:
                print(yaml_content)
            else:
                print("(无 YAML 元数据)")
        except Exception as e:
            print(f"✗ 读取时出错: {e}")
        return

    # 目录结构
    for idx, name in enumerate(names):
        file_path = cat_info['path'] / f"{name}.md"

        if not file_path.exists():
            print(f"✗ 未找到: {name}")
            if idx < len(names) - 1:
                print()
            continue

        try:
            content = file_path.read_text(encoding='utf-8')
            yaml_content = extract_yaml_frontmatter(content)

            print(f"=== {info_type}: {name} ===")
            if yaml_content:
                print(yaml_content)
            else:
                print("(无 YAML 元数据)")

            if idx < len(names) - 1:
                print()

        except Exception as e:
            print(f"✗ 读取 {name} 时出错: {e}")
            if idx < len(names) - 1:
                print()


def show_detail(info_type: str, names: list):
    """显示指定条目的完整信息"""
    cat_info = get_category_info(info_type)

    if not cat_info:
        print(f"错误: 未找到分类 '{info_type}'")
        return

    if cat_info['type'] == 'custom_single_file':
        # 单文件结构
        file_path = cat_info['path']
        if not file_path.exists():
            print(f"✗ 未找到: {info_type}")
            return

        try:
            content = file_path.read_text(encoding='utf-8')
            print("=" * 80)
            print(f"{info_type} (单文件)")
            print("=" * 80)
            print(content)
        except Exception as e:
            print(f"✗ 读取时出错: {e}")
        return

    # 目录结构
    for idx, name in enumerate(names):
        file_path = cat_info['path'] / f"{name}.md"

        if not file_path.exists():
            print(f"✗ 未找到: {name}")
            if idx < len(names) - 1:
                print("=" * 80)
                print()
            continue

        try:
            content = file_path.read_text(encoding='utf-8')

            print("=" * 80)
            print(f"{info_type}: {name}")
            print("=" * 80)
            print(content)

            if idx < len(names) - 1:
                print()
                print("=" * 80)
                print()

        except Exception as e:
            print(f"✗ 读取 {name} 时出错: {e}")
            if idx < len(names) - 1:
                print("=" * 80)
                print()


def main():
    if len(sys.argv) < 2:
        print("用法: uv run list_info.py <类型|--all> [名称...] [--brief|--detail]")
        print()
        print("参数:")
        print(f"  类型: {', '.join(STANDARD_TYPES)}（标准分类）或自定义分类名称")
        print("  名称: (可选) 要查看的条目名称")
        print()
        print("选项:")
        print("  --all: 列出所有分类概览（标准 + 自定义）")
        print("  --brief: 显示 YAML 元数据（仅在指定名称时可用）")
        print("  --detail: 显示完整信息（仅在指定名称时可用）")
        print()
        print("示例:")
        print("  uv run list_info.py --all                      # 显示所有分类概览")
        print("  uv run list_info.py 角色                       # 列出所有角色文件名")
        print("  uv run list_info.py 系统数据                   # 列出自定义分类下的文件")
        print("  uv run list_info.py 角色 张三 --brief          # 显示张三的元数据")
        print("  uv run list_info.py 系统数据 技能树 --detail   # 显示技能树的完整信息")
        sys.exit(1)

    # 处理 --all 选项
    if sys.argv[1] == '--all':
        list_all_types()
        return

    info_type = sys.argv[1]

    # 检查类型是否有效
    cat_info = get_category_info(info_type)
    if not cat_info:
        valid_types = get_all_types()
        print(f"错误: 无效的类型 '{info_type}'")
        print(f"标准分类: {', '.join(STANDARD_TYPES)}")
        custom = parse_info_structure()
        if custom:
            print(f"自定义分类: {', '.join(custom.keys())}")
        print("使用 --all 查看所有可用分类")
        sys.exit(1)

    # 解析参数
    args = sys.argv[2:]
    brief_mode = '--brief' in args
    detail_mode = '--detail' in args

    # 移除选项，剩下的是名称
    names = [arg for arg in args if arg not in ['--brief', '--detail']]

    # 如果同时指定了 --brief 和 --detail，报错
    if brief_mode and detail_mode:
        print("错误: 不能同时使用 --brief 和 --detail")
        sys.exit(1)

    # 单文件结构的特殊处理
    if cat_info['type'] == 'custom_single_file':
        if brief_mode:
            show_brief(info_type, [])
        elif detail_mode:
            show_detail(info_type, [])
        else:
            list_all_files(info_type)
        return

    # 如果使用了 --brief 或 --detail 但没有指定名称，报错
    if (brief_mode or detail_mode) and not names:
        print("错误: 使用 --brief 或 --detail 时必须指定具体名称")
        print()
        print("示例:")
        print(f"  uv run list_info.py {info_type} 张三 --brief")
        print(f"  uv run list_info.py {info_type} 张三 李四 --detail")
        sys.exit(1)

    # 根据模式执行
    if not names:
        # 没有指定名称，列出所有文件名
        list_all_files(info_type)
    elif detail_mode:
        # 显示完整信息
        show_detail(info_type, names)
    elif brief_mode:
        # 显示元数据
        show_brief(info_type, names)
    else:
        # 检查指定文件是否存在
        check_files_exist(info_type, names)


if __name__ == '__main__':
    main()
