"""
日报求和数据采集与管理
"""
import json
import os
from datetime import datetime
from lib.db import execute_query, execute_update, execute_insert
from lib.field_mapping import get_field_display_name
from lib.logger import log_info, log_error, log_warning


def collect_sum_data_from_history(history_id=None, start_date=None, end_date=None):
    """
    从历史记录中采集求和数据并写入求和数据表
    充电电量（charge_degree）是必须采集的，其他求和字段有就采集，没有就不采集
    
    Args:
        history_id: 历史记录ID（可选，不填则采集所有成功的历史记录）
        start_date: 开始日期（可选，格式 YYYY-MM-DD）
        end_date: 结束日期（可选，格式 YYYY-MM-DD）
    
    Returns:
        dict: 采集结果
    """
    try:
        # 查询历史记录
        if history_id:
            history_list = execute_query(
                'SELECT * FROM t_daily_report_history WHERE id = %s AND status = 1',
                (history_id,)
            )
        else:
            where_clauses = ['status = 1']
            params = []
            if start_date:
                where_clauses.append('report_date >= %s')
                params.append(start_date)
            if end_date:
                where_clauses.append('report_date <= %s')
                params.append(end_date)
            where_sql = ' AND '.join(where_clauses)
            history_list = execute_query(
                f'SELECT * FROM t_daily_report_history WHERE {where_sql} ORDER BY create_time DESC',
                tuple(params)
            )
        
        if not history_list:
            return {'success': False, 'message': '没有找到符合条件的历史记录'}
        
        collected_count = 0
        skipped_count = 0
        config_cache = {}  # 缓存配置的排序号和自定义服务费单价
        
        # 获取全局配置的求和数据采集字段
        sum_data_fields = None
        try:
            global_config_result = execute_query(
                'SELECT sum_data_fields FROM t_daily_report_global_config WHERE id = 1 LIMIT 1'
            )
            if global_config_result and global_config_result[0].get('sum_data_fields'):
                sum_data_fields = json.loads(global_config_result[0]['sum_data_fields'])
        except Exception:
            pass
        
        for history in history_list:
            sum_results = history.get('sum_results')
            
            # 解析 sum_results JSON
            if isinstance(sum_results, str):
                sum_results = json.loads(sum_results) if sum_results else {}
            elif sum_results is None:
                sum_results = {}
            
            # 获取配置信息（排序号、自定义服务费单价）（缓存）
            config_id = history.get('config_id')
            sort_order = None
            custom_service_fee_price = None
            if config_id:
                if config_id in config_cache:
                    sort_order = config_cache[config_id].get('sort_order')
                    custom_service_fee_price = config_cache[config_id].get('custom_service_fee_price')
                    custom_service_fee_name = config_cache[config_id].get('custom_service_fee_name')
                else:
                    try:
                        cfg_result = execute_query(
                            'SELECT sort_order, custom_service_fee_price, custom_service_fee_name FROM t_daily_report_config WHERE id = %s LIMIT 1',
                            (config_id,)
                        )
                        if cfg_result:
                            sort_order = cfg_result[0].get('sort_order')
                            custom_service_fee_price = cfg_result[0].get('custom_service_fee_price')
                            custom_service_fee_name = cfg_result[0].get('custom_service_fee_name')
                        config_cache[config_id] = {
                            'sort_order': sort_order,
                            'custom_service_fee_price': custom_service_fee_price,
                            'custom_service_fee_name': custom_service_fee_name
                        }
                    except Exception:
                        config_cache[config_id] = {
                            'sort_order': None,
                            'custom_service_fee_price': None,
                            'custom_service_fee_name': None
                        }
            
            # 强制确保有充电电量（charge_degree）
            if 'charge_degree' not in sum_results or sum_results['charge_degree'] is None:
                # 从订单表重新计算充电电量
                try:
                    charge_degree = _calculate_charge_degree(history)
                    if charge_degree is not None:
                        sum_results['charge_degree'] = charge_degree
                        log_info(f"[采集] 历史记录 {history['id']} 补充计算充电电量: {charge_degree} kWh", 'sum_data')
                except Exception as calc_error:
                    log_error(f"[采集] 历史记录 {history['id']} 计算充电电量失败: {calc_error}", 'sum_data')
            
            # 如果还是没有任何求和数据，跳过
            if not sum_results:
                skipped_count += 1
                continue
            
            # 先删除该历史记录对应的旧数据（避免重复）
            execute_update(
                '''DELETE FROM t_daily_report_sum_data 
                   WHERE report_date = %s AND config_id = %s AND split_value = %s AND data_source = 'auto'
                ''',
                (history['report_date'], history['config_id'], history['split_value'])
            )
            
            # 根据配置过滤采集字段
            # 如果配置了 sum_data_fields，则只采集这些字段（charge_degree 始终采集）
            if sum_data_fields and isinstance(sum_data_fields, list):
                filtered_fields = set(sum_data_fields)
                filtered_fields.add('charge_degree')  # 充电电量始终采集
                sum_results = {k: v for k, v in sum_results.items() if k in filtered_fields}
            
            # 收集所有待插入的数据
            batch_params = []
            
            # 收集求和字段数据
            for field_key, field_value in sum_results.items():
                sum_data_id = int(datetime.now().timestamp() * 1000000) + collected_count + len(batch_params)
                batch_params.append((
                    sum_data_id,
                    history['report_date'],
                    history['config_id'],
                    history.get('config_name', ''),
                    history.get('split_type', ''),
                    history.get('split_value', ''),
                    history.get('split_name', ''),
                    field_key,
                    get_field_display_name(field_key),
                    float(field_value) if field_value is not None else 0,
                    history.get('total_orders', 0),
                    sort_order,
                    'auto',
                    f'从历史记录自动采集，历史ID: {history["id"]}'
                ))
            
            # 如果配置了自定义服务费单价，自动计算并采集自定义服务费
            custom_service_fee = None
            if custom_service_fee_price is not None and custom_service_fee_price != '' and sum_results.get('charge_degree') is not None:
                try:
                    charge_degree = float(sum_results['charge_degree'])
                    custom_service_fee = round(charge_degree * float(custom_service_fee_price), 2)
                    if custom_service_fee_name and str(custom_service_fee_name).strip():
                        fee_display_name = str(custom_service_fee_name).strip()
                    else:
                        fee_display_name = f'自定义服务费({custom_service_fee_price}元/kWh)'
                    sum_data_id = int(datetime.now().timestamp() * 1000000) + collected_count + len(batch_params)
                    batch_params.append((
                        sum_data_id,
                        history['report_date'],
                        history['config_id'],
                        history.get('config_name', ''),
                        history.get('split_type', ''),
                        history.get('split_value', ''),
                        history.get('split_name', ''),
                        'custom_service_fee',
                        fee_display_name,
                        custom_service_fee,
                        history.get('total_orders', 0),
                        sort_order,
                        'auto',
                        f'自动计算：充电电量{charge_degree}kWh × 单价{custom_service_fee_price}元/kWh'
                    ))
                except Exception as fee_error:
                    log_warning(f"[采集] 历史记录 {history['id']} 自定义服务费计算失败: {fee_error}", 'sum_data')
            
            # 计算自定义实收总金额（实收电费 + 自定义服务费）
            if custom_service_fee is not None:
                try:
                    charge_elecfee_amount = float(sum_results.get('charge_elecfee_amount', 0) or 0)
                    custom_total_amount = round(charge_elecfee_amount + custom_service_fee, 2)
                    sum_data_id = int(datetime.now().timestamp() * 1000000) + collected_count + len(batch_params)
                    batch_params.append((
                        sum_data_id,
                        history['report_date'],
                        history['config_id'],
                        history.get('config_name', ''),
                        history.get('split_type', ''),
                        history.get('split_value', ''),
                        history.get('split_name', ''),
                        'custom_total_amount',
                        '自定义实收总金额',
                        custom_total_amount,
                        history.get('total_orders', 0),
                        sort_order,
                        'auto',
                        f'自动计算：实收电费{charge_elecfee_amount}元 + 自定义服务费{custom_service_fee}元'
                    ))
                except Exception as total_error:
                    log_warning(f"[采集] 历史记录 {history['id']} 自定义实收总金额计算失败: {total_error}", 'sum_data')
            
            # 批量插入所有数据（Doris 优化）
            if batch_params:
                sql = '''
                    INSERT INTO t_daily_report_sum_data
                    (id, report_date, config_id, config_name, split_type, split_value, split_name,
                     sum_field_key, sum_field_name, sum_value, total_orders, sort_order, data_source, remark, 
                     create_time, update_time)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
                '''
                from lib.db import execute_batch_insert
                inserted = execute_batch_insert(sql, batch_params, batch_size=50)
                collected_count += inserted
        
        log_info(f'[采集] 采集完成，共采集 {collected_count} 条求和数据，跳过 {skipped_count} 条无求和数据的记录', 'sum_data')
        return {
            'success': True,
            'message': f'采集完成，共采集 {collected_count} 条求和数据，跳过 {skipped_count} 条无求和数据的记录'
        }
    except Exception as e:
        log_error(f'[采集] 采集失败: {e}', 'sum_data')
        return {'success': False, 'message': f'采集失败: {str(e)}'}


def _calculate_charge_degree(history):
    """
    从订单表中计算指定历史记录对应的充电电量总和
    
    Args:
        history: 历史记录字典
    
    Returns:
        float: 充电电量总和（保留三位小数），失败返回 None
    """
    try:
        split_type = history.get('split_type', '')
        split_value = history.get('split_value', '')
        start_time = history.get('start_time', '')
        end_time = history.get('end_time', '')
        
        if not split_type or not split_value or not start_time or not end_time:
            return None
        
        # 检查是否为多选值（逗号分隔）
        split_values = [v.strip() for v in str(split_value).split(',') if v.strip()]
        
        if len(split_values) > 1:
            placeholders = ', '.join(['%s'] * len(split_values))
            sql = f"""
                SELECT SUM(charge_degree) as total_degree
                FROM t_equipment_charge_order
                WHERE state = 3
                AND report_time >= %s
                AND report_time < %s
                AND {split_type} IN ({placeholders})
            """
            params = [start_time, end_time] + split_values
        else:
            sql = f"""
                SELECT SUM(charge_degree) as total_degree
                FROM t_equipment_charge_order
                WHERE state = 3
                AND report_time >= %s
                AND report_time < %s
                AND {split_type} = %s
            """
            params = [start_time, end_time, split_value]
        
        result = execute_query(sql, tuple(params))
        if result and result[0].get('total_degree') is not None:
            return round(float(result[0]['total_degree']), 3)
        
        return 0.0
    except Exception as e:
        log_error(f"[计算充电电量] 失败: {e}", 'sum_data')
        return None


def get_sum_data_list(page=None, page_size=20, start_date=None, end_date=None, config_id=None,
                       config_name=None, sum_field_key=None, data_source=None, skip_count=False):
    """
    查询求和数据列表
    
    Args:
        page: 页码（None表示不分页，返回所有数据）
        page_size: 每页大小
        start_date: 开始日期（可选）
        end_date: 结束日期（可选）
        config_id: 配置ID（可选）
        config_name: 配置名称（可选，模糊搜索）
        sum_field_key: 求和字段键名（可选）
        data_source: 数据来源（可选）
        skip_count: 是否跳过 COUNT 查询（优化性能）
    
    Returns:
        dict: 查询结果
    """
    try:
        where_clauses = ['1=1']
        params = []
        
        if start_date:
            where_clauses.append('report_date >= %s')
            params.append(start_date)
        
        if end_date:
            where_clauses.append('report_date <= %s')
            params.append(end_date)
        
        if config_id:
            where_clauses.append('config_id = %s')
            params.append(config_id)
        
        if config_name:
            where_clauses.append('config_name LIKE %s')
            params.append(f'%{config_name}%')
        
        if sum_field_key:
            where_clauses.append('sum_field_key = %s')
            params.append(sum_field_key)
        
        if data_source:
            where_clauses.append('data_source = %s')
            params.append(data_source)
        
        where_sql = ' AND '.join(where_clauses)
        
        # 查询总数（如果不跳过）
        total = 0
        if not skip_count:
            total_result = execute_query(
                f'SELECT COUNT(*) as total FROM t_daily_report_sum_data WHERE {where_sql}',
                tuple(params)
            )
            total = total_result[0]['total']
        
        # 查询数据
        if page is not None:
            offset = (page - 1) * page_size
            list_result = execute_query(
                f'''SELECT * FROM t_daily_report_sum_data 
                    WHERE {where_sql} 
                    ORDER BY report_date DESC, sort_order ASC, config_id ASC, id DESC 
                    LIMIT %s OFFSET %s''',
                tuple(params) + (page_size, offset)
            )
        else:
            list_result = execute_query(
                f'''SELECT * FROM t_daily_report_sum_data 
                    WHERE {where_sql} 
                    ORDER BY report_date DESC, sort_order ASC, config_id ASC, id DESC'''
                ,
                tuple(params)
            )
        
        return {
            'success': True,
            'data': {
                'list': list_result,
                'total': total,
                'page': page,
                'page_size': page_size
            }
        }
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def add_sum_data(data):
    """
    手动添加求和数据
    
    Args:
        data: 求和数据字典
    
    Returns:
        dict: 操作结果
    """
    try:
        sum_data_id = int(datetime.now().timestamp() * 1000)
        
        # 获取配置的排序号
        sort_order = None
        config_id = data.get('config_id')
        if config_id:
            try:
                cfg_result = execute_query(
                    'SELECT sort_order FROM t_daily_report_config WHERE id = %s LIMIT 1',
                    (config_id,)
                )
                if cfg_result and cfg_result[0]['sort_order'] is not None:
                    sort_order = cfg_result[0]['sort_order']
            except Exception:
                pass
        
        sql = '''
            INSERT INTO t_daily_report_sum_data
            (id, report_date, config_id, config_name, split_type, split_value, split_name,
             sum_field_key, sum_field_name, sum_value, total_orders, sort_order, data_source, remark, 
             create_time, update_time)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
        '''
        params = (
            sum_data_id,
            data.get('report_date', ''),
            data.get('config_id'),
            data.get('config_name', ''),
            data.get('split_type', ''),
            data.get('split_value', ''),
            data.get('split_name', ''),
            data.get('sum_field_key', ''),
            data.get('sum_field_name', ''),
            float(data.get('sum_value', 0)),
            data.get('total_orders', 0),
            sort_order,
            'manual',
            data.get('remark', '')
        )
        execute_insert(sql, params)
        return {'success': True, 'message': '添加成功', 'id': sum_data_id}
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def batch_add_sum_data(data):
    """
    批量添加求和数据
    
    Args:
        data: 求和数据字典，包含 fields 列表
    
    Returns:
        dict: 操作结果
    """
    try:
        fields = data.get('fields', [])
        if not fields:
            return {'success': False, 'message': '请至少添加一个字段'}
        
        # 获取配置的排序号
        sort_order = None
        config_id = data.get('config_id')
        if config_id:
            try:
                cfg_result = execute_query(
                    'SELECT sort_order FROM t_daily_report_config WHERE id = %s LIMIT 1',
                    (config_id,)
                )
                if cfg_result and cfg_result[0]['sort_order'] is not None:
                    sort_order = cfg_result[0]['sort_order']
            except Exception:
                pass
        
        sql = '''
            INSERT INTO t_daily_report_sum_data
            (id, report_date, config_id, config_name, split_type, split_value, split_name,
             sum_field_key, sum_field_name, sum_value, total_orders, sort_order, data_source, remark, 
             create_time, update_time)
            VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
        '''
        
        count = 0
        for field in fields:
            sum_data_id = int(datetime.now().timestamp() * 1000) + count
            params = (
                sum_data_id,
                data.get('report_date', ''),
                data.get('config_id'),
                data.get('config_name', ''),
                data.get('split_type', ''),
                data.get('split_value', ''),
                data.get('split_name', ''),
                field.get('sum_field_key', ''),
                field.get('sum_field_name', ''),
                float(field.get('sum_value', 0)),
                data.get('total_orders', 0),
                sort_order,
                'manual',
                data.get('remark', '')
            )
            execute_insert(sql, params)
            count += 1
        
        return {'success': True, 'message': f'添加成功，共{count}条记录', 'count': count}
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def update_sum_data(sum_data_id, data):
    """
    更新求和数据
    
    Args:
        sum_data_id: 求和数据ID
        data: 更新的数据字典
    
    Returns:
        dict: 操作结果
    """
    try:
        update_fields = []
        params = []
        
        if 'report_date' in data:
            update_fields.append('report_date = %s')
            params.append(data['report_date'])
        
        if 'config_id' in data:
            update_fields.append('config_id = %s')
            params.append(data['config_id'])
        
        if 'config_name' in data:
            update_fields.append('config_name = %s')
            params.append(data['config_name'])
        
        if 'split_type' in data:
            update_fields.append('split_type = %s')
            params.append(data['split_type'])
        
        if 'split_value' in data:
            update_fields.append('split_value = %s')
            params.append(data['split_value'])
        
        if 'split_name' in data:
            update_fields.append('split_name = %s')
            params.append(data['split_name'])
        
        if 'sum_field_key' in data:
            update_fields.append('sum_field_key = %s')
            params.append(data['sum_field_key'])
        
        if 'sum_field_name' in data:
            update_fields.append('sum_field_name = %s')
            params.append(data['sum_field_name'])
        
        if 'sum_value' in data:
            update_fields.append('sum_value = %s')
            params.append(float(data['sum_value']))
        
        if 'total_orders' in data:
            update_fields.append('total_orders = %s')
            params.append(data['total_orders'])
        
        if 'remark' in data:
            update_fields.append('remark = %s')
            params.append(data['remark'])
        
        if 'data_source' in data:
            update_fields.append('data_source = %s')
            params.append(data['data_source'])
        
        if not update_fields:
            return {'success': False, 'message': '没有需要更新的字段'}
        
        update_fields.append('update_time = NOW()')
        params.append(sum_data_id)
        
        sql = f'''
            UPDATE t_daily_report_sum_data 
            SET {', '.join(update_fields)}
            WHERE id = %s
        '''
        rowcount = execute_update(sql, tuple(params))
        
        if rowcount > 0:
            return {'success': True, 'message': '更新成功'}
        else:
            return {'success': False, 'message': '记录不存在'}
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def delete_sum_data(sum_data_id):
    """
    删除求和数据
    
    Args:
        sum_data_id: 求和数据ID
    
    Returns:
        dict: 操作结果
    """
    try:
        rowcount = execute_update(
            'DELETE FROM t_daily_report_sum_data WHERE id = %s',
            (sum_data_id,)
        )
        if rowcount > 0:
            return {'success': True, 'message': '删除成功'}
        else:
            return {'success': False, 'message': '记录不存在'}
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def batch_delete_sum_data(ids):
    """
    批量删除求和数据
    
    Args:
        ids: ID列表
    
    Returns:
        dict: 操作结果
    """
    try:
        placeholders = ', '.join(['%s'] * len(ids))
        rowcount = execute_update(
            f'DELETE FROM t_daily_report_sum_data WHERE id IN ({placeholders})',
            tuple(ids)
        )
        return {'success': True, 'message': f'成功删除 {rowcount} 条记录'}
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def export_sum_data_to_excel(start_date=None, end_date=None, config_id=None, data_source=None, keyword=None):
    """
    导出求和数据为Excel
    
    Args:
        start_date: 开始日期（可选）
        end_date: 结束日期（可选）
        config_id: 配置ID（可选）
        data_source: 数据来源（可选）
        keyword: 配置名称关键词（可选）
    
    Returns:
        dict: {success, message, file_path}
    """
    try:
        from openpyxl import Workbook
        from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
        
        # 构建查询条件
        where_clauses = []
        params = []
        
        if start_date:
            where_clauses.append('report_date >= %s')
            params.append(start_date)
        
        if end_date:
            where_clauses.append('report_date <= %s')
            params.append(end_date)
        
        if config_id:
            where_clauses.append('config_id = %s')
            params.append(config_id)
        
        if data_source:
            where_clauses.append('data_source = %s')
            params.append(data_source)
        
        if keyword:
            where_clauses.append('config_name LIKE %s')
            params.append(f'%{keyword}%')
        
        where_sql = ''
        if where_clauses:
            where_sql = 'WHERE ' + ' AND '.join(where_clauses)
        
        # 使用分页查询避免大数据量超时
        rows = []
        page_size = 500
        page = 1
        
        while True:
            offset = (page - 1) * page_size
            sql = f'''
                SELECT id, report_date, config_id, config_name, split_type, split_value, split_name,
                       sum_field_key, sum_field_name, sum_value, total_orders, sort_order, data_source, remark,
                       create_time, update_time
                FROM t_daily_report_sum_data
                {where_sql}
                ORDER BY report_date DESC, sort_order ASC, config_id ASC, sum_field_key ASC
                LIMIT %s OFFSET %s
            '''
            query_params = tuple(params) + (page_size, offset)
            page_rows = execute_query(sql, query_params)
            if not page_rows:
                break
            rows.extend(page_rows)
            if len(page_rows) < page_size:
                break
            page += 1
        
        # 创建Excel
        wb = Workbook()
        ws = wb.active
        ws.title = '求和数据'
        
        # 表头
        headers = ['序号', '报表日期', '配置名称', '拆分方式', '拆分值', '求和字段', '求和值', '订单数', '数据来源', '修改原因/备注', '创建时间', '更新时间']
        
        header_fill = PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid')
        header_font = Font(bold=True, color='FFFFFF', size=11)
        header_alignment = Alignment(horizontal='center', vertical='center')
        
        thin_border = Border(
            left=Side(style='thin', color='000000'),
            right=Side(style='thin', color='000000'),
            top=Side(style='thin', color='000000'),
            bottom=Side(style='thin', color='000000')
        )
        
        even_fill = PatternFill(start_color='F2F2F2', end_color='F2F2F2', fill_type='solid')
        
        # 写入表头
        for col_idx, header in enumerate(headers, 1):
            cell = ws.cell(row=1, column=col_idx)
            cell.value = header
            cell.font = header_font
            cell.fill = header_fill
            cell.alignment = header_alignment
            cell.border = thin_border
        
        ws.row_dimensions[1].height = 25
        
        # 拆分方式映射
        split_type_map = {
            'company_id': '按企业ID',
            'user_id': '按用户ID',
            'station_id': '按场站ID'
        }
        
        # 数据来源映射
        source_map = {
            'auto': '自动采集',
            'manual': '手动编辑'
        }
        
        # 写入数据
        for row_idx, row in enumerate(rows, 2):
            is_even = (row_idx - 2) % 2 == 1
            
            values = [
                row.get('sort_order') or '',
                row.get('report_date', ''),
                row.get('config_name', ''),
                split_type_map.get(row.get('split_type', ''), row.get('split_type', '')),
                row.get('split_name', '') or row.get('split_value', ''),
                row.get('sum_field_name', ''),
                float(row.get('sum_value', 0) or 0),
                int(row.get('total_orders', 0) or 0),
                source_map.get(row.get('data_source', ''), row.get('data_source', '')),
                row.get('remark', ''),
                str(row.get('create_time', '')) if row.get('create_time') else '',
                str(row.get('update_time', '')) if row.get('update_time') else ''
            ]
            
            for col_idx, val in enumerate(values, 1):
                cell = ws.cell(row=row_idx, column=col_idx)
                cell.value = val
                cell.border = thin_border
                
                # 对齐方式：数字靠右，其他居中或靠左
                if col_idx in [7, 8]:  # 求和值、订单数
                    cell.alignment = Alignment(horizontal='right', vertical='center')
                    if col_idx == 7:
                        cell.number_format = '0.000'
                elif col_idx in [1, 2, 4, 9]:  # 序号、日期、拆分方式、数据来源
                    cell.alignment = Alignment(horizontal='center', vertical='center')
                else:
                    cell.alignment = Alignment(horizontal='left', vertical='center')
                
                if is_even:
                    cell.fill = even_fill
            
            ws.row_dimensions[row_idx].height = 22
        
        # 调整列宽
        col_widths = [8, 14, 20, 12, 20, 18, 14, 10, 12, 30, 20, 20]
        for col_idx, width in enumerate(col_widths, 1):
            from openpyxl.utils import get_column_letter
            col_letter = get_column_letter(col_idx)
            ws.column_dimensions[col_letter].width = width
        
        # 冻结首行
        ws.freeze_panes = 'A2'
        
        # 保存文件
        reports_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'public', 'reports')
        os.makedirs(reports_dir, exist_ok=True)
        
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f'求和数据导出_{timestamp}.xlsx'
        file_path = os.path.join(reports_dir, filename)
        wb.save(file_path)
        
        return {'success': True, 'message': '导出成功', 'file_path': f'/public/reports/{filename}', 'filename': filename, 'total': len(rows)}
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}


def get_monthly_charge_degree_total(config_id=None, month=None, split_type=None, split_value=None, end_date=None):
    """
    获取当月充电电量累计（从求和数据表查询，对账后的准确数据）
    - 如果当天已经生成了日报并采集，自动包含在内，不会重复计算
    - 以配置当前拆分为准，只统计匹配的拆分值数据
    - 截止到 end_date（报表日期），不包含 end_date 之后的数据
    - 返回缺失的日期列表（从月初到 end_date 之间缺少哪些天的数据）
    
    Args:
        config_id: 配置ID（可选，不传则统计所有配置）
        month: 月份，格式 YYYY-MM（可选，默认当月）
        split_type: 拆分类型（可选，company_id/user_id/station_id）
        split_value: 拆分值，逗号分隔的字符串（可选，用于过滤）
        end_date: 截止日期，格式 YYYY-MM-DD（可选，默认当月最后一天）
    
    Returns:
        dict: {
            success: bool,
            data: {
                total_degree: float,       // 累计充电电量(kWh)
                total_days: int,           // 有数据的天数
                total_orders: int,         // 累计订单数
                today_degree: float,       // 报表日期当天的电量(kWh)
                month: str,                // 统计月份
                detail: list,              // 按天明细
                end_date: str,             // 截止日期
                missing_dates: list,       // 缺失的日期列表
                expected_days: int         // 应该有的天数（从月初到end_date）
            },
            message: str
        }
    """
    try:
        from datetime import datetime, timedelta
        
        # 默认当月
        if not month:
            month = datetime.now().strftime('%Y-%m')
        
        # 拼接日期模糊匹配前缀
        date_prefix = month + '-'
        
        # 计算截止日期（默认报表日期或当月最后一天）
        if end_date:
            end_date_str = end_date
        else:
            # 取当月最后一天
            if month.endswith('-12'):
                next_month = str(int(month[:4]) + 1) + '-01'
            else:
                next_month = month[:5] + str(int(month[5:7]) + 1).zfill(2)
            end_date_str = (datetime.strptime(next_month + '-01', '%Y-%m-%d') - timedelta(days=1)).strftime('%Y-%m-%d')
        
        # 构建查询SQL - 查询所有字段，按日期统计（包括手动添加的数据）
        # 使用 MAX(total_orders) 避免同一天多个字段重复计算订单数
        sql = """
            SELECT 
                report_date,
                SUM(CASE WHEN sum_field_key = 'charge_degree' THEN sum_value ELSE 0 END) as total_degree,
                MAX(total_orders) as total_orders
            FROM t_daily_report_sum_data
            WHERE report_date LIKE %s
            AND report_date <= %s
        """
        params = [date_prefix + '%', end_date_str]
        
        # 按配置过滤（包含手动添加的数据，手动添加的config_id为NULL）
        if config_id:
            sql += ' AND (config_id = %s OR config_id IS NULL)'
            params.append(config_id)
        
        # 按拆分值过滤（以配置当前拆分为准）
        if split_type and split_value:
            values = [v.strip() for v in split_value.split(',') if v.strip()]
            if values:
                placeholders = ','.join(['%s'] * len(values))
                sql += f' AND split_type = %s AND split_value IN ({placeholders})'
                params.append(split_type)
                params.extend(values)
        
        sql += ' GROUP BY report_date ORDER BY report_date ASC'
        
        rows = execute_query(sql, tuple(params))
        
        # 计算从月初到end_date应该有多少天
        start_of_month = month + '-01'
        start_date_obj = datetime.strptime(start_of_month, '%Y-%m-%d')
        end_date_obj = datetime.strptime(end_date_str, '%Y-%m-%d')
        expected_days = (end_date_obj - start_date_obj).days + 1
        
        # 收集已有数据的日期
        existing_dates = set()
        total_degree = 0.0
        total_orders = 0
        total_days = len(rows)
        today_degree = 0.0
        detail = []
        
        for row in rows:
            degree = float(row['total_degree'] or 0)
            orders = int(row['total_orders'] or 0)
            total_degree += degree
            total_orders += orders
            existing_dates.add(row['report_date'])
            detail.append({
                'report_date': row['report_date'],
                'degree': round(degree, 3),
                'orders': orders
            })
            if row['report_date'] == end_date_str:
                today_degree = degree
        
        # 计算缺失的日期
        missing_dates = []
        for i in range(expected_days):
            date_obj = start_date_obj + timedelta(days=i)
            date_str = date_obj.strftime('%Y-%m-%d')
            if date_str not in existing_dates:
                missing_dates.append(date_str)
        
        return {
            'success': True,
            'data': {
                'total_degree': round(total_degree, 3),
                'total_days': total_days,
                'total_orders': total_orders,
                'today_degree': round(today_degree, 3),
                'month': month,
                'detail': detail,
                'end_date': end_date_str,
                'missing_dates': missing_dates,
                'expected_days': expected_days
            },
            'message': '查询成功'
        }
    except Exception as e:
        import traceback
        traceback.print_exc()
        return {'success': False, 'message': str(e)}
