from flask import render_template, flash, redirect, url_for, send_file
from flask_login import login_required, current_user
from scripts.models import db, WorkOrder, WorkOrderHandling, ManualWorkOrder
from datetime import datetime, timedelta
from collections import defaultdict
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment
from utils.reward import get_reward_by_distance
from scripts.models import Device
import io

def init_statistics_routes(app):
    @app.route('/statistics')
    @login_required
    def statistics():
        allowed_roles = ['装维员', '统计员', '管理员', 'admin']
        if current_user.role not in allowed_roles and current_user.name != 'Admin':
            app.logger.warning(f'未授权访问：用户 {current_user.name} 尝试访问统计页面')
            flash('您没有权限访问此页面')
            return redirect(url_for('login'))
        
        app.logger.info(f'用户 {current_user.name} 访问统计页面')
        # 获取当前时间
        now = datetime.now()
        
        # 计算本周开始和结束时间
        week_start = now - timedelta(days=now.weekday())
        week_start = week_start.replace(hour=0, minute=0, second=0, microsecond=0)
        week_end = week_start + timedelta(days=7)
        
        # 计算本月开始和结束时间
        month_start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
        if now.month == 12:
            month_end = now.replace(year=now.year + 1, month=1, day=1)
        else:
            month_end = now.replace(month=now.month + 1, day=1)

        # 统计普通工单
        def get_work_order_stats(start_time, end_time):
            total = WorkOrder.query.filter(
                WorkOrder.dispatch_time >= start_time,
                WorkOrder.dispatch_time < end_time
            ).count()
            
            completed = WorkOrder.query.filter(
                WorkOrder.dispatch_time >= start_time,
                WorkOrder.dispatch_time < end_time,
                WorkOrder.status == '已处理'
            ).count()
            
            pending = total - completed
            return {'total': total, 'completed': completed, 'pending': pending}

        # 统计手工故障单
        def get_manual_order_stats(start_time, end_time):
            total = ManualWorkOrder.query.filter(
                ManualWorkOrder.create_time >= start_time,
                ManualWorkOrder.create_time < end_time
            ).count()
            return total
            
        # 计算奖励金额
        def calculate_reward(start_time, end_time):
            rewards = defaultdict(float)
            
            # 查询所有已处理的工单
            handlings = WorkOrderHandling.query.filter(
                WorkOrderHandling.restore_time >= start_time,
                WorkOrderHandling.restore_time < end_time
            ).all()
            
            # 查询所有手工故障单
            manual_orders = ManualWorkOrder.query.filter(
                ManualWorkOrder.create_time >= start_time,
                ManualWorkOrder.create_time < end_time
            ).all()

            # 计算普通工单奖励
            for handling in handlings:
                device = Device.query.get(handling.device_id)
                if device:
                    distance = float(handling.distance_from_branch)
                    reward = get_reward_by_distance(device.project_type, distance)
                    rewards[device.project_type] += reward

            # 计算手工故障单奖励
            for order in manual_orders:
                distance = float(order.distance_from_branch)
                reward = get_reward_by_distance(order.project_type, distance)
                rewards[order.project_type] += reward

            return rewards

        def get_handler_stats(start_time, end_time):
            handler_stats = defaultdict(lambda: {
                'work_orders': 0,
                'manual_orders': 0,
                'rewards': defaultdict(float)
            })
            
            # 统计普通工单
            handlings = WorkOrderHandling.query.filter(
                WorkOrderHandling.restore_time >= start_time,
                WorkOrderHandling.restore_time < end_time
            ).all()
            
            for handling in handlings:
                handler = handling.handler
                handler_stats[handler]['work_orders'] += 1
                device = Device.query.get(handling.device_id)
                if device:
                    distance = float(handling.distance_from_branch)
                    reward = get_reward_by_distance(device.project_type, distance)
                    handler_stats[handler]['rewards'][device.project_type] += reward
            
            # 统计手工故障单
            manual_orders = ManualWorkOrder.query.filter(
                ManualWorkOrder.create_time >= start_time,
                ManualWorkOrder.create_time < end_time
            ).all()
            
            for order in manual_orders:
                handler = order.handler
                handler_stats[handler]['manual_orders'] += 1
                distance = float(order.distance_from_branch)
                reward = get_reward_by_distance(order.project_type, distance)
                handler_stats[handler]['rewards'][order.project_type] += reward
            
            return handler_stats

        # 获取统计数据
        week_work_stats = get_work_order_stats(week_start, week_end)
        month_work_stats = get_work_order_stats(month_start, month_end)
        
        week_manual_stats = get_manual_order_stats(week_start, week_end)
        month_manual_stats = get_manual_order_stats(month_start, month_end)
        
        week_rewards = calculate_reward(week_start, week_end)
        month_rewards = calculate_reward(month_start, month_end)

        week_handler_stats = get_handler_stats(week_start, week_end)
        month_handler_stats = get_handler_stats(month_start, month_end)
        
        # 如果是装维员，只显示自己的数据
        if current_user.role == '装维员':
            week_work_stats = {
                'completed': WorkOrderHandling.query.filter(
                    WorkOrderHandling.restore_time >= week_start,
                    WorkOrderHandling.restore_time < week_end,
                    WorkOrderHandling.handler == current_user.name
                ).count()
            }
            month_work_stats = {
                'completed': WorkOrderHandling.query.filter(
                    WorkOrderHandling.restore_time >= month_start,
                    WorkOrderHandling.restore_time < month_end,
                    WorkOrderHandling.handler == current_user.name
                ).count()
            }
            week_manual_stats = ManualWorkOrder.query.filter(
                ManualWorkOrder.create_time >= week_start,
                ManualWorkOrder.create_time < week_end,
                ManualWorkOrder.handler == current_user.name
            ).count()
            month_manual_stats = ManualWorkOrder.query.filter(
                ManualWorkOrder.create_time >= month_start,
                ManualWorkOrder.create_time < month_end,
                ManualWorkOrder.handler == current_user.name
            ).count()
            # 修改这里：只获取当前装维员的奖励统计
            week_rewards = calculate_reward(week_start, week_end)
            month_rewards = calculate_reward(month_start, month_end)
            week_handler_stats = {current_user.name: week_handler_stats.get(current_user.name, defaultdict(int))}
            month_handler_stats = {current_user.name: month_handler_stats.get(current_user.name, defaultdict(int))}
            
            # 从 handler_stats 中提取当前用户的奖励数据
            week_rewards = week_handler_stats[current_user.name]['rewards']
            month_rewards = month_handler_stats[current_user.name]['rewards']

        return render_template('statistics.html',
                             week_work_stats=week_work_stats,
                             month_work_stats=month_work_stats,
                             week_manual_stats=week_manual_stats,
                             month_manual_stats=month_manual_stats,
                             week_rewards=week_rewards,
                             month_rewards=month_rewards,
                             week_handler_stats=week_handler_stats,
                             month_handler_stats=month_handler_stats)
    @app.route('/export_monthly_stats/<int:year>/<int:month>')
    @login_required
    def export_monthly_stats(year, month):
        if current_user.role != '统计员':
            app.logger.warning(f'未授权访问：用户 {current_user.name} 尝试导出月度统计')
            flash('您没有权限执行此操作')
            return redirect(url_for('statistics'))
        
        app.logger.info(f'用户 {current_user.name} 导出 {year}年{month}月 统计报表')
        
        # 计算指定月份的开始和结束时间
        month_start = datetime(year, month, 1, 0, 0, 0)
        if month == 12:
            month_end = datetime(year + 1, 1, 1, 0, 0, 0)
        else:
            month_end = datetime(year, month + 1, 1, 0, 0, 0)
        
        # 检查是否有数据
        handlings = WorkOrderHandling.query.filter(
            WorkOrderHandling.restore_time >= month_start,
            WorkOrderHandling.restore_time < month_end
        ).first()
        
        if not handlings:
            flash(f'{year}年{month}月系统无检修工单')
            return redirect(url_for('statistics'))
        
        # 创建工作簿
        wb = Workbook()
        ws = wb.active
        ws.title = "运维计件奖励"
        
        # 设置标题
        ws.merge_cells('A1:J1')
        title = ws.cell(1, 1, f"{year}年{month}月政企重点项目运维各支局检修激励汇总")
        title.font = Font(size=14, bold=True)
        title.alignment = Alignment(horizontal='center')
        
        # 设置表头
        headers = ['序号', '检修单位名称', '检修项目', '检修设备总数（台）', 
                '单位距支局维护人员所在地址（公里）', '检修设备每个单价（元）', 
                '检修项目合计数（路）', '本月检修金额（元）', '支局', '检修人员','本月个人检修合计','检修时间']
        for col, header in enumerate(headers, 1):
            cell = ws.cell(2, col, header)
            cell.font = Font(bold=True)
            cell.alignment = Alignment(horizontal='center', wrap_text=True)
        
        # 获取指定月份数据
        handlings = WorkOrderHandling.query.filter(
            WorkOrderHandling.restore_time >= month_start,
            WorkOrderHandling.restore_time < month_end
        ).all()
        
        # 查询本月所有手工故障单
        manual_orders = ManualWorkOrder.query.filter(
            ManualWorkOrder.create_time >= month_start,
            ManualWorkOrder.create_time < month_end
        ).order_by(ManualWorkOrder.create_time).all()
        
        # 填充数据
        row = 3
        idx = 0  # 初始化序号计数器
        
        # 处理普通工单
        for handling in handlings:
            device = db.session.get(Device, handling.device_id)
            if not device:
                continue
                
            idx += 1  # 增加序号
            ws.cell(row, 1, idx)  # 序号
            ws.cell(row, 2, device.device_id)  # 检修单位名称
            ws.cell(row, 3, device.project_type)  # 检修项目
            ws.cell(row, 4, 1)  # 检修设备总数
            ws.cell(row, 5, handling.distance_from_branch)  # 距离
            
            # 计算单价
            distance = float(handling.distance_from_branch)
            reward = get_reward_by_distance(device.project_type, distance)
            ws.cell(row, 6, reward)  # 单价
            
            ws.cell(row, 7, 1)  # 检修项目合计数
            ws.cell(row, 8, reward)  # 本月检修金额
            ws.cell(row, 9, handling.branch)  # 支局
            ws.cell(row, 10, handling.handler)  # 检修人员
            ws.cell(row, 12, handling.restore_time.strftime('%Y-%m-%d %H:%M:%S'))            # 检修时间
            
            row += 1

        # 处理手工故障单
        for manual_order in manual_orders:
            idx += 1  # 增加序号
            ws.cell(row, 1, idx)  # 序号
            ws.cell(row, 2, manual_order.device_location)  # 检修单位名称
            ws.cell(row, 3, manual_order.project_type)  # 检修项目
            ws.cell(row, 4, 1)  # 检修设备总数
            ws.cell(row, 5, manual_order.distance_from_branch)  # 距离
            
            # 计算单价
            distance = float(manual_order.distance_from_branch)
            reward = get_reward_by_distance(manual_order.project_type, distance)
            ws.cell(row, 6, reward)  # 单价
            
            ws.cell(row, 7, 1)  # 检修项目合计数
            ws.cell(row, 8, reward)  # 本月检修金额
            ws.cell(row, 9, manual_order.branch)  # 支局
            ws.cell(row, 10, manual_order.handler)  # 检修人员
            ws.cell(row, 12, manual_order.create_time.strftime('%Y-%m-%d %H:%M:%S'))  # 检修时间
            
            row += 1
            idx += 1
        
        # 添加合计行
        ws.cell(row, 7, f"合计")
        ws.cell(row, 8, f"=SUM(H3:H{row-1})")
        ws.cell(row, 8).font = Font(bold=True)
        
        # 设置列宽
        ws.column_dimensions['B'].width = 20
        ws.column_dimensions['C'].width = 15
        ws.column_dimensions['E'].width = 15
        ws.column_dimensions['F'].width = 15
        ws.column_dimensions['H'].width = 15
        
        # 保存到内存中
        excel_file = io.BytesIO()
        wb.save(excel_file)
        excel_file.seek(0)
        
        # 设置文件名
        filename = f'{year}年{month}月政企重点项目运维各支局检修激励汇总.xlsx'
        
        return send_file(
            excel_file,
            mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            as_attachment=True,
            download_name=filename
        )
