import datetime
import logging

import akshare as ak
import pandas as pd
import requests
from mcp.server.fastmcp import FastMCP

logging.basicConfig(level=logging.DEBUG)

# Create an MCP server
mcp = FastMCP("Akshare_Tools")


@mcp.tool(name="stock_cyq_em", description="筹码分布")
def stock_cyq_em(symbol: str = "601398", adjust: str = "qfq"):
    """
    筹码分布
    :param symbol: 股票代码
    :type symbol: str
    :param adjust: 复权选项，默认qfq(前复权)，可选bfq(不复权)/hfq(后复权)
    :type adjust: str
    :return: 筹码分布数据
    """
    stock_cyq_em_df = ak.stock_cyq_em(symbol=symbol, adjust=adjust)
    return stock_cyq_em_df


@mcp.tool(name="stock_fund_flow_individual", description="个股资金流向")
def stock_fund_flow_individual(symbol: str = "即时"):
    """
    个股资金流向
    :param symbol: 股票代码，默认为"即时"，也可以指定具体股票代码
    :type symbol: str
    :return: 个股资金流向数据
    """
    stock_fund_flow_individual_df = ak.stock_fund_flow_individual(symbol=symbol)
    return stock_fund_flow_individual_df


@mcp.tool(name="stock_fhps_em", description="分红推送")
def stock_fhps_em(date: str = "20231231"):
    """
    分红推送
    :param date: 日期，格式YYYYMMDD
    :type date: str
    :return: 分红推送数据
    """
    stock_fhps_em_df = ak.stock_fhps_em(date=date)
    return stock_fhps_em_df


@mcp.tool(name="stock_ggcg_em", description="现金流量表")
def stock_xjll_em(date: str = "20240331"):
    """
    现金流量表
    :param date: 报告期，格式YYYYMMDD
    :type date: str
    :return: 现金流量表数据
    """
    stock_xjll_em_df = ak.stock_xjll_em(date=date)
    return stock_xjll_em_df


@mcp.tool(name="stock_lrb_em", description="利润表")
def stock_lrb_em(date: str = "20240331"):
    """
    利润表
    :param date: 报告期，格式YYYYMMDD
    :type date: str
    :return: 利润表数据
    """
    stock_lrb_em_df = ak.stock_lrb_em(date=date)
    return stock_lrb_em_df


@mcp.tool(name="stock_zcfz_em", description="东方财富-资产负债表")
def stock_zcfz_em(symbol: str = "601398", date: str = "20240331"):
    """
    东方财富-资产负债表
    :param symbol: 股票代码
    :type symbol: str
    :param date: 报告期 YYYYMMDD格式
    :type date: str
    :return: 资产负债表
    """
    stock_zcfz_em_df = ak.stock_zcfz_em(symbol=symbol, date=date)
    return stock_zcfz_em_df


@mcp.tool(name="stock_yjbb_em", description="业绩报表")
def test_stock_yjbb_em():
    """
    业绩报表
    """
    stock_yjbb_em_df = ak.stock_yjbb_em(date="20220331")
    print(stock_yjbb_em_df)
    return stock_yjbb_em_df


@mcp.tool(name="stock_comment_detail_zhpj_lspf_em", description="个股历史评价")
def stock_comment_detail_zhpj_lspf_em(symbol: str = "600000"):
    """
    个股历史评价
    :param symbol: 股票代码
    :type symbol: str
    :return: 个股历史评价数据
    """
    df = ak.stock_comment_detail_zhpj_lspf_em(symbol=symbol)
    return df


@mcp.tool(name="stock_comment_detail_zlkp_jgcyd_em", description="个股机构参与度")
def stock_comment_detail_zlkp_jgcyd_em(symbol: str = "600000"):
    """
    个股机构参与度
    :param symbol: 股票代码
    :type symbol: str
    :return: 个股机构参与度数据
    """
    df = ak.stock_comment_detail_zlkp_jgcyd_em(symbol=symbol)
    return df


@mcp.tool(name="stock_comment_detail_scrd_focus_em", description="个股关注度")
def stock_comment_detail_scrd_focus_em(symbol: str = "601398"):
    """
    个股关注度
    :param symbol: 股票代码
    :type symbol: str
    :return: 用户关注指数数据
    """
    df = ak.stock_comment_detail_scrd_focus_em(symbol=symbol)
    return df


@mcp.tool(name="stock_zh_a_minute", description="分时数据")
def stock_zh_a_minute(symbol: str = 'sh600751', period: str = '1', adjust: str = 'qfq'):
    """
    分时数据
    :param symbol: 股票代码
    :type symbol: str
    :param period: 分时周期，可选1, 5, 15, 30, 60
    :type period: str
    :param adjust: 复权选项，默认qfq(前复权)，可选bfq(不复权)/hfq(后复权)
    :type adjust: str
    :return: 分时数据
    """
    df = ak.stock_zh_a_minute(symbol=symbol, period=period, adjust=adjust)
    df['Ticker'] = symbol
    return df


@mcp.tool(name="stock_comment_em_save", description="千股千评")
def stock_comment_em_save():
    """
    千股千评
    :return: 千股千评数据
    """
    df = ak.stock_comment_em()
    # df = df.drop(["SECURITY_CODE"], axis=1)  # 删除列 SECURITY_CODE
    return df


@mcp.tool(name="stock_value_em", description="估值分析")
def stock_value_em(symbol: str = "601398", trade_date: str = None):
    """
    估值分析
    :param symbol: 股票代码
    :type symbol: str
    :param trade_date: 交易日期，默认为当前日期
    :type trade_date: str
    :return: 估值分析数据
    """
    if trade_date is None:
        trade_date = datetime.datetime.now().strftime("%Y-%m-%d")
    stock_value_em_df = ak.stock_value_em(symbol=symbol, TRADE_DATE=trade_date)
    return stock_value_em_df


@mcp.tool(name="stock_zh_a_hist", description="日K数据")
def stock_zh_a_hist(symbol: str = "601398", period: str = 'daily', adjust: str = ''):
    """
    获取指定股票的日K数据
    :param symbol: 股票代码
    :type symbol: str
    :param period: 周期，可选'daily'(日线)/'weekly'(周线)/'monthly'(月线)
    :type period: str
    :param adjust: 复权选项，默认不复权，可选'qfq'(前复权)/'hfq'(后复权)
    :type adjust: str
    :return: 日K数据
    """
    stock_hfq_df = ak.stock_zh_a_hist(symbol=symbol, period=period, adjust=adjust)
    return stock_hfq_df


@mcp.tool(name="stock_zh_a_spot_em", description="单次返回所有沪深京 A 股上市公司的实时行情数据")
def stock_zh_a_spot_em():
    """
    单次返回所有沪深京 A 股上市公司的实时行情数据
    :return: A股实时行情数据
    """
    stock_zh_a_spot_em_df = ak.stock_zh_a_spot_em()
    return stock_zh_a_spot_em_df


@mcp.tool(name="stock_zh_valuation_comparison_em", description="估值比较")
def stock_zh_valuation_comparison_em(symbol: str = "SZ000895"):
    """
    估值比较
    :param symbol: 股票代码
    :type symbol: str
    :return: 估值比较数据
    """
    df = ak.stock_zh_valuation_comparison_em(symbol=symbol)
    return df


@mcp.tool(name="stock_zh_dupont_comparison_em", description="杜邦分析比较")
def stock_zh_dupont_comparison_em(symbol: str = "SZ000895"):
    """
    杜邦分析比较
    :param symbol: 股票代码
    :type symbol: str
    :return: 杜邦分析比较数据
    """
    df = ak.stock_zh_dupont_comparison_em(symbol=symbol)
    return df


@mcp.tool(name="stock_hsgt_hold_stock_em", description="个股排行")
def stock_hsgt_hold_stock_em(market: str = "沪股通", indicator: str = "5日排行"):
    """
    个股排行
    :param market: 市场类型，可选"沪股通"/"深股通"/"港股通"
    :type market: str
    :param indicator: 指标类型，可选"5日排行"/"10日排行"/"月排行"等
    :type indicator: str
    :return: 个股排行数据
    """
    df = ak.stock_hsgt_hold_stock_em(market=market, indicator=indicator)
    return df


@mcp.tool(name="stock_rank_cxg_ths", description="同花顺-创新高数据")
def stock_rank_cxg_ths(symbol: str = "创月新高"):
    """
    同花顺-创新高数据
    :param symbol: 类型选择: "创月新高", "半年新高", "一年新高", "历史新高"
    :type symbol: str
    :return: 创新高股票数据
    """
    df = ak.stock_rank_cxg_ths(symbol=symbol)
    return df


@mcp.tool(name="stock_hot_keyword_em", description="个股人气指数-关键词")
def stock_hot_keyword_em(symbol: str = "SZ000665"):
    """
    个股人气指数-关键词
    :param symbol: 股票代码
    :type symbol: str
    :return: 个股人气指数关键词数据
    """
    df = ak.stock_hot_keyword_em(symbol=symbol)
    return df


@mcp.tool(name="stock_zt_pool_em", description="涨停股池")
def stock_zt_pool_em(date: str = None):
    """
    涨停股池
    :param date: 日期，格式YYYYMMDD，默认为当前日期
    :type date: str
    :return: 涨停股池数据
    """
    if date is None:
        date = datetime.date.strftime(datetime.date.today(), "%Y%m%d")
    df = ak.stock_zt_pool_em(date=date)
    return df


@mcp.tool(name="stock_zt_pool_previous_em", description="昨日涨停股池")
def stock_zt_pool_previous_em(date: str = None):
    """
    昨日涨停股池
    :param date: 日期，格式YYYYMMDD，默认为当前日期
    :type date: str
    :return: 昨日涨停股池数据
    """
    if date is None:
        date = datetime.date.today().strftime("%Y%m%d")
    df = ak.stock_zt_pool_previous_em(date=date)
    return df


@mcp.tool(name="stock_news_em", description="个股新闻资讯")
def stock_news_em(symbol: str = "603777"):
    """
    个股新闻资讯
    """
    stock_news_em_df = ak.stock_news_em(symbol=symbol)
    return stock_news_em_df


@mcp.tool(
    name="stock_hot_rank_em",  # 工具名称：股票热度排名
    description="获取东方财富个股人气榜数据"  # 工具描述
)
def stock_hot_rank_em():
    """
    获取东方财富个股人气榜数据
    :return: 个股人气榜数据
    """
    return ak.stock_hot_rank_em()


@mcp.tool(
    name="stock_hot_rank_detail_realtime_em",
    description="东方财富-个股人气榜-实时变动"
)
def stock_hot_rank_detail_realtime_em(symbol: str = "000665"):
    # 如果symbol不带sz或sh前缀，则添加sz前缀
    if not symbol.lower().startswith("sz") and not symbol.lower().startswith("sh"):
        symbol = "SZ" + symbol
    return ak.stock_hot_rank_detail_realtime_em(symbol=symbol)


@mcp.tool(
    name="stock_hot_rank_latest_em",  # 工具名称：个股人气榜最新排名
    description="东方财富-个股人气榜-最新排名"  # 工具描述
)
def stock_hot_rank_latest_em(symbol: str = "000665"):
    # 如果symbol不带sz或sh前缀，则添加sz前缀
    if not symbol.lower().startswith("sz") and not symbol.lower().startswith("sh"):
        symbol = "SZ" + symbol
    return ak.stock_hot_rank_latest_em(symbol=symbol)


@mcp.tool(
    name="stock_daily_quote_list_em",  # 工具名称：今日个股行情列表
    description="获取东方财富今日个股行情列表"  # 工具描述
)
def stock_daily_quote_list_em(market_type: str = "A", sort_by: str = "f3", sort_order: int = 1):  # A股、HK港股、US美股
    """
    东方财富-今日个股行情列表
    :param market_type: 市场类型 A-沪深A股, HK-港股, US-美股
    :type market_type: str
    :param sort_by: 排序字段 f3-按涨跌幅, f4-按涨跌额, f2-按最新价
    :type sort_by: str
    :param sort_order: 排序顺序 1-降序(从高到低), 0-升序(从低到高)
    :type sort_order: int
    :return: 今日行情列表
    """
    if market_type == "A":
        # 沪深A股行情列表
        url = "https://push2.eastmoney.com/api/qt/clist/get"
        params = {
            "pn": "1",
            "pz": "20",  # 每页数量
            "po": sort_order,  # 排序顺序: 1-降序, 0-升序
            "np": "1",
            "ut": "bd1d8c7aad6651cde7cc9c055f43e8b1",
            "fltt": "2",
            "invt": "2",
            "fid": sort_by,  # 按指定字段排序
            "fs": "m:0+t:6+f:!2,m:0+t:13+f:!2,m:0+t:80+f:!2,m:1+t:2+f:!2,m:1+t:23+f:!2,m:0+t:7+f:!2,m:1+t:3+f:!2"
        }
    elif market_type == "HK":
        # 港股行情列表
        url = "https://push2.eastmoney.com/api/qt/clist/get"
        params = {
            "pn": "1",
            "pz": "20",
            "po": "1",
            "np": "1",
            "ut": "bd1d8c7aad6651cde7cc9c055f43e8b1",
            "fltt": "2",
            "invt": "2",
            "fid": "f3",
            "fs": "m:116"
        }
    elif market_type == "US":
        # 美股行情列表
        url = "https://push2.eastmoney.com/api/qt/clist/get"
        params = {
            "pn": "1",
            "pz": "20",
            "po": "1",
            "np": "1",
            "ut": "bd1d8c7aad6651cde7cc9c055f43e8b1",
            "fltt": "2",
            "invt": "2",
            "fid": "f3",
            "fs": "m:105,m:106,m:107"
        }
    else:
        # 默认A股
        url = "https://push2.eastmoney.com/api/qt/clist/get"
        params = {
            "pn": "1",
            "pz": "20",
            "po": "1",
            "np": "1",
            "ut": "bd1d8c7aad6651cde7cc9c055f43e8b1",
            "fltt": "2",
            "invt": "2",
            "fid": "f3",
            "fs": "m:0+t:6+f:!2,m:0+t:13+f:!2,m:0+t:80+f:!2,m:1+t:2+f:!2,m:1+t:23+f:!2,m:0+t:7+f:!2,m:1+t:3+f:!2"
        }

    r = requests.get(url, params=params)
    data_json = r.json()

    if data_json["data"] and "diff" in data_json["data"]:
        temp_df = pd.DataFrame(data_json["data"]["diff"])

        # 根据不同市场类型提取相应字段
        result_df = pd.DataFrame({
            "代码": temp_df["f12"],
            "名称": temp_df["f14"],
            "最新价": temp_df["f2"],
            "涨跌幅": temp_df["f3"],
            "涨跌额": temp_df["f4"],
            "成交量": temp_df["f5"],
            "成交额": temp_df["f6"],
            "振幅": temp_df["f7"],
            "最高": temp_df["f15"],
            "最低": temp_df["f16"],
            "今开": temp_df["f17"],
            "昨收": temp_df["f18"]
        })

        # 转换数值列
        numeric_columns = ["最新价", "涨跌幅", "涨跌额", "成交量", "成交额", "振幅", "最高", "最低", "今开", "昨收"]
        for col in numeric_columns:
            result_df[col] = pd.to_numeric(result_df[col], errors="coerce")

        return result_df
    else:
        return pd.DataFrame()


@mcp.tool(
    name="stock_daily_quote_em",  # 工具名称：今日个股行情
    description="获取东方财富今日个股行情数据"  # 工具描述
)
def stock_daily_quote_em(symbol: str = "000001"):
    """
    东方财富-今日个股行情
    :param symbol: 股票代码
    :type symbol: str
    :return: 个股行情数据
    """
    # 使用akshare获取个股历史数据（包含当日数据）
    df = ak.stock_zh_a_hist(symbol=symbol, period='daily', adjust='')
    
    if not df.empty:
        # 获取最新一天的数据
        latest_data = df.tail(1).copy()
        
        # 重命名列以匹配之前的格式
        result_df = pd.DataFrame({
            "代码": [symbol],
            "名称": [f"股票{symbol}"],  # 实际名称需要单独获取
            "最新价": [latest_data['收盘'].iloc[0]],
            "涨跌幅": [latest_data['涨跌幅'].iloc[0]],
            "涨跌额": [latest_data['涨跌额'].iloc[0]],
            "成交量": [latest_data['成交量'].iloc[0]],
            "成交额": [latest_data['成交额'].iloc[0]],
            "振幅": [latest_data['振幅'].iloc[0]],
            "最高": [latest_data['最高'].iloc[0]],
            "最低": [latest_data['最低'].iloc[0]],
            "今开": [latest_data['开盘'].iloc[0]],
            "昨收": [latest_data['收盘'].iloc[0] - latest_data['涨跌额'].iloc[0]]
        })
        
        return result_df
    else:
        return pd.DataFrame()

@mcp.tool(name="stock_balance_sheet_by_report_em", description="东方财富-按报告期-资产负债表")
def stock_balance_sheet_by_report_em(symbol: str = "SH600519"):
    """
    东方财富-按报告期-资产负债表
    :param symbol: 股票代码; 带市场标识 如SH600519
    :type symbol: str
    :return: 资产负债表-按报告期
    """
    df = ak.stock_balance_sheet_by_report_em(symbol=symbol)
    return df


def main():
    # Initialize and run the server
    mcp.run(transport="stdio")  # 使用标准输入输出流进行通信


if __name__ == "__main__":
    main()
