"""
Downloads Routes - File-centric RESTful API for download management.
Each endpoint operates on individual file downloads, not batches.
"""

from fastapi import APIRouter, HTTPException, Query
from pydantic import BaseModel
from typing import List, Dict, Optional
import logging

from ..services import downloads_service

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api", tags=["Downloads"])


# ==================== REQUEST MODELS ====================

class FileInfo(BaseModel):
    """Single file information."""
    name: str
    path: str
    isdir: bool = False
    is_folder: Optional[bool] = None  # Alias for isdir


class CreateBatchRequest(BaseModel):
    """Request to create a batch of file downloads (API mode)."""
    files: List[FileInfo]
    ge_id: str
    lang: str


class CreateSharingBatchRequest(BaseModel):
    """Request to create batch downloads from sharing link."""
    sharing_id: str
    files: List[FileInfo]
    ge_id: Optional[str] = None
    lang: Optional[str] = None


class UpdateDownloadRequest(BaseModel):
    """Request to update a single download."""
    action: str  # "retry" or "cancel"


# ==================== DOWNLOAD ENDPOINTS ====================

@router.get('/downloads')
def get_all_downloads(
    status: Optional[str] = Query(None, description="Filter by status"),
    mode: Optional[str] = Query(
        None, description="Filter by mode (api/sharing)"),
    limit: int = Query(100, description="Max number of downloads to return")
):
    """
    Get all file downloads with optional filtering.

    Query params:
        - status: pending, downloading, completed, failed, cancelled
        - mode: api, sharing
        - limit: Max results (default: 100)

    Returns list of individual file downloads (not batched).
    Frontend groups by batch_id for display.
    """
    try:
        downloads = downloads_service.get_all_downloads(
            status=status,
            mode=mode,
            limit=limit
        )

        return {
            "success": True,
            "downloads": downloads,
            "count": len(downloads)
        }

    except Exception as e:
        logger.error(f"Error getting downloads: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.get('/downloads/{download_id}')
def get_download_by_id(download_id: int):
    """Get a single file download by ID."""
    try:
        download = downloads_service.get_download_by_id(download_id)

        if not download:
            raise HTTPException(
                status_code=404, detail="Download không tồn tại")

        return {
            "success": True,
            "download": download
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting download {download_id}: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.get('/batches/{batch_id}')
def get_batch_downloads(batch_id: str):
    """Get all downloads in a specific batch."""
    try:
        downloads = downloads_service.get_downloads_by_batch(batch_id)
        summary = downloads_service.get_batch_summary(batch_id)

        if not downloads:
            raise HTTPException(status_code=404, detail="Batch không tồn tại")

        return {
            "success": True,
            "batch": summary,
            "downloads": downloads,
            "count": len(downloads)
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting batch {batch_id}: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.post('/batches/api')
def create_api_batch(payload: CreateBatchRequest):
    """
    Create a batch of downloads for API mode (direct NAS access).
    Each file becomes a separate download record.
    """
    try:
        from ..common import get_download_destination_path
        from ..services import mongodb_service

        logger.debug(
            f"Creating API batch: {payload.ge_id}_{payload.lang}, {len(payload.files)} files")

        if not payload.files:
            raise HTTPException(
                status_code=400, detail="Không có file nào được chọn")

        # Get MongoDB path
        mongodb_path = mongodb_service.get_path_from_tms_data(
            payload.ge_id, payload.lang)

        # Calculate destination
        destination_path = get_download_destination_path(
            payload.ge_id, payload.lang)

        # Convert FileInfo to dicts
        files_data = [
            {
                "name": f.name,
                "path": f.path,
                "isdir": f.isdir or f.is_folder or False
            }
            for f in payload.files
        ]

        # Create batch
        result = downloads_service.create_downloads_batch(
            files=files_data,
            ge_id=payload.ge_id,
            lang=payload.lang,
            mode='api',
            mongodb_path=mongodb_path,
            destination_path=destination_path
        )

        if not result["success"]:
            raise HTTPException(status_code=500, detail=result["message"])

        logger.debug(
            f"Created API batch {result['batch_id']}: {result['file_count']} files")

        return {
            "success": True,
            "batch_id": result["batch_id"],
            "download_ids": result["download_ids"],
            "file_count": result["file_count"],
            "destination_path": destination_path,
            "mongodb_path": mongodb_path,
            "message": f"Đã tạo {result['file_count']} downloads"
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error creating API batch: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.post('/batches/sharing')
def create_sharing_batch(payload: CreateSharingBatchRequest):
    """
    Create a batch of downloads for Sharing mode (sharing link).
    Each file becomes a separate download record.
    """
    try:
        from ..common import get_download_destination_path
        from ..services import nas_service

        logger.debug(
            f"Creating Sharing batch: {payload.sharing_id}, {len(payload.files)} files")

        if not payload.files:
            raise HTTPException(
                status_code=400, detail="Không có file nào được chọn")

        # Determine GE ID and destination
        if payload.ge_id and payload.lang:
            from ..services import mongodb_service
            destination_path = get_download_destination_path(
                payload.ge_id, payload.lang)
            # For sharing mode, mongodb_path = sharing link (linkRaw) from MongoDB
            mongodb_path = mongodb_service.get_sharing_link_from_tms_data(
                payload.ge_id, payload.lang)
            ge_id = payload.ge_id
            lang = payload.lang
        else:
            destination_path = nas_service.DESTINATION_PATH
            mongodb_path = None
            ge_id = f"SHARING_{payload.sharing_id}"
            lang = "LINK"

        # Convert FileInfo to dicts
        files_data = [
            {
                "name": f.name,
                "path": f.path,
                "isdir": f.isdir or f.is_folder or False
            }
            for f in payload.files
        ]

        # Create batch
        result = downloads_service.create_downloads_batch(
            files=files_data,
            ge_id=ge_id,
            lang=lang,
            mode='sharing',
            sharing_id=payload.sharing_id,
            mongodb_path=mongodb_path,
            destination_path=destination_path
        )

        if not result["success"]:
            raise HTTPException(status_code=500, detail=result["message"])

        logger.debug(
            f"Created Sharing batch {result['batch_id']}: {result['file_count']} files")

        return {
            "success": True,
            "batch_id": result["batch_id"],
            "download_ids": result["download_ids"],
            "file_count": result["file_count"],
            "destination_path": destination_path,
            "sharing_id": payload.sharing_id,
            "message": f"Đã tạo {result['file_count']} downloads"
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error creating Sharing batch: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.patch('/downloads/{download_id}')
def update_download(download_id: int, payload: UpdateDownloadRequest):
    """
    Update a file download (cancel or retry).

    Actions:
        - "cancel": Cancel pending/downloading file
        - "retry": Retry failed file
    """
    try:
        if payload.action == "cancel":
            success = downloads_service.cancel_download(download_id)

            if success:
                return {
                    "success": True,
                    "message": f"Download {download_id} đã được hủy"
                }
            else:
                raise HTTPException(
                    status_code=404, detail="Download không tồn tại")

        elif payload.action == "retry":
            success = downloads_service.retry_download(download_id)

            if success:
                return {
                    "success": True,
                    "message": f"Download {download_id} đã được đưa vào queue"
                }
            else:
                raise HTTPException(
                    status_code=404, detail="Download không tồn tại")

        else:
            raise HTTPException(
                status_code=400,
                detail=f"Action không hợp lệ: {payload.action}. Chỉ chấp nhận 'cancel' hoặc 'retry'"
            )

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error updating download {download_id}: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.delete('/downloads/{download_id}')
def delete_download(download_id: int):
    """
    Delete a file download record.
    Only completed/failed/cancelled downloads can be deleted.
    """
    try:
        # Check download exists and status
        download = downloads_service.get_download_by_id(download_id)

        if not download:
            raise HTTPException(
                status_code=404, detail="Download không tồn tại")

        # Only delete terminal status
        if download["status"] not in ["completed", "failed", "cancelled"]:
            raise HTTPException(
                status_code=400,
                detail="Chỉ có thể xóa downloads đã hoàn thành hoặc thất bại"
            )

        success = downloads_service.delete_download(download_id)

        if success:
            return {
                "success": True,
                "message": f"Download {download_id} đã được xóa"
            }
        else:
            raise HTTPException(
                status_code=500, detail="Không thể xóa download")

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error deleting download {download_id}: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")


@router.delete('/batches/{batch_id}')
def delete_batch(batch_id: str):
    """
    Delete all downloads in a batch.
    Only works if all downloads are in terminal status.
    """
    try:
        # Check all downloads in batch
        downloads = downloads_service.get_downloads_by_batch(batch_id)

        if not downloads:
            raise HTTPException(status_code=404, detail="Batch không tồn tại")

        # Verify all are terminal
        active_count = sum(
            1 for d in downloads
            if d["status"] in ["pending", "downloading"]
        )

        if active_count > 0:
            raise HTTPException(
                status_code=400,
                detail=f"Batch còn {active_count} downloads đang active"
            )

        success = downloads_service.delete_batch(batch_id)

        if success:
            return {
                "success": True,
                "message": f"Batch {batch_id} đã được xóa ({len(downloads)} files)"
            }
        else:
            raise HTTPException(status_code=500, detail="Không thể xóa batch")

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error deleting batch {batch_id}: {e}")
        raise HTTPException(status_code=500, detail=f"Lỗi hệ thống: {str(e)}")
