#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
驗證工具模組

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

import os
from pathlib import Path
from flask import current_app
from .exceptions import ValidationError


def validate_file(file_obj):
    """驗證上傳的檔案"""
    if not file_obj:
        raise ValidationError("未選擇檔案", "NO_FILE")
    
    if not file_obj.filename:
        raise ValidationError("檔案名稱為空", "NO_FILENAME")
    
    # 檢查檔案副檔名
    file_ext = Path(file_obj.filename).suffix.lower()
    allowed_extensions = current_app.config.get('ALLOWED_EXTENSIONS', {'.docx', '.doc', '.pptx', '.xlsx', '.xls', '.pdf'})
    
    if file_ext not in allowed_extensions:
        raise ValidationError(
            f"不支援的檔案類型: {file_ext}，支援的格式: {', '.join(allowed_extensions)}", 
            "INVALID_FILE_TYPE"
        )
    
    # 檢查檔案大小
    max_size = current_app.config.get('MAX_CONTENT_LENGTH', 26214400)  # 25MB
    
    # 取得檔案大小
    file_obj.seek(0, os.SEEK_END)
    file_size = file_obj.tell()
    file_obj.seek(0)
    
    if file_size > max_size:
        raise ValidationError(
            f"檔案大小超過限制 ({format_file_size(max_size)})", 
            "FILE_TOO_LARGE"
        )
    
    if file_size == 0:
        raise ValidationError("檔案為空", "EMPTY_FILE")
    
    return {
        'filename': file_obj.filename,
        'file_extension': file_ext,
        'file_size': file_size,
        'valid': True
    }


def validate_languages(source_language, target_languages):
    """驗證語言設定"""
    # 支援的語言列表
    supported_languages = {
        'auto': '自動偵測',
        'zh-CN': '簡體中文',
        'zh-TW': '繁體中文',
        'en': '英文',
        'ja': '日文',
        'ko': '韓文',
        'vi': '越南文',
        'th': '泰文',
        'id': '印尼文',
        'ms': '馬來文',
        'es': '西班牙文',
        'fr': '法文',
        'de': '德文',
        'ru': '俄文'
    }
    
    # 驗證來源語言
    if source_language and source_language not in supported_languages:
        raise ValidationError(
            f"不支援的來源語言: {source_language}", 
            "INVALID_SOURCE_LANGUAGE"
        )
    
    # 驗證目標語言
    if not target_languages or not isinstance(target_languages, list):
        raise ValidationError("必須指定至少一個目標語言", "NO_TARGET_LANGUAGES")
    
    if len(target_languages) == 0:
        raise ValidationError("必須指定至少一個目標語言", "NO_TARGET_LANGUAGES")
    
    if len(target_languages) > 10:  # 限制最多10個目標語言
        raise ValidationError("目標語言數量過多，最多支援10個", "TOO_MANY_TARGET_LANGUAGES")
    
    invalid_languages = [lang for lang in target_languages if lang not in supported_languages]
    if invalid_languages:
        raise ValidationError(
            f"不支援的目標語言: {', '.join(invalid_languages)}", 
            "INVALID_TARGET_LANGUAGE"
        )
    
    # 檢查來源語言和目標語言是否有重疊
    if source_language and source_language != 'auto' and source_language in target_languages:
        raise ValidationError(
            "目標語言不能包含來源語言", 
            "SOURCE_TARGET_OVERLAP"
        )
    
    return {
        'source_language': source_language or 'auto',
        'target_languages': target_languages,
        'supported_languages': supported_languages,
        'valid': True
    }


def validate_job_uuid(job_uuid):
    """驗證任務UUID格式"""
    import uuid
    
    if not job_uuid:
        raise ValidationError("任務UUID不能為空", "INVALID_UUID")
    
    try:
        uuid.UUID(job_uuid)
        return True
    except ValueError:
        raise ValidationError("任務UUID格式錯誤", "INVALID_UUID")


def validate_pagination(page, per_page):
    """驗證分頁參數"""
    try:
        page = int(page) if page else 1
        per_page = int(per_page) if per_page else 20
    except (ValueError, TypeError):
        raise ValidationError("分頁參數必須為數字", "INVALID_PAGINATION")
    
    if page < 1:
        raise ValidationError("頁數必須大於0", "INVALID_PAGE")
    
    if per_page < 1 or per_page > 100:
        raise ValidationError("每頁項目數必須在1-100之間", "INVALID_PER_PAGE")
    
    return page, per_page


def format_file_size(size_bytes):
    """格式化檔案大小顯示"""
    if size_bytes == 0:
        return "0 B"
    
    size_names = ["B", "KB", "MB", "GB", "TB"]
    i = 0
    while size_bytes >= 1024 and i < len(size_names) - 1:
        size_bytes /= 1024.0
        i += 1
    
    return f"{size_bytes:.1f} {size_names[i]}"


def sanitize_filename(filename):
    """清理檔案名稱，移除不安全字元"""
    import re
    
    # 保留檔案名稱和副檔名
    name = Path(filename).stem
    ext = Path(filename).suffix
    
    # 移除或替換不安全字元
    safe_name = re.sub(r'[^\w\s.-]', '_', name)
    safe_name = re.sub(r'\s+', '_', safe_name)  # 空白替換為底線
    safe_name = safe_name.strip('._')  # 移除開頭結尾的點和底線
    
    # 限制長度
    if len(safe_name) > 100:
        safe_name = safe_name[:100]
    
    return f"{safe_name}{ext}"


def validate_date_range(start_date, end_date):
    """驗證日期範圍"""
    from datetime import datetime
    
    if start_date:
        try:
            start_date = datetime.fromisoformat(start_date.replace('Z', '+00:00'))
        except ValueError:
            raise ValidationError("開始日期格式錯誤", "INVALID_START_DATE")
    
    if end_date:
        try:
            end_date = datetime.fromisoformat(end_date.replace('Z', '+00:00'))
        except ValueError:
            raise ValidationError("結束日期格式錯誤", "INVALID_END_DATE")
    
    if start_date and end_date and start_date > end_date:
        raise ValidationError("開始日期不能晚於結束日期", "INVALID_DATE_RANGE")
    
    return start_date, end_date