#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
翻譯任務管理 API

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

from flask import Blueprint, request, jsonify, g
from app.utils.decorators import jwt_login_required, admin_required
from app.utils.validators import (
    validate_job_uuid, 
    validate_pagination, 
    validate_date_range
)
from app.utils.helpers import create_response, calculate_processing_time
from app.utils.exceptions import ValidationError
from app.utils.logger import get_logger
from app.models.job import TranslationJob
from app.models.stats import APIUsageStats
from app.models.log import SystemLog
from sqlalchemy import and_, or_

jobs_bp = Blueprint('jobs', __name__, url_prefix='/jobs')
logger = get_logger(__name__)


@jobs_bp.route('', methods=['GET'])
@jwt_login_required
def get_user_jobs():
    """取得使用者任務列表"""
    try:
        # 取得查詢參數
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        status = request.args.get('status', 'all')
        
        # 驗證分頁參數
        page, per_page = validate_pagination(page, per_page)
        
        # 建立查詢
        query = TranslationJob.query.filter_by(user_id=g.current_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(include_files=False)
            
            # 計算處理時間
            if job.processing_started_at and job.completed_at:
                job_data['processing_time'] = calculate_processing_time(
                    job.processing_started_at, job.completed_at
                )
            
            # 取得佇列位置（只對 PENDING 狀態）
            if job.status == 'PENDING':
                job_data['queue_position'] = TranslationJob.get_queue_position(job.job_uuid)
            
            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 user jobs error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得任務列表失敗'
        )), 500


@jobs_bp.route('/<job_uuid>', methods=['GET'])
@jwt_login_required
def get_job_detail(job_uuid):
    """取得任務詳細資訊"""
    try:
        # 驗證 UUID 格式
        validate_job_uuid(job_uuid)
        
        # 取得任務
        job = TranslationJob.query.filter_by(job_uuid=job_uuid).first()
        
        if not job:
            return jsonify(create_response(
                success=False,
                error='JOB_NOT_FOUND',
                message='任務不存在'
            )), 404
        
        # 檢查權限
        if job.user_id != g.current_user_id and not g.is_admin:
            return jsonify(create_response(
                success=False,
                error='PERMISSION_DENIED',
                message='無權限存取此任務'
            )), 403
        
        # 取得任務詳細資料
        job_data = job.to_dict(include_files=True)
        
        # 計算處理時間
        if job.processing_started_at and job.completed_at:
            job_data['processing_time'] = calculate_processing_time(
                job.processing_started_at, job.completed_at
            )
        elif job.processing_started_at:
            job_data['processing_time'] = calculate_processing_time(
                job.processing_started_at
            )
        
        # 取得佇列位置（只對 PENDING 狀態）
        if job.status == 'PENDING':
            job_data['queue_position'] = TranslationJob.get_queue_position(job.job_uuid)
        
        # 取得 API 使用統計（如果已完成）
        if job.status == 'COMPLETED':
            api_stats = APIUsageStats.get_user_statistics(
                user_id=job.user_id,
                start_date=job.created_at,
                end_date=job.completed_at
            )
            job_data['api_usage'] = api_stats
        
        return jsonify(create_response(
            success=True,
            data={
                'job': job_data
            }
        ))
    
    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 job detail error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得任務詳情失敗'
        )), 500


@jobs_bp.route('/<job_uuid>/retry', methods=['POST'])
@jwt_login_required
def retry_job(job_uuid):
    """重試失敗任務"""
    try:
        # 驗證 UUID 格式
        validate_job_uuid(job_uuid)
        
        # 取得任務
        job = TranslationJob.query.filter_by(job_uuid=job_uuid).first()
        
        if not job:
            return jsonify(create_response(
                success=False,
                error='JOB_NOT_FOUND',
                message='任務不存在'
            )), 404
        
        # 檢查權限
        if job.user_id != g.current_user_id and not g.is_admin:
            return jsonify(create_response(
                success=False,
                error='PERMISSION_DENIED',
                message='無權限操作此任務'
            )), 403
        
        # 檢查是否可以重試
        if not job.can_retry():
            return jsonify(create_response(
                success=False,
                error='CANNOT_RETRY',
                message='任務無法重試（狀態不正確或重試次數已達上限）'
            )), 400
        
        # 重置任務狀態
        job.update_status('PENDING', error_message=None)
        job.increment_retry()
        
        # 計算新的佇列位置
        queue_position = TranslationJob.get_queue_position(job.job_uuid)
        
        # 記錄重試日誌
        SystemLog.info(
            'jobs.retry',
            f'Job retry requested: {job_uuid}',
            user_id=g.current_user_id,
            job_id=job.id,
            extra_data={
                'retry_count': job.retry_count,
                'previous_error': job.error_message
            }
        )
        
        logger.info(f"Job retry requested: {job_uuid} (retry count: {job.retry_count})")
        
        # 重新觸發翻譯任務（這裡會在實作 Celery 時加入）
        # from app.tasks.translation import process_translation_job
        # process_translation_job.delay(job.id)
        
        return jsonify(create_response(
            success=True,
            data={
                'job_uuid': job.job_uuid,
                'status': job.status,
                'retry_count': job.retry_count,
                'queue_position': queue_position
            },
            message='任務已重新加入佇列'
        ))
    
    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"Job retry error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='重試任務失敗'
        )), 500


@jobs_bp.route('/statistics', methods=['GET'])
@jwt_login_required
def get_user_statistics():
    """取得使用者統計資料"""
    try:
        # 取得日期範圍參數
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')
        
        # 驗證日期範圍
        if start_date or end_date:
            start_date, end_date = validate_date_range(start_date, end_date)
        
        # 取得任務統計
        job_stats = TranslationJob.get_statistics(
            user_id=g.current_user_id,
            start_date=start_date,
            end_date=end_date
        )
        
        # 取得 API 使用統計
        api_stats = APIUsageStats.get_user_statistics(
            user_id=g.current_user_id,
            start_date=start_date,
            end_date=end_date
        )
        
        return jsonify(create_response(
            success=True,
            data={
                'job_statistics': job_stats,
                'api_statistics': api_stats
            }
        ))
    
    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 user statistics error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得統計資料失敗'
        )), 500


@jobs_bp.route('/queue/status', methods=['GET'])
def get_queue_status():
    """取得佇列狀態（不需登入）"""
    try:
        # 取得各狀態任務數量
        pending_count = TranslationJob.query.filter_by(status='PENDING').count()
        processing_count = TranslationJob.query.filter_by(status='PROCESSING').count()
        
        # 取得當前處理中的任務（最多5個）
        processing_jobs = TranslationJob.query.filter_by(
            status='PROCESSING'
        ).order_by(TranslationJob.processing_started_at).limit(5).all()
        
        processing_jobs_data = []
        for job in processing_jobs:
            processing_jobs_data.append({
                'job_uuid': job.job_uuid,
                'original_filename': job.original_filename,
                'progress': float(job.progress) if job.progress else 0.0,
                'processing_started_at': job.processing_started_at.isoformat() if job.processing_started_at else None,
                'processing_time': calculate_processing_time(job.processing_started_at) if job.processing_started_at else None
            })
        
        return jsonify(create_response(
            success=True,
            data={
                'queue_status': {
                    'pending': pending_count,
                    'processing': processing_count,
                    'total_in_queue': pending_count + processing_count
                },
                'processing_jobs': processing_jobs_data
            }
        ))
    
    except Exception as e:
        logger.error(f"Get queue status error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取得佇列狀態失敗'
        )), 500


@jobs_bp.route('/<job_uuid>/cancel', methods=['POST'])
@jwt_login_required
def cancel_job(job_uuid):
    """取消任務（僅限 PENDING 狀態）"""
    try:
        # 驗證 UUID 格式
        validate_job_uuid(job_uuid)
        
        # 取得任務
        job = TranslationJob.query.filter_by(job_uuid=job_uuid).first()
        
        if not job:
            return jsonify(create_response(
                success=False,
                error='JOB_NOT_FOUND',
                message='任務不存在'
            )), 404
        
        # 檢查權限
        if job.user_id != g.current_user_id and not g.is_admin:
            return jsonify(create_response(
                success=False,
                error='PERMISSION_DENIED',
                message='無權限操作此任務'
            )), 403
        
        # 只能取消等待中的任務
        if job.status != 'PENDING':
            return jsonify(create_response(
                success=False,
                error='CANNOT_CANCEL',
                message='只能取消等待中的任務'
            )), 400
        
        # 更新任務狀態為失敗（取消）
        job.update_status('FAILED', error_message='使用者取消任務')
        
        # 記錄取消日誌
        SystemLog.info(
            'jobs.cancel',
            f'Job cancelled by user: {job_uuid}',
            user_id=g.current_user_id,
            job_id=job.id
        )
        
        logger.info(f"Job cancelled by user: {job_uuid}")
        
        return jsonify(create_response(
            success=True,
            data={
                'job_uuid': job.job_uuid,
                'status': job.status
            },
            message='任務已取消'
        ))
    
    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"Cancel job error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='取消任務失敗'
        )), 500


@jobs_bp.route('/<job_uuid>', methods=['DELETE'])
@jwt_login_required
def delete_job(job_uuid):
    """刪除任務"""
    try:
        # 驗證 UUID 格式
        validate_job_uuid(job_uuid)
        
        # 取得任務
        job = TranslationJob.query.filter_by(job_uuid=job_uuid).first()
        
        if not job:
            return jsonify(create_response(
                success=False,
                error='JOB_NOT_FOUND',
                message='任務不存在'
            )), 404
        
        # 檢查權限
        if job.user_id != g.current_user_id and not g.is_admin:
            return jsonify(create_response(
                success=False,
                error='PERMISSION_DENIED',
                message='無權限操作此任務'
            )), 403
        
        # 檢查任務狀態 - 不能刪除正在處理中的任務
        if job.status == 'PROCESSING':
            return jsonify(create_response(
                success=False,
                error='CANNOT_DELETE',
                message='無法刪除正在處理中的任務'
            )), 400
        
        # 刪除任務相關檔案
        import os
        import shutil
        from pathlib import Path
        
        try:
            if job.file_path and os.path.exists(job.file_path):
                # 取得任務目錄（通常是 uploads/job_uuid）
                job_dir = Path(job.file_path).parent
                if job_dir.exists() and job_dir.name == job.job_uuid:
                    shutil.rmtree(job_dir)
                    logger.info(f"Deleted job directory: {job_dir}")
        except Exception as file_error:
            logger.warning(f"Failed to delete job files: {str(file_error)}")
        
        # 記錄刪除日誌
        SystemLog.info(
            'jobs.delete',
            f'Job deleted by user: {job_uuid}',
            user_id=g.current_user_id,
            job_id=job.id,
            extra_data={
                'filename': job.original_filename,
                'status': job.status
            }
        )
        
        from app import db
        
        # 刪除資料庫記錄
        db.session.delete(job)
        db.session.commit()
        
        logger.info(f"Job deleted by user: {job_uuid}")
        
        return jsonify(create_response(
            success=True,
            message='任務已刪除'
        ))
    
    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"Delete job error: {str(e)}")
        
        return jsonify(create_response(
            success=False,
            error='SYSTEM_ERROR',
            message='刪除任務失敗'
        )), 500