#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
使用 qwen3-max 生成后台管理页面代码

用法:
    admin-gen --config fields/example.json
    admin-gen -i  # 交互模式
"""

import os
import sys
import re
import json
import argparse
import time
from pathlib import Path
from datetime import datetime

try:
    from openai import OpenAI
    import httpx
except ImportError:
    print("请先安装依赖库: pip install openai httpx")
    sys.exit(1)


class CodeGenerator:
    """代码生成器"""

    # 包内资源目录（pip install 后资源在包内）
    _PKG_DIR = Path(__file__).parent

    def __init__(self, api_key: str = None, base_dir: Path = None):
        self.api_key = api_key or os.getenv("DASHSCOPE_API_KEY", "")
        if not self.api_key:
            raise ValueError(
                "未配置 API Key。请通过以下任一方式提供:\n"
                "  1. 设置环境变量 DASHSCOPE_API_KEY\n"
                "  2. 实例化时传入 api_key 参数"
            )

        # 配置超时和重试
        self.client = OpenAI(
            api_key=self.api_key,
            base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
            timeout=httpx.Timeout(120.0, connect=30.0),
            max_retries=3
        )

        # 资源目录优先级: 显式指定 > 包内目录 > 当前工作目录
        if base_dir:
            self.base_dir = Path(base_dir)
        else:
            self.base_dir = self._PKG_DIR

        self.templates_dir = self.base_dir / "templates"
        self.commands_dir = self.base_dir / "commands"
        self.fields_dir = self.base_dir / "fields"

        # 如果包内目录不存在模板（开发模式可能出现），回退到上两级
        if not self.templates_dir.exists():
            fallback = self._PKG_DIR.parent.parent
            if (fallback / "templates").exists():
                self.templates_dir = fallback / "templates"
                self.commands_dir = fallback / "commands"
                self.fields_dir = fallback / "fields"
    
    # 前端 type → Java 类型映射
    TYPE_TO_JAVA = {
        "input": "String",
        "textarea": "String",
        "select": "String",
        "radio": "String",
        "date": "LocalDate",
        "datetime": "LocalDateTime",
        "number": "BigDecimal",
        "upload": "String",
    }

    # BaseEntity 已提供的字段，后端 Entity 无需再生成
    BASE_ENTITY_FIELDS = {
        "id", "version",
        "createUserId", "createUser", "createPosId", "createPos",
        "createDptId", "createDpt", "createOgnId", "createOgn",
        "createPsmFullId", "createPsmFullName",
        "updatePsmFullId", "updatePsmFullName",
        "createTime", "updateTime",
    }

    # 每个模块都有的固定字段，模板已包含，无需重复传给 AI
    STANDARD_ENTITY_FIELDS = {
        "billCode", "billStateId", "billState", "billDate",
        "tenantId", "finishedTime", "rowStatus",
    }

    @staticmethod
    def _camel_to_snake(name: str) -> str:
        """camelCase / PascalCase → snake_case"""
        import re as _re
        s = _re.sub(r'([A-Z])', r'_\1', name).lower().lstrip('_')
        return s

    def unified_config_to_backend(self, config: dict) -> dict:
        """从前端统一配置推导出后端配置"""
        module_path = config.get('模块路径', '')  # e.g. "hr/businessTrip"
        parts = module_path.split('/') if module_path else ['', '']
        module_name = parts[0]  # "hr"
        feature_name = parts[1] if len(parts) > 1 else ''  # "businessTrip"
        entity_name = feature_name[0].upper() + feature_name[1:] if feature_name else ''  # "BusinessTrip"
        table_name = self._camel_to_snake(feature_name)  # "business_trip"
        api_path = feature_name[0].lower() + feature_name[1:] if feature_name else ''  # "businessTrip"

        skip_fields = self.BASE_ENTITY_FIELDS | self.STANDARD_ENTITY_FIELDS

        # 转换主表字段
        master_fields_src = config.get('主表字段', config.get('字段列表', []))
        backend_fields = []
        for f in master_fields_src:
            key = f.get('key', '')
            if key in skip_fields:
                continue
            backend_fields.append({
                "label": f.get('label', ''),
                "key": key,
                "javaType": f.get('javaType', self.TYPE_TO_JAVA.get(f.get('type', 'input'), 'String')),
                "dict": f.get('dict', ''),
            })

        # 转换子表配置
        detail_configs_src = config.get('子表配置', [])
        backend_details = []
        for idx, detail in enumerate(detail_configs_src, 1):
            detail_entity = detail.get('实体名称', f'{entity_name}Detail')
            if not detail_entity.endswith('Entity'):
                pass  # 后端生成时会自动加 Entity 后缀
            detail_table = detail.get('数据库表名', self._camel_to_snake(detail_entity))
            detail_field_name = detail.get('字段名', detail.get('标识', 'detail') + 'List')

            detail_fields = []
            for f in detail.get('字段列表', []):
                key = f.get('key', '')
                if key in self.BASE_ENTITY_FIELDS | {"mainId", "tenantId", "rowStatus"}:
                    continue
                detail_fields.append({
                    "label": f.get('label', ''),
                    "key": key,
                    "javaType": f.get('javaType', self.TYPE_TO_JAVA.get(f.get('type', 'input'), 'String')),
                    "dict": f.get('dict', ''),
                })

            backend_details.append({
                "名称": detail.get('名称', f'子表{idx}'),
                "实体名称": detail_entity,
                "数据库表名": detail_table,
                "字段名": detail_field_name,
                "字段列表": detail_fields,
            })

        return {
            "功能名称": config.get('功能名称', ''),
            "模块名称": module_name,
            "实体名称": entity_name,
            "数据库表名": table_name,
            "接口路径": api_path,
            "主表字段": backend_fields,
            "子表配置": backend_details,
        }

    def generate_fullstack(self, config: dict, model: str = "qwen3-max", backend_root: str = "") -> dict:
        """从统一配置同时生成前端 + 后端代码"""
        results = {"frontend": {}, "backend": {}}

        # ---- 前端 ----
        print("\n===== 生成前端代码 =====")
        frontend_input = self.config_to_prompt(config)
        frontend_raw = self.generate(frontend_input, model)
        results["frontend"] = self.parse_generated_code(frontend_raw)
        print(f"  前端解析到 {len(results['frontend'])} 个文件")

        # ---- 后端 ----
        print("\n===== 生成后端代码 =====")
        backend_config = self.unified_config_to_backend(config)
        backend_input = self.backend_config_to_prompt(backend_config)
        backend_raw = self.generate_backend(backend_input, backend_config, model)
        results["backend"] = self.parse_backend_code(backend_raw)
        results["backend_config"] = backend_config
        print(f"  后端解析到 {len(results['backend'])} 个文件")

        return results

    def load_config(self, config_path: str) -> dict:
        """从 JSON 文件加载字段配置"""
        config_file = Path(config_path)
        
        # 如果是相对路径，从 fields 目录查找
        if not config_file.is_absolute() and not config_file.exists():
            config_file = self.fields_dir / config_path
        
        if not config_file.exists():
            raise FileNotFoundError(f"配置文件不存在: {config_file}")
        
        with open(config_file, "r", encoding="utf-8") as f:
            return json.load(f)
    
    def config_to_prompt(self, config: dict) -> str:
        """将配置转换为提示词格式"""
        prompt = f"""
## 需求信息

- 功能名称: {config.get('功能名称', '')}
- 模块路径: {config.get('模块路径', '')}
- 权限前缀: {config.get('权限前缀', '')}

## 主表字段列表 (dataMasterEntity)

| 字段名称 | 字段标识 | 类型 | 必填 | 显示 | 智能搜索 | 始终隐藏 | 列宽 | 字典 |
|---------|---------|------|-----|-----|---------|---------|------|-----|
"""
        # 兼容旧格式（字段列表）和新格式（主表字段）
        master_fields = config.get('主表字段', config.get('字段列表', []))
        for field in master_fields:
            prompt += f"| {field.get('label', '')} | {field.get('key', '')} | {field.get('type', 'input')} | {'是' if field.get('required') else '否'} | {'是' if field.get('show') else '否'} | {'是' if field.get('smart') else '否'} | {'是' if field.get('alwaysHide') else '否'} | {field.get('width', '100')} | {field.get('dict', '')} |\n"
        
        # 处理子表配置
        detail_configs = config.get('子表配置', [])
        if detail_configs:
            prompt += f"\n## 子表数量: {len(detail_configs)}\n"
            
            for idx, detail in enumerate(detail_configs, 1):
                entity_name = detail.get('实体名称', f'dataDetail{"" if idx == 1 else idx}Entity')
                prompt += f"\n### 子表{idx}: {detail.get('名称', '')} \n"
                prompt += f"- 标识: `{detail.get('标识', 'detail')}`\n"
                prompt += f"- 实体名称: `{entity_name}`\n"
                prompt += f"- dataForm中的字段: `{detail.get('标识', 'detail')}: []`\n\n"
                prompt += "| 字段名称 | 字段标识 | 类型 | 必填 | 显示 | 智能搜索 | 始终隐藏 | 列宽 | 字典 |\n"
                prompt += "|---------|---------|------|-----|-----|---------|---------|------|-----|\n"
                for field in detail.get('字段列表', []):
                    prompt += f"| {field.get('label', '')} | {field.get('key', '')} | {field.get('type', 'input')} | {'是' if field.get('required') else '否'} | {'是' if field.get('show') else '否'} | {'是' if field.get('smart') else '否'} | {'是' if field.get('alwaysHide') else '否'} | {field.get('width', '100')} | {field.get('dict', '')} |\n"
        
        if config.get('字典配置'):
            prompt += "\n## 字典配置\n\n"
            for d in config.get('字典配置', []):
                prompt += f"- 字段: {d.get('key')}, 字典名: {d.get('dict')}, 导入路径: {d.get('import', '/@/enums/dict')}\n"
        
        return prompt
    
    def read_template_files(self, mode: str = "frontend") -> dict:
        """读取模板文件，mode: frontend(前端) 或 backend(后端)"""
        templates = {}

        if not self.templates_dir.exists():
            print(f"警告: 模板目录不存在 - {self.templates_dir}")
            return templates

        if mode == "frontend":
            suffixes = [".ts", ".vue", ".js"]
        else:
            suffixes = [".java", ".xml"]

        for file in self.templates_dir.glob("*"):
            if file.is_file() and file.suffix in suffixes:
                templates[file.name] = file.read_text(encoding="utf-8")
                print(f"  已加载模板: {file.name}")

        return templates

    def read_prompt(self, mode: str = "frontend") -> str:
        """读取提示词文件，mode: frontend 或 backend"""
        if mode == "frontend":
            prompt_file = self.commands_dir / "admin-gen.md"
        else:
            prompt_file = self.commands_dir / "backend-gen.md"

        if not prompt_file.exists():
            print(f"警告: 提示词文件不存在 - {prompt_file}")
            return ""

        return prompt_file.read_text(encoding="utf-8")
    
    def build_system_prompt(self, templates: dict) -> str:
        """构建系统提示词"""
        prompt = self.read_prompt()
        prompt = prompt.replace("$ARGUMENTS", "")
        
        prompt += "\n\n---\n\n## 模板文件内容（请严格参考以下模板的代码风格和结构）\n\n"
        
        for name, content in templates.items():
            ext = Path(name).suffix
            lang = {"ts": "typescript", ".vue": "vue", ".js": "javascript"}.get(ext, "")
            prompt += f"### {name}\n```{lang}\n{content}\n```\n\n"
        
        prompt += """
---

## 输出要求

请根据用户提供的需求，生成以下 4 个文件的完整代码：

1. **api.ts** - API 接口文件
2. **options.ts** - 字段配置文件  
3. **index.vue** - 列表页文件
4. **form.vue** - 表单页文件

每个文件使用以下格式输出：

```文件类型:文件名
代码内容
```

例如：
```typescript:api.ts
// 代码内容
```

```vue:index.vue
// 代码内容
```
"""
        return prompt
    
    def generate_single_file(self, file_type: str, user_input: str, templates: dict, model: str = "qwen3-max", mode: str = "frontend") -> str:
        """生成单个文件"""
        prompt = self.read_prompt(mode)
        prompt = prompt.replace("$ARGUMENTS", "")

        # 只添加相关的模板
        if mode == "frontend":
            template_map = {
                "api.ts": ["api.ts"],
                "options.ts": ["options.ts"],
                "index.vue": ["index.vue", "options.ts"],
                "form.vue": ["form.vue", "options.ts"]
            }
            lang_map = {".ts": "typescript", ".vue": "vue"}
        else:
            template_map = {
                "Entity.java": ["Entity.java"],
                "DetailEntity.java": ["DetailEntity.java", "Entity.java"],
                "Controller.java": ["Controller.java", "Entity.java"],
                "Service.java": ["Service.java", "Entity.java"],
                "ServiceImpl.java": ["ServiceImpl.java", "Entity.java", "DetailEntity.java"],
                "Mapper.java": ["Mapper.java"],
                "Mapper.xml": ["Mapper.xml"],
                "DetailMapper.java": ["Mapper.java"],
                "DetailMapper.xml": ["Mapper.xml"]
            }
            lang_map = {".java": "java", ".xml": "xml"}

        related_templates = template_map.get(file_type, [])
        prompt += "\n\n---\n\n## 参考模板\n\n"

        for name in related_templates:
            if name in templates:
                ext = Path(name).suffix
                lang = lang_map.get(ext, "")
                prompt += f"### {name}\n```{lang}\n{templates[name]}\n```\n\n"

        if mode == "frontend":
            code_lang = "typescript" if file_type.endswith(".ts") else "vue"
        else:
            code_lang = "xml" if file_type.endswith(".xml") else "java"

        prompt += f"""
---

## 输出要求

请只生成 **{file_type}** 文件的完整代码。

直接输出代码，不要添加任何解释说明。使用以下格式：

```{code_lang}:{file_type}
// 完整代码
```
"""
        
        print(f"\n  生成 {file_type}...")
        
        completion = self.client.chat.completions.create(
            model=model,
            messages=[
                {"role": "system", "content": prompt},
                {"role": "user", "content": user_input}
            ],
            stream=True
        )
        
        result = ""
        for chunk in completion:
            content = chunk.choices[0].delta.content
            if content:
                result += content
        
        return result
    
    def generate(self, user_input: str, model: str = "qwen3-max") -> str:
        """调用 API 生成前端代码（分批生成每个文件）"""
        print("\n正在读取模板文件...")
        templates = self.read_template_files(mode="frontend")

        if not templates:
            raise ValueError("没有找到任何模板文件")

        print(f"\n正在调用 {model} 分批生成代码...")

        # 分批生成每个文件
        file_types = ["api.ts", "options.ts", "index.vue", "form.vue"]
        all_results = []

        for file_type in file_types:
            result = self.generate_single_file(file_type, user_input, templates, model, mode="frontend")
            all_results.append(result)
            print(f"    ✓ {file_type} 生成完成")

        return "\n\n".join(all_results)

    def backend_config_to_prompt(self, config: dict) -> str:
        """将后端配置转换为提示词格式"""
        prompt = f"""
## 需求信息

- 功能名称: {config.get('功能名称', '')}
- 模块名称: {config.get('模块名称', '')}
- 实体名称: {config.get('实体名称', '')}
- 数据库表名: {config.get('数据库表名', '')}
- 接口路径: {config.get('接口路径', '')}

## 主表字段列表

| 字段描述 | 字段名 | Java类型 | 字典 |
|---------|--------|---------|------|
"""
        master_fields = config.get('主表字段', [])
        for field in master_fields:
            prompt += f"| {field.get('label', '')} | {field.get('key', '')} | {field.get('javaType', 'String')} | {field.get('dict', '')} |\n"

        detail_configs = config.get('子表配置', [])
        if detail_configs:
            prompt += f"\n## 子表数量: {len(detail_configs)}\n"

            for idx, detail in enumerate(detail_configs, 1):
                prompt += f"\n### 子表{idx}: {detail.get('名称', '')}\n"
                prompt += f"- 实体名称: `{detail.get('实体名称', '')}`\n"
                prompt += f"- 数据库表名: `{detail.get('数据库表名', '')}`\n"
                prompt += f"- 字段名(主表中): `{detail.get('字段名', 'detailList')}`\n\n"
                prompt += "| 字段描述 | 字段名 | Java类型 | 字典 |\n"
                prompt += "|---------|--------|---------|------|\n"
                for field in detail.get('字段列表', []):
                    prompt += f"| {field.get('label', '')} | {field.get('key', '')} | {field.get('javaType', 'String')} | {field.get('dict', '')} |\n"

        return prompt

    def generate_backend(self, user_input: str, config: dict, model: str = "qwen3-max") -> str:
        """调用 API 生成后端代码（分批生成每个文件）"""
        print("\n正在读取后端模板文件...")
        templates = self.read_template_files(mode="backend")

        if not templates:
            raise ValueError("没有找到任何后端模板文件")

        print(f"\n正在调用 {model} 分批生成后端代码...")

        has_detail = bool(config.get('子表配置', []))

        # 确定需要生成的文件类型
        file_types = [
            "Entity.java",
            "Controller.java",
            "Service.java",
            "ServiceImpl.java",
            "Mapper.java",
            "Mapper.xml"
        ]
        if has_detail:
            file_types.extend([
                "DetailEntity.java",
                "DetailMapper.java",
                "DetailMapper.xml"
            ])

        all_results = []
        for file_type in file_types:
            result = self.generate_single_file(file_type, user_input, templates, model, mode="backend")
            all_results.append(result)
            print(f"    ✓ {file_type} 生成完成")

        return "\n\n".join(all_results)

    def parse_backend_code(self, content: str) -> dict:
        """解析生成的后端代码，提取各个文件"""
        files = {}

        # 匹配 ```java:文件名 或 ```xml:文件名 格式
        pattern = r'```(?:[\w]+:)?([\w.]+)\n(.*?)```'
        matches = re.findall(pattern, content, re.DOTALL)

        valid_suffixes = (".java", ".xml")
        for filename, code in matches:
            filename = filename.strip()
            if filename in ["java", "xml"]:
                continue
            if any(filename.endswith(s) for s in valid_suffixes):
                files[filename] = code.strip()

        # 备用解析：按关键字识别
        if not files:
            alt_pattern = r'```(?:java|xml)?\n(.*?)```'
            blocks = re.findall(alt_pattern, content, re.DOTALL)
            for block in blocks:
                block = block.strip()
                if "@TableName" in block and "mainId" not in block and "Entity.java" not in [k for k in files if "Detail" not in k]:
                    files["Entity.java"] = block
                elif "@TableName" in block and "mainId" in block:
                    files["DetailEntity.java"] = block
                elif "@RestController" in block:
                    files["Controller.java"] = block
                elif "interface" in block and "extends BaseService" in block:
                    files["Service.java"] = block
                elif "extends BaseServiceImpl" in block:
                    files["ServiceImpl.java"] = block
                elif "@Mapper" in block and "Detail" not in block:
                    files["Mapper.java"] = block
                elif "@Mapper" in block and "Detail" in block:
                    files["DetailMapper.java"] = block
                elif "<!DOCTYPE mapper" in block and "Detail" not in block:
                    files["Mapper.xml"] = block
                elif "<!DOCTYPE mapper" in block and "Detail" in block:
                    files["DetailMapper.xml"] = block

        return files

    def save_backend_files(self, files: dict, config: dict, backend_root: str):
        """保存后端生成的文件到对应目录结构"""
        module = config.get('模块名称', 'hr')
        entity_name = config.get('实体名称', 'Unknown')

        # 基础路径
        base = Path(backend_root)
        api_entity_dir = base / f"worsoft-{module}" / f"worsoft-{module}-api" / "src" / "main" / "java" / "com" / "worsoft" / "worsoft" / module / "entity"
        biz_base = base / f"worsoft-{module}" / f"worsoft-{module}-biz" / "src" / "main" / "java" / "com" / "worsoft" / "worsoft" / module
        controller_dir = biz_base / "controller"
        service_dir = biz_base / "service"
        service_impl_dir = biz_base / "service" / "impl"
        mapper_dir = biz_base / "mapper"
        mapper_xml_dir = base / f"worsoft-{module}" / f"worsoft-{module}-biz" / "src" / "main" / "resources" / "mapper"

        # 文件名到目录的映射
        file_dir_map = {
            "Entity.java": (api_entity_dir, f"{entity_name}Entity.java"),
            "DetailEntity.java": (api_entity_dir, f"{entity_name}DetailEntity.java"),
            "Controller.java": (controller_dir, f"{entity_name}Controller.java"),
            "Service.java": (service_dir, f"{entity_name}Service.java"),
            "ServiceImpl.java": (service_impl_dir, f"{entity_name}ServiceImpl.java"),
            "Mapper.java": (mapper_dir, f"{entity_name}Mapper.java"),
            "DetailMapper.java": (mapper_dir, f"{entity_name}DetailMapper.java"),
            "Mapper.xml": (mapper_xml_dir, f"{entity_name}Mapper.xml"),
            "DetailMapper.xml": (mapper_xml_dir, f"{entity_name}DetailMapper.xml"),
        }

        saved = []
        for template_name, content in files.items():
            if template_name in file_dir_map:
                target_dir, target_filename = file_dir_map[template_name]
                target_dir.mkdir(parents=True, exist_ok=True)
                file_path = target_dir / target_filename
                file_path.write_text(content, encoding="utf-8")
                saved.append(str(file_path))
                print(f"  ✓ {target_filename} -> {file_path}")
            else:
                # 文件名已经是实际名称（如 ContractSignBatchEntity.java）
                # 尝试根据后缀匹配目录
                for key, (d, _) in file_dir_map.items():
                    if template_name.endswith(key.replace("Entity.java", "").replace("Mapper.java", "") + key):
                        d.mkdir(parents=True, exist_ok=True)
                        file_path = d / template_name
                        file_path.write_text(content, encoding="utf-8")
                        saved.append(str(file_path))
                        print(f"  ✓ {template_name} -> {file_path}")
                        break

        return saved
    
    def parse_generated_code(self, content: str) -> dict:
        """解析生成的代码，提取各个文件"""
        files = {}
        
        # 匹配 ```类型:文件名 或 ```文件名 格式
        pattern = r'```(?:[\w]+:)?([\w.]+)\n(.*?)```'
        matches = re.findall(pattern, content, re.DOTALL)
        
        for filename, code in matches:
            # 清理文件名
            filename = filename.strip()
            if filename in ["typescript", "vue", "javascript", "ts", "js"]:
                continue
            
            # 确保是目标文件
            if filename in ["api.ts", "options.ts", "index.vue", "form.vue"]:
                files[filename] = code.strip()
        
        # 备用解析：按文件名关键字查找
        if len(files) < 4:
            # 尝试匹配更宽松的格式
            alt_pattern = r'```(?:typescript|vue|ts)?\n(.*?)```'
            blocks = re.findall(alt_pattern, content, re.DOTALL)
            
            for block in blocks:
                block = block.strip()
                if "fetchList" in block and "api.ts" not in files:
                    files["api.ts"] = block
                elif "dataMasterEntity" in block and "options.ts" not in files:
                    files["options.ts"] = block
                elif "DetailForm" in block and "<template>" in block and "index.vue" not in files:
                    files["index.vue"] = block
                elif "dataFormRef" in block and "<template>" in block and "form.vue" not in files:
                    files["form.vue"] = block
        
        return files
    
    def save_files(self, files: dict, output_dir: str, module_path: str):
        """保存生成的文件"""
        # 构建完整输出路径
        full_path = Path(output_dir) / module_path
        full_path.mkdir(parents=True, exist_ok=True)
        
        print(f"\n保存文件到: {full_path}")
        
        saved = []
        for filename, content in files.items():
            file_path = full_path / filename
            file_path.write_text(content, encoding="utf-8")
            saved.append(str(file_path))
            print(f"  ✓ {filename}")
        
        return saved


def interactive_mode(generator: CodeGenerator):
    """交互模式"""
    print("\n" + "=" * 50)
    print("后台管理页面代码生成器 (交互模式)")
    print("=" * 50)
    
    # 收集用户输入
    print("\n请输入以下信息：\n")
    
    name = input("功能名称 (如: 员工考勤记录): ").strip()
    module = input("模块路径 (如: hr/attendance): ").strip()
    
    print("\n请输入字段列表 (每行一个字段，格式: 字段名称|字段标识|类型|是否必填|是否显示)")
    print("类型可选: input, textarea, select, date, datetime, number, upload")
    print("示例: 员工姓名|employeeName|input|是|是")
    print("输入空行结束:\n")
    
    fields = []
    while True:
        line = input().strip()
        if not line:
            break
        fields.append(line)
    
    print("\n请输入字典配置 (每行一个，格式: 字段标识|字典名称)")
    print("示例: status|attendance_status")
    print("输入空行结束:\n")
    
    dicts = []
    while True:
        line = input().strip()
        if not line:
            break
        dicts.append(line)
    
    output = input("\n输出目录 (默认: src/views): ").strip() or "src/views"
    
    # 构建用户输入
    user_input = f"""
## 需求信息

- 功能名称: {name}
- 模块路径: {module}

## 字段列表

| 字段名称 | 字段标识 | 类型 | 必填 | 显示 |
|---------|---------|------|-----|-----|
"""
    
    for field in fields:
        parts = field.split("|")
        if len(parts) >= 5:
            user_input += f"| {parts[0]} | {parts[1]} | {parts[2]} | {parts[3]} | {parts[4]} |\n"
    
    if dicts:
        user_input += "\n## 字典配置\n\n"
        for d in dicts:
            parts = d.split("|")
            if len(parts) >= 2:
                user_input += f"- {parts[0]}: {parts[1]}\n"
    
    # 生成代码
    try:
        result = generator.generate(user_input)
        
        # 解析并保存
        files = generator.parse_generated_code(result)
        
        if files:
            print(f"\n成功解析 {len(files)} 个文件")
            generator.save_files(files, output, module)
            print("\n✓ 代码生成完成!")
        else:
            print("\n警告: 无法解析生成的代码，原始输出如下：")
            print("-" * 50)
            print(result)
            
            # 保存原始输出
            raw_file = Path(output) / module / "generated_raw.md"
            raw_file.parent.mkdir(parents=True, exist_ok=True)
            raw_file.write_text(result, encoding="utf-8")
            print(f"\n原始输出已保存到: {raw_file}")
            
    except Exception as e:
        print(f"\n错误: {e}")
        sys.exit(1)


def main():
    parser = argparse.ArgumentParser(
        description="使用 qwen3-max 生成后台管理页面代码",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  # 从 JSON 配置文件生成（推荐）
  python scripts/generate_code.py --config fields/example.json
  
  # 交互模式
  python scripts/generate_code.py -i
  
  # 命令行模式
  python scripts/generate_code.py --name "员工考勤" --module "hr/attendance"
        """
    )
    
    parser.add_argument("-i", "--interactive", action="store_true", help="交互模式")
    parser.add_argument("--config", "-c", help="JSON 配置文件路径 (如: fields/example.json)")
    parser.add_argument("--name", help="功能名称")
    parser.add_argument("--module", help="模块路径 (如: hr/attendance)")
    parser.add_argument("--fields", help="字段列表，用分号分隔")
    parser.add_argument("--input", help="从文件读取需求描述")
    parser.add_argument("--output", default="src/views", help="输出目录 (默认: src/views)")
    parser.add_argument("--model", default="qwen3-max", help="模型名称 (默认: qwen3-max)")
    parser.add_argument("--print-only", action="store_true", help="只打印生成结果，不保存文件")
    
    args = parser.parse_args()
    
    generator = CodeGenerator()
    
    # 交互模式
    if args.interactive:
        interactive_mode(generator)
        return
    
    # 从 JSON 配置文件读取（推荐方式）
    if args.config:
        try:
            config = generator.load_config(args.config)
            user_input = generator.config_to_prompt(config)
            module = config.get('模块路径', 'generated')
            output = config.get('输出目录', args.output)
        except Exception as e:
            print(f"错误: 加载配置文件失败 - {e}")
            sys.exit(1)
    
    # 从文件读取
    elif args.input:
        user_input = Path(args.input).read_text(encoding="utf-8")
        module = args.module or "generated"
        output = args.output
    
    # 命令行参数模式
    elif args.name and args.module:
        user_input = f"功能名称: {args.name}\n模块路径: {args.module}\n"
        if args.fields:
            user_input += f"字段列表:\n{args.fields.replace(';', chr(10))}"
        module = args.module
        output = args.output
    
    else:
        parser.print_help()
        print("\n提示: 使用 --config 指定配置文件，或使用 -i 进入交互模式")
        sys.exit(1)
    
    # 生成代码
    try:
        result = generator.generate(user_input, args.model)
        
        if args.print_only:
            print("\n" + "=" * 50)
            print("生成结果:")
            print("=" * 50)
            print(result)
        else:
            files = generator.parse_generated_code(result)
            if files:
                generator.save_files(files, output, module)
                print("\n✓ 代码生成完成!")
            else:
                print("\n生成结果:")
                print(result)
                
    except Exception as e:
        print(f"\n错误: {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
