from typing import Any, List, Optional
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query, UploadFile, File
from fastapi.responses import FileResponse
from sqlalchemy.orm import Session
from sqlalchemy import desc, asc
from app.api.v1 import deps
from app.schemas.backup import (
    BackupRecord, 
    BackupSettings, 
    BackupSettingsUpdate, 
    BackupRecordList,
    RestorePreviewResponse,
    RestoreRequest,
    SendSmsRequest
)
from app.models.backup import BackupRecord as BackupRecordModel
from app.services.backup_service import BackupService
from app.models.user import User, UserRole

router = APIRouter()

@router.post("/create", response_model=BackupRecord)
def create_backup(
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """
    Manually create a backup.
    """
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
         
    return BackupService.create_backup(db)

@router.post("/upload", response_model=BackupRecord)
def upload_backup(
    file: UploadFile = File(...),
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
    
    content = file.file.read()
    return BackupService.save_uploaded_backup(db, content, file.filename)

@router.get("/", response_model=BackupRecordList)
def read_backups(
    skip: int = 0,
    limit: int = 20,
    start_date: Optional[str] = None, # YYYY-MM-DD
    end_date: Optional[str] = None,   # YYYY-MM-DD
    sort_order: str = "desc", # "desc" or "asc"
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    """
    Retrieve backup records with pagination, filtering and sorting.
    """
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
    
    query = db.query(BackupRecordModel)
    
    if start_date:
        try:
            start_dt = datetime.strptime(start_date, "%Y-%m-%d")
            query = query.filter(BackupRecordModel.created_at >= start_dt)
        except ValueError:
            pass # Ignore invalid date format
            
    if end_date:
        try:
            end_dt = datetime.strptime(end_date, "%Y-%m-%d")
            end_dt = end_dt.replace(hour=23, minute=59, second=59)
            query = query.filter(BackupRecordModel.created_at <= end_dt)
        except ValueError:
            pass

    total = query.count()
    
    if sort_order == "asc":
        query = query.order_by(asc(BackupRecordModel.created_at))
    else:
        query = query.order_by(desc(BackupRecordModel.created_at))
        
    items = query.offset(skip).limit(limit).all()
    
    return {"total": total, "items": items}

@router.get("/settings", response_model=BackupSettings)
def read_backup_settings(
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
    return BackupService.get_settings(db)

@router.put("/settings", response_model=BackupSettings)
def update_backup_settings(
    settings_in: BackupSettingsUpdate,
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
) -> Any:
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
    return BackupService.update_settings(db, settings_in.auto_backup_enabled, settings_in.backup_time)

@router.get("/download/{id}")
def download_backup(
    id: int,
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
):
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
    
    backup = db.query(BackupRecordModel).filter(BackupRecordModel.id == id).first()
    if not backup:
        raise HTTPException(status_code=404, detail="Backup not found")
        
    return FileResponse(backup.file_path, filename=backup.filename, media_type='application/zip')

@router.get("/{id}/restore/preview", response_model=RestorePreviewResponse)
def preview_restore(
    id: int,
    type: str, # APPLICATIONS, USERS, MAPPINGS
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
):
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
         
    return BackupService.preview_restore(db, id, type)

@router.post("/send-sms")
def send_restore_sms(
    req: SendSmsRequest,
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
):
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
    
    BackupService.send_restore_sms(req.captcha_id, req.captcha_code, current_user)
    return {"message": "短信验证码已发送"}

@router.post("/{id}/restore")
def restore_backup(
    id: int,
    request: RestoreRequest,
    db: Session = Depends(deps.get_db),
    current_user: User = Depends(deps.get_current_active_user),
):
    if current_user.role != UserRole.SUPER_ADMIN:
         raise HTTPException(status_code=403, detail="Not enough permissions")
         
    return BackupService.restore_data(
        db, 
        current_user, 
        id, 
        request.restore_type, 
        request.field_mapping,
        request.password,
        request.sms_code,
        request.selected_files
    )
