#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
MCP Server for Admin Page Generator
"""

import json
import os
from pathlib import Path
from typing import Any

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

from .generator import CodeGenerator


# 创建 MCP Server 实例
server = Server("admin-gen")

# 代码生成器实例
generator = None


def get_generator() -> CodeGenerator:
    """获取或创建代码生成器实例"""
    global generator
    if generator is None:
        generator = CodeGenerator()
    return generator


@server.list_tools()
async def list_tools() -> list[Tool]:
    """列出可用的工具"""
    return [
        Tool(
            name="generate_admin_page",
            description="根据字段配置生成 Vue 3 + Element Plus 后台管理页面代码（api.ts, options.ts, index.vue, form.vue）",
            inputSchema={
                "type": "object",
                "properties": {
                    "功能名称": {
                        "type": "string",
                        "description": "功能名称，如：员工请假登记"
                    },
                    "模块路径": {
                        "type": "string",
                        "description": "模块路径，如：hr/personLeaveApplication"
                    },
                    "权限前缀": {
                        "type": "string",
                        "description": "权限前缀，如：hr_personleaveapplication"
                    },
                    "输出目录": {
                        "type": "string",
                        "description": "输出目录，默认：src/views",
                        "default": "src/views"
                    },
                    "主表字段": {
                        "type": "array",
                        "description": "主表字段列表",
                        "items": {
                            "type": "object",
                            "properties": {
                                "label": {"type": "string", "description": "字段名称"},
                                "key": {"type": "string", "description": "字段标识"},
                                "type": {"type": "string", "description": "字段类型：input/textarea/select/date/datetime/number/upload"},
                                "required": {"type": "boolean", "description": "是否必填"},
                                "show": {"type": "boolean", "description": "是否显示"},
                                "alwaysHide": {"type": "boolean", "description": "是否始终隐藏"},
                                "smart": {"type": "boolean", "description": "是否智能搜索"},
                                "width": {"type": "string", "description": "列宽"},
                                "dict": {"type": "string", "description": "字典名称"}
                            },
                            "required": ["label", "key", "type"]
                        }
                    },
                    "子表配置": {
                        "type": "array",
                        "description": "子表配置列表（可选）",
                        "items": {
                            "type": "object",
                            "properties": {
                                "名称": {"type": "string", "description": "子表名称"},
                                "标识": {"type": "string", "description": "子表标识"},
                                "实体名称": {"type": "string", "description": "实体名称"},
                                "字段列表": {"type": "array", "description": "子表字段列表"}
                            }
                        }
                    },
                    "字典配置": {
                        "type": "array",
                        "description": "字典配置列表",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {"type": "string"},
                                "dict": {"type": "string"},
                                "import": {"type": "string"}
                            }
                        }
                    }
                },
                "required": ["功能名称", "模块路径", "主表字段"]
            }
        ),
        Tool(
            name="generate_from_config",
            description="从 JSON 配置文件生成后台管理页面代码",
            inputSchema={
                "type": "object",
                "properties": {
                    "config_path": {
                        "type": "string",
                        "description": "JSON 配置文件路径"
                    }
                },
                "required": ["config_path"]
            }
        ),
        Tool(
            name="generate_backend_code",
            description="根据字段配置生成 Spring Boot + MyBatis-Plus 后端接口代码（Entity, Controller, Service, ServiceImpl, Mapper, Mapper.xml），支持子表",
            inputSchema={
                "type": "object",
                "properties": {
                    "功能名称": {
                        "type": "string",
                        "description": "功能名称，如：合同批量签订"
                    },
                    "模块名称": {
                        "type": "string",
                        "description": "后端模块名称，如：hr（对应 worsoft-hr）"
                    },
                    "实体名称": {
                        "type": "string",
                        "description": "实体类名（PascalCase），如：ContractSignBatch"
                    },
                    "数据库表名": {
                        "type": "string",
                        "description": "数据库表名（下划线格式），如：contract_sign_batch"
                    },
                    "接口路径": {
                        "type": "string",
                        "description": "REST接口路径（camelCase），如：contractSignBatch"
                    },
                    "后端项目路径": {
                        "type": "string",
                        "description": "后端项目根目录路径，如：E:/vue3/worsoft5.3"
                    },
                    "主表字段": {
                        "type": "array",
                        "description": "主表字段列表",
                        "items": {
                            "type": "object",
                            "properties": {
                                "label": {"type": "string", "description": "字段描述，如：单据编号"},
                                "key": {"type": "string", "description": "字段名（camelCase），如：billCode"},
                                "javaType": {"type": "string", "description": "Java类型：String/Long/BigDecimal/LocalDate/LocalDateTime/Integer"},
                                "dict": {"type": "string", "description": "字典名称（可选），如：bill_state"}
                            },
                            "required": ["label", "key", "javaType"]
                        }
                    },
                    "子表配置": {
                        "type": "array",
                        "description": "子表配置列表（可选）",
                        "items": {
                            "type": "object",
                            "properties": {
                                "名称": {"type": "string", "description": "子表名称"},
                                "实体名称": {"type": "string", "description": "子表实体名（PascalCase），如：ContractSignBatchDetail"},
                                "数据库表名": {"type": "string", "description": "子表数据库表名"},
                                "字段名": {"type": "string", "description": "在主表Entity中的字段名，如：detailList"},
                                "字段列表": {
                                    "type": "array",
                                    "description": "子表字段列表",
                                    "items": {
                                        "type": "object",
                                        "properties": {
                                            "label": {"type": "string"},
                                            "key": {"type": "string"},
                                            "javaType": {"type": "string"},
                                            "dict": {"type": "string"}
                                        },
                                        "required": ["label", "key", "javaType"]
                                    }
                                }
                            }
                        }
                    }
                },
                "required": ["功能名称", "模块名称", "实体名称", "数据库表名", "主表字段"]
            }
        ),
        Tool(
            name="generate_fullstack",
            description="从一份统一的 JSON 配置同时生成前端（api.ts, options.ts, index.vue, form.vue）和后端（Entity, Controller, Service, ServiceImpl, Mapper, Mapper.xml）代码。字段类型自动映射，后端参数自动推导。",
            inputSchema={
                "type": "object",
                "properties": {
                    "config_path": {
                        "type": "string",
                        "description": "JSON 配置文件路径（与 generate_from_config 使用相同格式）"
                    },
                    "后端项目路径": {
                        "type": "string",
                        "description": "后端项目根目录路径，如：E:/vue3/worsoft5.3"
                    },
                    "前端输出目录": {
                        "type": "string",
                        "description": "前端输出目录，默认：src/views",
                        "default": "src/views"
                    }
                },
                "required": ["config_path"]
            }
        )
    ]


@server.call_tool()
async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
    """调用工具"""
    gen = get_generator()
    
    if name == "generate_admin_page":
        try:
            # 构建配置
            config = {
                "功能名称": arguments.get("功能名称", ""),
                "模块路径": arguments.get("模块路径", ""),
                "权限前缀": arguments.get("权限前缀", ""),
                "输出目录": arguments.get("输出目录", "src/views"),
                "主表字段": arguments.get("主表字段", []),
                "子表配置": arguments.get("子表配置", []),
                "字典配置": arguments.get("字典配置", [])
            }
            
            # 是否直接保存文件
            save_files = arguments.get("save_files", False)
            
            # 生成代码
            user_input = gen.config_to_prompt(config)
            result = gen.generate(user_input)
            
            # 解析生成的代码
            files = gen.parse_generated_code(result)
            
            if not files:
                return [TextContent(type="text", text=f"生成结果:\n{result}")]
            
            if save_files:
                # 直接保存到文件
                saved = gen.save_files(
                    files, 
                    config["输出目录"], 
                    config["模块路径"]
                )
                return [TextContent(
                    type="text",
                    text=f"✓ 成功生成 {len(files)} 个文件:\n" + "\n".join(f"  - {f}" for f in saved)
                )]
            else:
                # 返回代码内容，让 AI 决定如何处理
                output = f"## 生成了 {len(files)} 个文件\n\n"
                output += f"目标目录: `{config['输出目录']}/{config['模块路径']}/`\n\n"
                
                for filename, content in files.items():
                    lang = "typescript" if filename.endswith(".ts") else "vue"
                    output += f"### {filename}\n```{lang}\n{content}\n```\n\n"
                
                return [TextContent(type="text", text=output)]
                
        except Exception as e:
            return [TextContent(type="text", text=f"错误: {str(e)}")]
    
    elif name == "generate_from_config":
        try:
            config_path = arguments.get("config_path", "")
            save_files = arguments.get("save_files", True)  # 默认保存
            
            config = gen.load_config(config_path)
            user_input = gen.config_to_prompt(config)
            result = gen.generate(user_input)
            
            files = gen.parse_generated_code(result)
            
            if not files:
                return [TextContent(type="text", text=f"生成结果:\n{result}")]
            
            if save_files:
                saved = gen.save_files(
                    files,
                    config.get("输出目录", "src/views"),
                    config.get("模块路径", "generated")
                )
                return [TextContent(
                    type="text",
                    text=f"✓ 成功生成 {len(files)} 个文件:\n" + "\n".join(f"  - {f}" for f in saved)
                )]
            else:
                output = f"## 生成了 {len(files)} 个文件\n\n"
                for filename, content in files.items():
                    lang = "typescript" if filename.endswith(".ts") else "vue"
                    output += f"### {filename}\n```{lang}\n{content}\n```\n\n"
                return [TextContent(type="text", text=output)]
                
        except Exception as e:
            return [TextContent(type="text", text=f"错误: {str(e)}")]
    
    elif name == "generate_backend_code":
        try:
            config = {
                "功能名称": arguments.get("功能名称", ""),
                "模块名称": arguments.get("模块名称", ""),
                "实体名称": arguments.get("实体名称", ""),
                "数据库表名": arguments.get("数据库表名", ""),
                "接口路径": arguments.get("接口路径", arguments.get("实体名称", "")[0].lower() + arguments.get("实体名称", "")[1:] if arguments.get("实体名称") else ""),
                "后端项目路径": arguments.get("后端项目路径", ""),
                "主表字段": arguments.get("主表字段", []),
                "子表配置": arguments.get("子表配置", [])
            }

            save_files = arguments.get("save_files", False)
            backend_root = config.get("后端项目路径", "")

            # 生成后端代码
            user_input = gen.backend_config_to_prompt(config)
            result = gen.generate_backend(user_input, config)

            # 解析生成的代码
            files = gen.parse_backend_code(result)

            if not files:
                return [TextContent(type="text", text=f"生成结果:\n{result}")]

            if save_files and backend_root:
                saved = gen.save_backend_files(files, config, backend_root)
                return [TextContent(
                    type="text",
                    text=f"✓ 成功生成 {len(files)} 个后端文件:\n" + "\n".join(f"  - {f}" for f in saved)
                )]
            else:
                output = f"## 生成了 {len(files)} 个后端文件\n\n"
                if backend_root:
                    output += f"目标项目: `{backend_root}`\n"
                output += f"模块: `worsoft-{config['模块名称']}`\n\n"

                for filename, content in files.items():
                    lang = "xml" if filename.endswith(".xml") else "java"
                    output += f"### {filename}\n```{lang}\n{content}\n```\n\n"

                return [TextContent(type="text", text=output)]

        except Exception as e:
            return [TextContent(type="text", text=f"错误: {str(e)}")]

    elif name == "generate_fullstack":
        try:
            config_path = arguments.get("config_path", "")
            backend_root = arguments.get("后端项目路径", "")
            frontend_output = arguments.get("前端输出目录", "src/views")
            save_files = arguments.get("save_files", False)

            config = gen.load_config(config_path)
            results = gen.generate_fullstack(config, backend_root=backend_root)

            frontend_files = results.get("frontend", {})
            backend_files = results.get("backend", {})
            backend_config = results.get("backend_config", {})

            output = f"## 全栈代码生成完成\n\n"

            # 保存或输出前端
            if save_files and frontend_files:
                saved_fe = gen.save_files(
                    frontend_files,
                    config.get("输出目录", frontend_output),
                    config.get("模块路径", "generated")
                )
                output += f"### 前端（{len(frontend_files)} 个文件已保存）\n"
                for f in saved_fe:
                    output += f"  - {f}\n"
            else:
                output += f"### 前端（{len(frontend_files)} 个文件）\n\n"
                for filename, content in frontend_files.items():
                    lang = "typescript" if filename.endswith(".ts") else "vue"
                    output += f"#### {filename}\n```{lang}\n{content}\n```\n\n"

            # 保存或输出后端
            if save_files and backend_files and backend_root:
                saved_be = gen.save_backend_files(backend_files, backend_config, backend_root)
                output += f"\n### 后端（{len(backend_files)} 个文件已保存）\n"
                for f in saved_be:
                    output += f"  - {f}\n"
            else:
                output += f"\n### 后端（{len(backend_files)} 个文件）\n"
                output += f"推导信息: 模块=`{backend_config.get('模块名称')}`, 实体=`{backend_config.get('实体名称')}`, 表=`{backend_config.get('数据库表名')}`\n\n"
                for filename, content in backend_files.items():
                    lang = "xml" if filename.endswith(".xml") else "java"
                    output += f"#### {filename}\n```{lang}\n{content}\n```\n\n"

            return [TextContent(type="text", text=output)]

        except Exception as e:
            return [TextContent(type="text", text=f"错误: {str(e)}")]

    return [TextContent(type="text", text=f"未知工具: {name}")]


async def main():
    """运行 MCP Server"""
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, server.create_initialization_options())


if __name__ == "__main__":
    import asyncio
    asyncio.run(main())
