"""
ファイルアップロード管理
"""
from fastapi import APIRouter, UploadFile, File, HTTPException
from pathlib import Path
import shutil
import uuid
from datetime import datetime

router = APIRouter(prefix="/files", tags=["File Upload"])

# アップロード先のベースディレクトリ
UPLOAD_BASE_DIR = Path("uploads")
UPLOAD_BASE_DIR.mkdir(exist_ok=True)

# 許可されるファイルタイプ
ALLOWED_EXTENSIONS = {
    'image': {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp'},
    'document': {'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.txt'},
}

def get_file_extension(filename: str) -> str:
    """ファイル拡張子を取得"""
    return Path(filename).suffix.lower()

def is_allowed_file(filename: str, file_type: str = None) -> bool:
    """許可されたファイルタイプか確認"""
    ext = get_file_extension(filename)
    if file_type == 'image':
        return ext in ALLOWED_EXTENSIONS['image']
    elif file_type == 'document':
        return ext in ALLOWED_EXTENSIONS['document']
    else:
        # すべての許可された拡張子
        all_extensions = set()
        for exts in ALLOWED_EXTENSIONS.values():
            all_extensions.update(exts)
        return ext in all_extensions

def generate_unique_filename(original_filename: str, prefix: str = "") -> str:
    """一意のファイル名を生成"""
    ext = get_file_extension(original_filename)
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    unique_id = str(uuid.uuid4())[:8]
    
    if prefix:
        return f"{prefix}_{timestamp}_{unique_id}{ext}"
    return f"{timestamp}_{unique_id}{ext}"

@router.post("/upload/employee/{employee_code}")
async def upload_employee_file(
    employee_code: str,
    file: UploadFile = File(...),
    file_type: str = "image"
):
    """
    従業員関連ファイルをアップロード
    
    Args:
        employee_code: 従業員コード
        file: アップロードするファイル
        file_type: ファイルタイプ (image, document)
    
    Returns:
        アップロードされたファイルのパス
    """
    # ファイルタイプチェック
    if not is_allowed_file(file.filename, file_type):
        raise HTTPException(
            status_code=400,
            detail=f"許可されていないファイル形式です。{file_type}タイプの許可される拡張子: {ALLOWED_EXTENSIONS.get(file_type, 'なし')}"
        )
    
    # 保存先ディレクトリ作成
    employee_dir = UPLOAD_BASE_DIR / "employees" / employee_code
    employee_dir.mkdir(parents=True, exist_ok=True)
    
    # 一意のファイル名生成
    unique_filename = generate_unique_filename(file.filename, employee_code)
    file_path = employee_dir / unique_filename
    
    # ファイル保存
    try:
        with file_path.open("wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"ファイル保存に失敗しました: {str(e)}")
    
    # 相対パスを返す（データベースに保存する値）
    relative_path = f"/uploads/employees/{employee_code}/{unique_filename}"
    
    return {
        "success": True,
        "file_path": relative_path,
        "filename": unique_filename,
        "original_filename": file.filename,
        "size": file_path.stat().st_size
    }

@router.post("/upload/general")
async def upload_general_file(
    file: UploadFile = File(...),
    category: str = "general"
):
    """
    一般ファイルをアップロード
    
    Args:
        file: アップロードするファイル
        category: カテゴリー (general, reports, temp など)
    
    Returns:
        アップロードされたファイルのパス
    """
    # ファイルタイプチェック
    if not is_allowed_file(file.filename):
        raise HTTPException(
            status_code=400,
            detail=f"許可されていないファイル形式です"
        )
    
    # 保存先ディレクトリ作成
    category_dir = UPLOAD_BASE_DIR / category
    category_dir.mkdir(parents=True, exist_ok=True)
    
    # 一意のファイル名生成
    unique_filename = generate_unique_filename(file.filename)
    file_path = category_dir / unique_filename
    
    # ファイル保存
    try:
        with file_path.open("wb") as buffer:
            shutil.copyfileobj(file.file, buffer)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"ファイル保存に失敗しました: {str(e)}")
    
    # 相対パスを返す
    relative_path = f"/uploads/{category}/{unique_filename}"
    
    return {
        "success": True,
        "file_path": relative_path,
        "filename": unique_filename,
        "original_filename": file.filename,
        "size": file_path.stat().st_size
    }

@router.delete("/delete")
async def delete_file(file_path: str):
    """
    ファイルを削除
    
    Args:
        file_path: 削除するファイルのパス (/uploads/... 形式)
    """
    # セキュリティ: パストラバーサル攻撃を防ぐ
    if ".." in file_path or file_path.startswith("/"):
        file_path = file_path.lstrip("/")
    
    full_path = Path(file_path)
    
    # uploadsディレクトリ内のファイルのみ削除可能
    if not str(full_path).startswith("uploads"):
        raise HTTPException(status_code=400, detail="無効なファイルパスです")
    
    if not full_path.exists():
        raise HTTPException(status_code=404, detail="ファイルが見つかりません")
    
    try:
        full_path.unlink()
        return {"success": True, "message": "ファイルを削除しました"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"ファイル削除に失敗しました: {str(e)}")
