"""
数据可视化组件
"""
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSpinBox,
    QPushButton, QComboBox
)
from PyQt5.QtCore import Qt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from frontend.utils.api_client import APIClient

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

class VisualizationWidget(QWidget):
    """数据可视化界面"""
    
    def __init__(self, api_client: APIClient, parent=None):
        super().__init__(parent)
        self.api_client = api_client
        self.init_ui()
        self.load_ranking()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout()
        
        # 标题
        title = QLabel("积分排名可视化")
        title.setStyleSheet("font-size: 18px; font-weight: bold; margin: 10px;")
        layout.addWidget(title)
        
        # 控制栏
        control_layout = QHBoxLayout()
        
        control_layout.addWidget(QLabel("显示前"))
        self.top_n_spin = QSpinBox()
        self.top_n_spin.setRange(5, 50)
        self.top_n_spin.setValue(10)
        control_layout.addWidget(self.top_n_spin)
        
        control_layout.addWidget(QLabel("名"))
        
        self.chart_type_combo = QComboBox()
        self.chart_type_combo.addItems(["柱形图", "折线图"])
        control_layout.addWidget(self.chart_type_combo)
        
        self.refresh_btn = QPushButton("刷新")
        self.refresh_btn.clicked.connect(self.load_ranking)
        control_layout.addWidget(self.refresh_btn)
        
        control_layout.addStretch()
        layout.addLayout(control_layout)
        
        # 图表区域
        self.figure = Figure(figsize=(10, 6))
        self.canvas = FigureCanvas(self.figure)
        layout.addWidget(self.canvas)
        
        self.setLayout(layout)
    
    def load_ranking(self):
        """加载排名数据并绘制图表"""
        try:
            top_n = self.top_n_spin.value()
            data = self.api_client.get_ranking(top_n=top_n)
            
            if not data['rankings']:
                self.figure.clear()
                ax = self.figure.add_subplot(111)
                ax.text(0.5, 0.5, '暂无数据', ha='center', va='center', fontsize=16)
                self.canvas.draw()
                return
            
            rankings = data['rankings']
            names = [f"{r['name']}\n({r['student_id']})" for r in rankings]
            scores = [r['total_score'] for r in rankings]
            rollcall_counts = [r['random_rollcall_count'] for r in rankings]
            
            self.figure.clear()
            
            chart_type = self.chart_type_combo.currentText()
            
            if chart_type == "柱形图":
                # 创建双Y轴
                ax1 = self.figure.add_subplot(111)
                ax2 = ax1.twinx()
                
                # 绘制积分柱形图
                bars = ax1.bar(range(len(names)), scores, color='skyblue', alpha=0.7, label='总积分')
                ax1.set_xlabel('学生')
                ax1.set_ylabel('总积分', color='blue')
                ax1.set_xticks(range(len(names)))
                ax1.set_xticklabels(names, rotation=45, ha='right')
                ax1.tick_params(axis='y', labelcolor='blue')
                ax1.grid(True, alpha=0.3)
                
                # 绘制点名次数折线图
                line = ax2.plot(range(len(names)), rollcall_counts, 
                               color='red', marker='o', linewidth=2, label='随机点名次数')
                ax2.set_ylabel('随机点名次数', color='red')
                ax2.tick_params(axis='y', labelcolor='red')
                
                # 添加图例
                ax1.legend(loc='upper left')
                ax2.legend(loc='upper right')
                
                self.figure.suptitle(f'积分排名前{top_n}名（柱形图：积分，折线图：点名次数）', fontsize=14)
            
            else:  # 折线图
                ax = self.figure.add_subplot(111)
                
                # 绘制积分折线
                line1 = ax.plot(range(len(names)), scores, 
                               color='blue', marker='o', linewidth=2, label='总积分')
                ax.set_xlabel('学生')
                ax.set_ylabel('总积分', color='blue')
                ax.tick_params(axis='y', labelcolor='blue')
                ax.set_xticks(range(len(names)))
                ax.set_xticklabels(names, rotation=45, ha='right')
                
                # 创建第二个Y轴用于点名次数
                ax2 = ax.twinx()
                line2 = ax2.plot(range(len(names)), rollcall_counts,
                                color='red', marker='s', linewidth=2, label='随机点名次数')
                ax2.set_ylabel('随机点名次数', color='red')
                ax2.tick_params(axis='y', labelcolor='red')
                
                # 添加图例
                ax.legend(loc='upper left')
                ax2.legend(loc='upper right')
                ax.grid(True, alpha=0.3)
                
                self.figure.suptitle(f'积分排名前{top_n}名（折线图）', fontsize=14)
            
            self.figure.tight_layout()
            self.canvas.draw()
            
        except Exception as e:
            import traceback
            error_msg = f"加载排名数据失败: {str(e)}\n{traceback.format_exc()}"
            print(error_msg)
            self.figure.clear()
            ax = self.figure.add_subplot(111)
            ax.text(0.5, 0.5, f'加载失败\n{str(e)}', ha='center', va='center', fontsize=12)
            self.canvas.draw()

