"""
Flask 主应用
订单日报系统
"""
import os
from datetime import datetime
from flask import Flask, render_template, Response, request, jsonify, g
from flask_cors import CORS
from apscheduler.schedulers.background import BackgroundScheduler
import pytz

from lib.db import execute_query
from lib.report_generator import generate_daily_report
from lib.api import register_blueprints
from lib.db_init import init_database_tables, optimize_sum_data_indexes
from lib.logger import log_info, log_error, log_warning
from lib.api.download_api import cleanup_old_temp_zips
from lib.api.auth_api import get_current_user

# 创建 Flask 应用
app = Flask(__name__, 
            template_folder='templates',
            static_folder='public')
CORS(app)

# 确保 public/reports 目录存在
os.makedirs(os.path.join('public', 'reports'), exist_ok=True)

# 注册 API 蓝图
register_blueprints(app)

# 应用启动时自动初始化数据库表
log_info('正在初始化数据库表...', 'app')
if init_database_tables():
    log_info('数据库表初始化成功', 'app')
    
    # 优化求和数据表索引
    log_info('正在优化数据库索引...', 'app')
    if optimize_sum_data_indexes():
        log_info('数据库索引优化成功', 'app')
    else:
        log_warning('数据库索引优化失败，但不影响正常使用', 'app')
else:
    log_error('数据库表初始化失败，请检查数据库连接', 'app')


# ==================== 登录验证中间件 ====================

# 不需要登录的路径白名单
WHITELIST_PATHS = [
    '/api/auth/login',
    '/api/auth/info',
    '/public/',
    '/static/',
    '/favicon.ico',
    '/'
]


@app.before_request
def check_login():
    """全局登录验证"""
    path = request.path
    
    # 白名单路径直接放行
    for wp in WHITELIST_PATHS:
        if path.startswith(wp):
            return None
    
    # 页面请求（HTML）直接放行，由前端控制登录
    if path == '/' or path.endswith('.html'):
        return None
    
    # 静态文件直接放行
    if path.startswith('/public/') or path.startswith('/static/'):
        return None
    
    # API 请求需要验证登录
    if path.startswith('/api/'):
        # 先从 header 取 token，再从 query 参数取（用于下载链接）
        token = request.headers.get('Authorization', '')
        if token.startswith('Bearer '):
            token = token[7:]
        
        if not token:
            token = request.args.get('token', '')
        
        user = None
        if token:
            from lib.api.auth_api import get_user_by_token
            user = get_user_by_token(token)
        
        if not user:
            return jsonify({
                'success': False,
                'message': '未登录或登录已过期',
                'code': 401
            }), 401
        g.current_user = user
    
    return None


# ==================== 页面路由 ====================

@app.route('/')
def index():
    """主页"""
    return render_template('index.html')


@app.route('/favicon.ico')
def favicon():
    """网站图标（返回空响应避免404）"""
    return Response(status=204)


# ==================== 定时任务 ====================

def scheduled_job():
    """定时任务：每天 8:01 自动生成日报"""
    log_info(f'开始执行定时任务...', 'scheduler')
    
    try:
        # 获取所有启用的配置
        configs = execute_query(
            'SELECT id, config_name FROM t_daily_report_config WHERE is_active = 1'
        )
        
        if not configs:
            log_warning('没有启用的配置，跳过生成', 'scheduler')
            return
        
        log_info(f'找到 {len(configs)} 个启用的配置', 'scheduler')
        
        # 为每个配置生成日报
        success_count = 0
        fail_count = 0
        for config in configs:
            log_info(f'正在生成：{config["config_name"]} (ID: {config["id"]})', 'scheduler')
            result = generate_daily_report(config['id'])
            
            if result['success']:
                log_info(f'  ✓ 成功：{result["total_orders"]} 条订单，总电量：{result.get("total_degree", 0)} kWh', 'scheduler')
                success_count += 1
            else:
                log_error(f'  ✗ 失败：{result["message"]}', 'scheduler')
                fail_count += 1
        
        log_info(f'定时任务执行完成，成功 {success_count} 个，失败 {fail_count} 个', 'scheduler')
    except Exception as e:
        log_error(f'定时任务执行失败：{e}', 'scheduler')


# ==================== 启动定时任务 ====================
scheduler = BackgroundScheduler(timezone='Asia/Shanghai')
scheduler.add_job(scheduled_job, 'cron', hour=8, minute=30)
scheduler.add_job(cleanup_old_temp_zips, 'interval', hours=1)

# 添加 Doris 表统计信息定时优化任务（每天凌晨3点执行）
def optimize_doris_tables():
    """定期优化 Doris 表统计信息"""
    try:
        log_info('开始执行 Doris 表统计信息优化...', 'scheduler')
        from lib.doris_optimize import optimize_doris_table
        
        tables = [
            't_daily_report_sum_data',
            't_daily_report_config',
            't_daily_report_history',
        ]
        
        for table in tables:
            try:
                optimize_doris_table(table)
                log_info(f'表 {table} 统计信息优化完成', 'scheduler')
            except Exception as e:
                log_warning(f'表 {table} 统计信息优化失败: {e}', 'scheduler')
        
        log_info('Doris 表统计信息优化完成', 'scheduler')
    except Exception as e:
        log_error(f'Doris 表统计信息优化失败: {e}', 'scheduler')


scheduler.add_job(optimize_doris_tables, 'cron', hour=3, minute=0)

scheduler.start()
log_info('定时任务已启动：每天 08:30 执行日报生成，每小时清理临时文件，每天 03:00 优化 Doris 统计信息', 'app')


# ==================== 启动应用 ====================

if __name__ == '__main__':
    # 支持沙箱环境和本地环境
    port = int(os.environ.get('DEPLOY_RUN_PORT', os.environ.get('PORT', 5000)))
    log_info(f'启动服务器：http://localhost:{port}', 'app')
    log_info(f'数据库：{os.environ.get("DB_HOST", "haoslm2.xicp.net")}:{os.environ.get("DB_PORT", "10216")}', 'app')
    app.run(host='0.0.0.0', port=port, debug=True)