import requests
import pandas as pd
import json
from datetime import datetime
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
matplotlib.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题


def get_fund_flow_data():
    """获取资金流向数据，包括板块和股票名称"""
    url = "https://push2delay.eastmoney.com/api/qt/clist/get"

    params = {
        'fid': 'f184',
        'po': '1',
        'pz': '50',
        'pn': '1',
        'np': '1',
        'fltt': '2',
        'invt': '2',
        'fields': 'f2,f3,f12,f13,f14,f62,f184,f225,f165,f263,f109,f175,f264,f160,f100,f124,f265,f1',
        'ut': 'b2884a393a59ad64002292a3e90d46a5',
        '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',
    }

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Referer': 'https://data.eastmoney.com/zjlx/list.html'
    }

    try:
        response = requests.get(url, params=params, headers=headers)
        data = json.loads(response.text)

        if 'data' not in data or 'diff' not in data['data']:
            raise Exception("未能获取到数据")

        items = data['data']['diff']

        parsed_data = []
        for idx, item in enumerate(items[:50]):
            # 获取每个板块的股票名称
            stock_names = item.get('f14', '')

            if isinstance(stock_names, str):
                stock_names = stock_names.split(';')  # 假设股票名称以分号分隔
            else:
                stock_names = []  # 如果 f62 为空或格式不正确，设置为空列表

            if not stock_names:
                continue

                # 确保涨停数是有效的数字，并且为正数
            limit_up_count = item.get('f165', 0)
            if not isinstance(limit_up_count, (int, float)) or limit_up_count < 0:
                limit_up_count = 0

            parsed_data.append({
                '板块': item.get('f100', '未知板块'),
                '涨停数': limit_up_count,  # 获取涨停股数，确保是非负数
            })

            # 确保至少有一些数据
        if not parsed_data:
            raise Exception("未能解析到有效的板块数据")

        return pd.DataFrame(parsed_data)

    except Exception as e:
        print(f"获取数据时发生错误: {str(e)}")
        return None


def create_pie_chart(data):
    """创建涨停股数的扇形图"""
    # 确保所有要绘制的值都是正数
    filtered_data = data[data['涨停数'] > 0].copy()

    # 如果没有正数值，给用户提示并返回
    if filtered_data.empty:
        print("没有找到正数的涨停股数，无法绘制饼图")
        return None

    # 获取前15个有效的板块的涨停股数
    filtered_data = filtered_data.sort_values('涨停数', ascending=False).head(15)
    sectors = filtered_data['板块'].tolist()
    pie_data = filtered_data['涨停数'].tolist()

    # 确保数据长度一致且非空
    if not sectors or not pie_data or len(sectors) != len(pie_data):
        print("数据不一致或为空，无法绘制饼图")
        return None

    # 打印一下要绘制的数据，用于调试
    print("要绘制的数据:")
    for i, (sector, value) in enumerate(zip(sectors, pie_data)):
        print(f"{i + 1}. {sector}: {value}")

    root = tk.Tk()
    root.title("前15板块涨停股数占比")
    root.geometry("800x600")
    root.configure(bg='#2C3E50')  # 深色背景

    # 创建Matplotlib图形
    fig = plt.Figure(figsize=(8, 6), facecolor='#FFFFFF')
    ax = fig.add_subplot(111)

    # 设置图形背景颜色
    ax.set_facecolor('#2C3E50')

    # 绘制扇形图
    wedges, texts, autotexts = ax.pie(
        pie_data,
        labels=sectors,
        autopct='%1.1f%%',
        startangle=140,
        colors=plt.cm.Paired.colors,  # 使用配色方案
        wedgeprops={'edgecolor': 'black', 'linewidth': 0.5}  # 设置扇形边框
    )

    # 设置标题
    ax.set_title('前15板块涨停股数占比', fontsize=16, color='black', pad=20)

    # 设置标签样式
    for text in texts:
        text.set_fontsize(10)
        text.set_color('black')

    for autotext in autotexts:
        autotext.set_fontsize(10)
        autotext.set_color('black')

        # 设置图例
    ax.legend(wedges, sectors, title="板块", loc="upper left", fontsize=10, bbox_to_anchor=(1, 1))

    # 将图形添加到Tkinter窗口
    canvas = FigureCanvasTkAgg(fig, master=root)
    canvas.draw()
    canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)

    # 添加关闭按钮
    close_button = tk.Button(root, text="关闭", command=root.quit, font=('SimHei', 12), bg='#C82423', fg='white',
                             padx=10, pady=5)
    close_button.pack(side=tk.BOTTOM, pady=10)

    # 启动Tkinter主循环
    root.mainloop()

    return root


def main():
    # 获取资金流向数据
    print("正在获取资金流向数据...")
    data = get_fund_flow_data()

    if data is not None:
        # 保存数据到Excel
        current_date = datetime.now().strftime('%Y%m%d')
        output_file = f'fund_flow_ranking_{current_date}.xlsx'
        data.to_excel(output_file, index=False)
        print(f"资金流向数据已保存到: {output_file}")

        # 检查数据是否包含有效的涨停数
        if data['涨停数'].max() <= 0:
            print("警告: 没有找到正的涨停数据，无法绘制饼图")
        else:
            # 创建并显示扇形图
            print("正在创建扇形图...")
            create_pie_chart(data)
    else:
        print("获取数据失败，请检查网络连接或接口可用性。")


if __name__ == "__main__":
    main()