#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
管理員 API

Author: PANJIT IT Team
Created: 2024-01-28
Modified: 2024-01-28
"""

from datetime import datetime, timedelta
from flask import Blueprint, request, jsonify, g
from app.utils.decorators import admin_required
from app.utils.validators import validate_pagination, validate_date_range
from app.utils.helpers import create_response
from app.utils.exceptions import ValidationError
from app.utils.logger import get_logger
from app.models.user import User
from app.models.job import TranslationJob
from app.models.stats import APIUsageStats
from app.models.log import SystemLog
from app.models.cache import TranslationCache
from sqlalchemy import func, desc

admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
logger = get_logger(__name__)


@admin_bp.route('/stats', methods=['GET'])
@admin_required
def get_system_stats():
    """取得系統統計資料"""
    try:
        # 取得時間範圍參數
        period = request.args.get('period', 'month')  # day, week, month
        
        # 計算時間範圍
        end_date = datetime.utcnow()
        if period == 'day':
            start_date = end_date - timedelta(days=1)
        elif period == 'week':
            start_date = end_date - timedelta(days=7)
        else:  # month
            start_date = end_date - timedelta(days=30)
        
        from app import db
        
        # 系統概覽統計
        overview = {
            'total_jobs': TranslationJob.query.count(),
            'completed_jobs': TranslationJob.query.filter_by(status='COMPLETED').count(),
            'failed_jobs': TranslationJob.query.filter_by(status='FAILED').count(),
            'pending_jobs': TranslationJob.query.filter_by(status='PENDING').count(),
            'processing_jobs': TranslationJob.query.filter_by(status='PROCESSING').count(),
            'total_users': User.query.count(),
            'active_users_today': User.query.filter(
                User.last_login >= datetime.utcnow() - timedelta(days=1)
            ).count(),
            'total_cost': db.session.query(func.sum(APIUsageStats.cost)).scalar() or 0.0
        }
        
        # 每日統計
        daily_stats = db.session.query(
            func.date(TranslationJob.created_at).label('date'),
            func.count(TranslationJob.id).label('jobs'),
            func.sum(func.case(
                (TranslationJob.status == 'COMPLETED', 1),
                else_=0
            )).label('completed'),
            func.sum(func.case(
                (TranslationJob.status == 'FAILED', 1),
                else_=0
            )).label('failed')
        ).filter(
            TranslationJob.created_at >= start_date
        ).group_by(func.date(TranslationJob.created_at)).order_by(
            func.date(TranslationJob.created_at)
        ).all()
        
        # 每日成本統計
        daily_costs = db.session.query(
            func.date(APIUsageStats.created_at).label('date'),
            func.sum(APIUsageStats.cost).label('cost')
        ).filter(
            APIUsageStats.created_at >= start_date
        ).group_by(func.date(APIUsageStats.created_at)).order_by(
            func.date(APIUsageStats.created_at)
        ).all()
        
        # 組合每日統計資料
        daily_stats_dict = {stat.date: stat for stat in daily_stats}
        daily_costs_dict = {cost.date: cost for cost in daily_costs}
        
        combined_daily_stats = []
        current_date = start_date.date()
        while current_date <= end_date.date():
            stat = daily_stats_dict.get(current_date)
            cost = daily_costs_dict.get(current_date)
            
            combined_daily_stats.append({
                'date': current_date.isoformat(),
                'jobs': stat.jobs if stat else 0,
                'completed': stat.completed if stat else 0,
                'failed': stat.failed if stat else 0,
                'cost': float(cost.cost) if cost and cost.cost else 0.0
            })
            
            current_date += timedelta(days=1)
        
        # 使用者排行榜
        user_rankings = db.session.query(
            User.id,
            User.display_name,
            func.count(TranslationJob.id).label('job_count'),
            func.sum(APIUsageStats.cost).label('total_cost')
        ).outerjoin(TranslationJob).outerjoin(APIUsageStats).filter(
            TranslationJob.created_at >= start_date
        ).group_by(User.id, User.display_name).order_by(
            func.sum(APIUsageStats.cost).desc().nullslast()
        ).limit(10).all()
        
        user_rankings_data = []
        for ranking in user_rankings:
            user_rankings_data.append({
                'user_id': ranking.id,
                'display_name': ranking.display_name,
                'job_count': ranking.job_count or 0,
                'total_cost': float(ranking.total_cost) if ranking.total_cost else 0.0
            })
        
        return jsonify(create_response(
            success=True,
            data={
                'overview': overview,
                'daily_stats': combined_daily_stats,
                'user_rankings': user_rankings_data,
                'period': period,
                'start_date': start_date.isoformat(),
                'end_date': end_date.isoformat()
            }
        ))
    
    except Exception as e:
        logger.error(f"Get system stats error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得系統統計失敗'
        )), 500


@admin_bp.route('/jobs', methods=['GET'])
@admin_required
def get_all_jobs():
    """取得所有使用者任務"""
    try:
        # 取得查詢參數
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 50, type=int)
        user_id = request.args.get('user_id', type=int)
        status = request.args.get('status')
        
        # 驗證分頁參數
        page, per_page = validate_pagination(page, min(per_page, 100))
        
        # 建立查詢
        query = TranslationJob.query
        
        # 使用者篩選
        if user_id:
            query = query.filter_by(user_id=user_id)
        
        # 狀態篩選
        if status and status != 'all':
            valid_statuses = ['PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'RETRY']
            if status.upper() in valid_statuses:
                query = query.filter_by(status=status.upper())
        
        # 排序
        query = query.order_by(TranslationJob.created_at.desc())
        
        # 分頁
        pagination = query.paginate(
            page=page, 
            per_page=per_page, 
            error_out=False
        )
        
        jobs = pagination.items
        
        # 組合回應資料（包含使用者資訊）
        jobs_data = []
        for job in jobs:
            job_data = job.to_dict()
            job_data['user'] = {
                'id': job.user.id,
                'username': job.user.username,
                'display_name': job.user.display_name,
                'email': job.user.email
            }
            jobs_data.append(job_data)
        
        return jsonify(create_response(
            success=True,
            data={
                'jobs': jobs_data,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': pagination.total,
                    'pages': pagination.pages,
                    'has_prev': pagination.has_prev,
                    'has_next': pagination.has_next
                }
            }
        ))
    
    except ValidationError as e:
        return jsonify(create_response(
            success=False,
            error=e.error_code,
            message=str(e)
        )), 400
    
    except Exception as e:
        logger.error(f"Get all jobs error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得任務列表失敗'
        )), 500


@admin_bp.route('/users', methods=['GET'])
@admin_required
def get_all_users():
    """取得所有使用者"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        
        # 驗證分頁參數
        page, per_page = validate_pagination(page, per_page)
        
        # 分頁查詢
        pagination = User.query.order_by(
            User.last_login.desc().nullslast(),
            User.created_at.desc()
        ).paginate(
            page=page, 
            per_page=per_page, 
            error_out=False
        )
        
        users = pagination.items
        
        # 組合使用者資料（包含統計）
        users_data = []
        for user in users:
            user_data = user.to_dict(include_stats=True)
            users_data.append(user_data)
        
        return jsonify(create_response(
            success=True,
            data={
                'users': users_data,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': pagination.total,
                    'pages': pagination.pages,
                    'has_prev': pagination.has_prev,
                    'has_next': pagination.has_next
                }
            }
        ))
    
    except ValidationError as e:
        return jsonify(create_response(
            success=False,
            error=e.error_code,
            message=str(e)
        )), 400
    
    except Exception as e:
        logger.error(f"Get all users error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得使用者列表失敗'
        )), 500


@admin_bp.route('/logs', methods=['GET'])
@admin_required
def get_system_logs():
    """取得系統日誌"""
    try:
        # 取得查詢參數
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 100, type=int)
        level = request.args.get('level')
        module = request.args.get('module')
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        
        # 驗證參數
        page, per_page = validate_pagination(page, min(per_page, 500))
        
        if start_date or end_date:
            start_date, end_date = validate_date_range(start_date, end_date)
        
        # 取得日誌
        logs = SystemLog.get_logs(
            level=level,
            module=module,
            start_date=start_date,
            end_date=end_date,
            limit=per_page,
            offset=(page - 1) * per_page
        )
        
        # 取得總數（簡化版本，不完全精確）
        total = len(logs) if len(logs) < per_page else (page * per_page) + 1
        
        logs_data = [log.to_dict() for log in logs]
        
        return jsonify(create_response(
            success=True,
            data={
                'logs': logs_data,
                'pagination': {
                    'page': page,
                    'per_page': per_page,
                    'total': total,
                    'has_more': len(logs) == per_page
                }
            }
        ))
    
    except ValidationError as e:
        return jsonify(create_response(
            success=False,
            error=e.error_code,
            message=str(e)
        )), 400
    
    except Exception as e:
        logger.error(f"Get system logs error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得系統日誌失敗'
        )), 500


@admin_bp.route('/api-usage', methods=['GET'])
@admin_required
def get_api_usage():
    """取得 API 使用統計"""
    try:
        # 取得時間範圍
        days = request.args.get('days', 30, type=int)
        days = min(days, 90)  # 最多90天
        
        # 取得每日統計
        daily_stats = APIUsageStats.get_daily_statistics(days=days)
        
        # 取得使用量排行
        top_users = APIUsageStats.get_top_users(limit=10)
        
        # 取得端點統計
        endpoint_stats = APIUsageStats.get_endpoint_statistics()
        
        # 取得成本趨勢
        cost_trend = APIUsageStats.get_cost_trend(days=days)
        
        return jsonify(create_response(
            success=True,
            data={
                'daily_stats': daily_stats,
                'top_users': top_users,
                'endpoint_stats': endpoint_stats,
                'cost_trend': cost_trend,
                'period_days': days
            }
        ))
    
    except Exception as e:
        logger.error(f"Get API usage error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得API使用統計失敗'
        )), 500


@admin_bp.route('/cache/stats', methods=['GET'])
@admin_required
def get_cache_stats():
    """取得翻譯快取統計"""
    try:
        cache_stats = TranslationCache.get_cache_statistics()
        
        return jsonify(create_response(
            success=True,
            data=cache_stats
        ))
    
    except Exception as e:
        logger.error(f"Get cache stats error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得快取統計失敗'
        )), 500


@admin_bp.route('/maintenance/cleanup', methods=['POST'])
@admin_required
def cleanup_system():
    """系統清理維護"""
    try:
        data = request.get_json() or {}
        
        # 清理選項
        cleanup_logs = data.get('cleanup_logs', False)
        cleanup_cache = data.get('cleanup_cache', False)
        cleanup_files = data.get('cleanup_files', False)
        
        logs_days = data.get('logs_days', 30)
        cache_days = data.get('cache_days', 90)
        files_days = data.get('files_days', 7)
        
        cleanup_results = {}
        
        # 清理舊日誌
        if cleanup_logs:
            deleted_logs = SystemLog.cleanup_old_logs(days_to_keep=logs_days)
            cleanup_results['logs'] = {
                'deleted_count': deleted_logs,
                'days_kept': logs_days
            }
        
        # 清理舊快取
        if cleanup_cache:
            deleted_cache = TranslationCache.clear_old_cache(days_to_keep=cache_days)
            cleanup_results['cache'] = {
                'deleted_count': deleted_cache,
                'days_kept': cache_days
            }
        
        # 清理舊檔案（這裡會在檔案服務中實作）
        if cleanup_files:
            # from app.services.file_service import cleanup_old_files
            # deleted_files = cleanup_old_files(days_to_keep=files_days)
            cleanup_results['files'] = {
                'message': 'File cleanup not implemented yet',
                'days_kept': files_days
            }
        
        # 記錄維護日誌
        SystemLog.info(
            'admin.maintenance',
            f'System cleanup performed by {g.current_user.username}',
            user_id=g.current_user.id,
            extra_data={
                'cleanup_options': data,
                'results': cleanup_results
            }
        )
        
        logger.info(f"System cleanup performed by {g.current_user.username}")
        
        return jsonify(create_response(
            success=True,
            data=cleanup_results,
            message='系統清理完成'
        ))
    
    except Exception as e:
        logger.error(f"System cleanup error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='系統清理失敗'
        )), 500