import json
import mysql.connector
from mysql.connector import Error
from typing import Any, Dict, List, Sequence
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
from mcp.shared.exceptions import McpError
from datetime import datetime
import re
import decimal
import os
from dotenv import load_dotenv
# version = "0.8.15"
load_dotenv()

MYSQL_CONFIG = {
    'host': os.getenv('DB_HOST'),
    'port': int(os.getenv('DB_PORT', 3306)),  # 默认 3306
    'user': os.getenv('DB_USER'),
    'password': os.getenv('DB_PASSWORD'),
    'database': os.getenv('DB_NAME'),
    'charset': os.getenv('DB_CHARSET', 'utf8mb4'),
    'ssl_disabled': True,
}

def _convert_decimal(obj):
    if isinstance(obj, decimal.Decimal):
        return float(obj)  # 或 str(obj) 如果你希望保留精度
    elif isinstance(obj, dict):
        return {k: _convert_decimal(v) for k, v in obj.items()}
    elif isinstance(obj, list):
        return [_convert_decimal(item) for item in obj]
    else:
        return obj


def agro_product_search_recommend(product_chunks: List[Dict[str, Any]], user_preferences: Dict[str, str] = None) -> Dict[str, Any]:
    connection = None
    try:
        connection = mysql.connector.connect(**MYSQL_CONFIG)
        cursor = connection.cursor(dictionary=True)

        final_result = {}

        for chunk in product_chunks:
            prod_id = chunk.get("PID")
            name = chunk.get("PN")
            skus = []
            for sku in chunk.get("SKU"):
                sku_id = int(sku.get("商品ID"))
                cursor.execute("""
                    SELECT price, stocks, prod_date 
                    FROM ls_sku 
                    WHERE sku_id = %s AND status = 1  -- 只查询正常状态的 SKU
                """, (sku_id,))

                result = cursor.fetchone()
                skus.append({
                    "sku_id": sku_id,
                    "spec": sku.get("包装规格"),
                    "price": result["price"] if result else None,
                    "stock": result["stocks"] if result else None,
                    "prod_date": result["prod_date"] if result else None})

            final_result[prod_id] = {
                "prod_id": prod_id,
                "prod_name": name,
                "skus": skus
            }

        results = _convert_decimal(final_result)
        return {"message": "Success", "data": results}

    except Exception as e:
        return {"message": "Error", "error": str(e)}
    finally:
        if connection and connection.is_connected():
            cursor.close()
            connection.close()

# ========== MCP Server ==========
async def serve() -> None:  
    server = Server("nbotbb-agro-mcp")
    @server.list_tools()
    async def list_tools() -> list[Tool]:
        return [
            Tool(
                name="agro_product_search_recommend",
                description="根据从知识库提取的结构化农资商品信息，查询库存与价格并推荐。",
                inputSchema={
                    "type": "object",
                    "properties": {
                        "product_chunks": {
                            "type": "array",
                            "description": "从知识库检索到的一个或多个商品数据块，每个块包含PID、PN、SKU表等信息。",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "PID": {"type": "string"},
                                    "PN": {"type": "string"},
                                    "SKU": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "商品ID": {"type": "string"},
                                                "包装规格": {"type": "string"},
                                                "价格": {"type": "integer"},
                                                "库存": {"type": "integer"},
                                                "生产日期": {"type": "string", "format": "date"}
                                            },
                                            "required": ["商品ID", "包装规格", "价格", "库存", "生产日期"],
                                            "additionalProperties": False
                                        }
                                    }
                                },
                                "required": ["PID", "PN", "SKU"],
                                "additionalProperties": False
                            }
                        },
                        "user_preferences": {
                            "type": "object",
                            "description": "用户偏好设置（仅当用户明确表达时提供）",
                            "properties": {
                                "price_preference": {
                                    "type": "string",
                                    "enum": ["cheapest", "balanced", "premium"]
                                },
                                "date_preference": {
                                    "type": "string",
                                    "enum": ["recent", "any"]
                                }
                            },
                            "required": [],
                            "additionalProperties": False
                        }
                    },
                    "required": ["product_chunks"],
                    "additionalProperties": False
                }
            )
    ]
            
            
    @server.call_tool()
    async def call_tool(name: str, arguments: dict) -> Sequence[TextContent]:
        try:
            if name == "agro_product_search_recommend":
                res = agro_product_search_recommend(
                    product_chunks=arguments["product_chunks"],
                    user_preferences=arguments.get("user_preferences")
                )
            else:
                raise ValueError(f"Unknown tool: {name}")

            return [TextContent(type="text", text=json.dumps(res, ensure_ascii=False))]

        except Exception as e:
            return [TextContent(type="text", text=json.dumps({"message": "Error", "error": str(e)}, ensure_ascii=False))]
            

    options = server.create_initialization_options()
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, options)