#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
翻譯任務資料模型

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

import json
import uuid
from datetime import datetime, timedelta
from sqlalchemy.sql import func
from sqlalchemy import event
from app import db
from app.utils.timezone import format_taiwan_time


class TranslationJob(db.Model):
    """翻譯任務表 (dt_translation_jobs)"""
    __tablename__ = 'dt_translation_jobs'
    
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    job_uuid = db.Column(db.String(36), unique=True, nullable=False, index=True, comment='任務唯一識別碼')
    user_id = db.Column(db.Integer, db.ForeignKey('dt_users.id'), nullable=False, comment='使用者ID')
    original_filename = db.Column(db.String(500), nullable=False, comment='原始檔名')
    file_extension = db.Column(db.String(10), nullable=False, comment='檔案副檔名')
    file_size = db.Column(db.BigInteger, nullable=False, comment='檔案大小(bytes)')
    file_path = db.Column(db.String(1000), nullable=False, comment='檔案路徑')
    source_language = db.Column(db.String(50), default=None, comment='來源語言')
    target_languages = db.Column(db.JSON, nullable=False, comment='目標語言陣列')
    status = db.Column(
        db.Enum('PENDING', 'PROCESSING', 'COMPLETED', 'FAILED', 'RETRY', name='job_status'), 
        default='PENDING', 
        comment='任務狀態'
    )
    progress = db.Column(db.Numeric(5, 2), default=0.00, comment='處理進度(%)')
    retry_count = db.Column(db.Integer, default=0, comment='重試次數')
    error_message = db.Column(db.Text, comment='錯誤訊息')
    total_tokens = db.Column(db.Integer, default=0, comment='總token數')
    total_cost = db.Column(db.Numeric(10, 4), default=0.0000, comment='總成本')
    processing_started_at = db.Column(db.DateTime, comment='開始處理時間')
    completed_at = db.Column(db.DateTime, comment='完成時間')
    created_at = db.Column(db.DateTime, default=func.now(), comment='建立時間')
    updated_at = db.Column(
        db.DateTime, 
        default=func.now(), 
        onupdate=func.now(), 
        comment='更新時間'
    )
    
    # 關聯關係
    files = db.relationship('JobFile', backref='job', lazy='dynamic', cascade='all, delete-orphan')
    api_usage_stats = db.relationship('APIUsageStats', backref='job', lazy='dynamic')
    
    def __repr__(self):
        return f'<TranslationJob {self.job_uuid}>'
    
    def __init__(self, **kwargs):
        """初始化，自動生成 UUID"""
        super().__init__(**kwargs)
        if not self.job_uuid:
            self.job_uuid = str(uuid.uuid4())
    
    def to_dict(self, include_files=False):
        """轉換為字典格式"""
        data = {
            'id': self.id,
            'job_uuid': self.job_uuid,
            'user_id': self.user_id,
            'original_filename': self.original_filename,
            'file_extension': self.file_extension,
            'file_size': self.file_size,
            'file_path': self.file_path,
            'source_language': self.source_language,
            'target_languages': self.target_languages,
            'status': self.status,
            'progress': float(self.progress) if self.progress else 0.0,
            'retry_count': self.retry_count,
            'error_message': self.error_message,
            'total_tokens': self.total_tokens,
            'total_cost': float(self.total_cost) if self.total_cost else 0.0,
            'processing_started_at': format_taiwan_time(self.processing_started_at, "%Y-%m-%d %H:%M:%S") if self.processing_started_at else None,
            'completed_at': format_taiwan_time(self.completed_at, "%Y-%m-%d %H:%M:%S") if self.completed_at else None,
            'created_at': format_taiwan_time(self.created_at, "%Y-%m-%d %H:%M:%S") if self.created_at else None,
            'updated_at': format_taiwan_time(self.updated_at, "%Y-%m-%d %H:%M:%S") if self.updated_at else None
        }
        
        if include_files:
            data['files'] = [f.to_dict() for f in self.files]
        
        return data
    
    def update_status(self, status, error_message=None, progress=None):
        """更新任務狀態"""
        self.status = status
        
        if error_message:
            self.error_message = error_message
        
        if progress is not None:
            self.progress = progress
        
        if status == 'PROCESSING' and not self.processing_started_at:
            self.processing_started_at = datetime.utcnow()
        elif status == 'COMPLETED':
            self.completed_at = datetime.utcnow()
            self.progress = 100.00
        
        self.updated_at = datetime.utcnow()
        db.session.commit()
    
    def add_original_file(self, filename, file_path, file_size):
        """新增原始檔案記錄"""
        original_file = JobFile(
            job_id=self.id,
            file_type='ORIGINAL',
            filename=filename,
            file_path=file_path,
            file_size=file_size
        )
        db.session.add(original_file)
        db.session.commit()
        return original_file
    
    def add_translated_file(self, language_code, filename, file_path, file_size):
        """新增翻譯檔案記錄"""
        translated_file = JobFile(
            job_id=self.id,
            file_type='TRANSLATED',
            language_code=language_code,
            filename=filename,
            file_path=file_path,
            file_size=file_size
        )
        db.session.add(translated_file)
        db.session.commit()
        return translated_file
    
    def get_translated_files(self):
        """取得翻譯檔案"""
        return self.files.filter_by(file_type='TRANSLATED').all()
    
    def get_original_file(self):
        """取得原始檔案"""
        return self.files.filter_by(file_type='ORIGINAL').first()
    
    def can_retry(self):
        """是否可以重試"""
        return self.status in ['FAILED', 'RETRY'] and self.retry_count < 3
    
    def increment_retry(self):
        """增加重試次數"""
        self.retry_count += 1
        self.updated_at = datetime.utcnow()
        db.session.commit()
    
    @classmethod
    def get_queue_position(cls, job_uuid):
        """取得任務在佇列中的位置"""
        job = cls.query.filter_by(job_uuid=job_uuid).first()
        if not job:
            return None
        
        position = cls.query.filter(
            cls.status == 'PENDING',
            cls.created_at < job.created_at
        ).count()
        
        return position + 1
    
    @classmethod
    def get_pending_jobs(cls):
        """取得所有等待處理的任務"""
        return cls.query.filter_by(status='PENDING').order_by(cls.created_at.asc()).all()
    
    @classmethod
    def get_processing_jobs(cls):
        """取得所有處理中的任務"""
        return cls.query.filter_by(status='PROCESSING').all()
    
    @classmethod
    def get_user_jobs(cls, user_id, status=None, limit=None, offset=None):
        """取得使用者的任務列表"""
        query = cls.query.filter_by(user_id=user_id)
        
        if status and status != 'all':
            query = query.filter_by(status=status.upper())
        
        query = query.order_by(cls.created_at.desc())
        
        if limit:
            query = query.limit(limit)
        if offset:
            query = query.offset(offset)
        
        return query.all()
    
    @classmethod
    def get_statistics(cls, user_id=None, start_date=None, end_date=None):
        """取得統計資料"""
        query = cls.query
        
        if user_id:
            query = query.filter_by(user_id=user_id)
        
        if start_date:
            query = query.filter(cls.created_at >= start_date)
        
        if end_date:
            query = query.filter(cls.created_at <= end_date)
        
        total = query.count()
        completed = query.filter_by(status='COMPLETED').count()
        failed = query.filter_by(status='FAILED').count()
        processing = query.filter_by(status='PROCESSING').count()
        pending = query.filter_by(status='PENDING').count()
        
        return {
            'total': total,
            'completed': completed,
            'failed': failed,
            'processing': processing,
            'pending': pending,
            'success_rate': (completed / total * 100) if total > 0 else 0
        }


class JobFile(db.Model):
    """檔案記錄表 (dt_job_files)"""
    __tablename__ = 'dt_job_files'
    
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    job_id = db.Column(db.Integer, db.ForeignKey('dt_translation_jobs.id'), nullable=False, comment='任務ID')
    file_type = db.Column(
        db.Enum('ORIGINAL', 'TRANSLATED', name='file_type'), 
        nullable=False, 
        comment='檔案類型'
    )
    language_code = db.Column(db.String(50), comment='語言代碼(翻譯檔案)')
    filename = db.Column(db.String(500), nullable=False, comment='檔案名稱')
    file_path = db.Column(db.String(1000), nullable=False, comment='檔案路徑')
    file_size = db.Column(db.BigInteger, nullable=False, comment='檔案大小')
    created_at = db.Column(db.DateTime, default=func.now(), comment='建立時間')
    
    def __repr__(self):
        return f'<JobFile {self.filename}>'
    
    def to_dict(self):
        """轉換為字典格式"""
        return {
            'id': self.id,
            'job_id': self.job_id,
            'file_type': self.file_type,
            'language_code': self.language_code,
            'filename': self.filename,
            'file_path': self.file_path,
            'file_size': self.file_size,
            'created_at': format_taiwan_time(self.created_at, "%Y-%m-%d %H:%M:%S") if self.created_at else None
        }


# 事件監聽器：自動生成 UUID
@event.listens_for(TranslationJob, 'before_insert')
def receive_before_insert(mapper, connection, target):
    """在插入前自動生成 UUID"""
    if not target.job_uuid:
        target.job_uuid = str(uuid.uuid4())