# #region DashboardActionRoutes [C:2] [TYPE Module] [SEMANTICS fastapi, dashboard, api, backup]
# @BRIEF Dashboard action route handlers — migrate, backup.
# @LAYER API
# @RELATION DEPENDS_ON -> [EXT:frontend:DashboardRouter]]
# @RELATION DEPENDS_ON -> [DashboardSchemas]

from fastapi import Depends, HTTPException

from src.core.logger import belief_scope, logger
from src.dependencies import (
    get_config_manager,
    get_task_manager,
    has_permission,
)

from ._router import router
from ._schemas import (
    BackupRequest,
    MigrateRequest,
    TaskResponse,
)


# #region migrate_dashboards [C:2] [TYPE Function]
# @BRIEF Trigger bulk migration of dashboards from source to target environment
# @PRE  User has permission plugin:migration:execute
# @PRE  source_env_id and target_env_id are valid environment IDs
# @PRE  dashboard_ids is a non-empty list
# @POST  Returns task_id for tracking migration progress
# @POST  Task is created and queued for execution
# @RELATION DISPATCHES -> [EXT:method:MigrationPlugin:execute]
# @RELATION CALLS -> [TaskManager]
@router.post("/migrate", response_model=TaskResponse)
async def migrate_dashboards(
    request: MigrateRequest,
    config_manager=Depends(get_config_manager),
    task_manager=Depends(get_task_manager),
    _=Depends(has_permission("plugin:migration", "EXECUTE")),
):
    with belief_scope(
        "migrate_dashboards",
        f"source={request.source_env_id}, target={request.target_env_id}, count={len(request.dashboard_ids)}",
    ):
        if not request.dashboard_ids:
            logger.error(
                "[migrate_dashboards][Coherence:Failed] No dashboard IDs provided"
            )
            raise HTTPException(
                status_code=400, detail="At least one dashboard ID must be provided"
            )

        environments = config_manager.get_environments()
        source_env = next(
            (e for e in environments if e.id == request.source_env_id), None
        )
        target_env = next(
            (e for e in environments if e.id == request.target_env_id), None
        )

        if not source_env:
            logger.error(
                f"[migrate_dashboards][Coherence:Failed] Source environment not found: {request.source_env_id}"
            )
            raise HTTPException(status_code=404, detail="Source environment not found")
        if not target_env:
            logger.error(
                f"[migrate_dashboards][Coherence:Failed] Target environment not found: {request.target_env_id}"
            )
            raise HTTPException(status_code=404, detail="Target environment not found")

        try:
            task_params = {
                "source_env_id": request.source_env_id,
                "target_env_id": request.target_env_id,
                "selected_ids": request.dashboard_ids,
                "replace_db_config": request.replace_db_config,
                "db_mappings": request.db_mappings or {},
            }

            task_obj = await task_manager.create_task(
                plugin_id="superset-migration", params=task_params
            )

            logger.info(
                f"[migrate_dashboards][Coherence:OK] Migration task created: {task_obj.id} for {len(request.dashboard_ids)} dashboards"
            )

            return TaskResponse(task_id=str(task_obj.id))

        except Exception as e:
            logger.error(
                f"[migrate_dashboards][Coherence:Failed] Failed to create migration task: {e}"
            )
            raise HTTPException(
                status_code=503, detail=f"Failed to create migration task: {e!s}"
            )


# #endregion migrate_dashboards


# #region backup_dashboards [C:2] [TYPE Function]
# @BRIEF Trigger bulk backup of dashboards with optional cron schedule
# @PRE  User has permission plugin:backup:execute
# @PRE  env_id is a valid environment ID
# @PRE  dashboard_ids is a non-empty list
# @POST  Returns task_id for tracking backup progress
# @POST  Task is created and queued for execution
# @POST  If schedule is provided, a scheduled task is created
# @RELATION DISPATCHES -> [EXT:method:BackupPlugin:execute]
# @RELATION CALLS -> [TaskManager]
@router.post("/backup", response_model=TaskResponse)
async def backup_dashboards(
    request: BackupRequest,
    config_manager=Depends(get_config_manager),
    task_manager=Depends(get_task_manager),
    _=Depends(has_permission("plugin:backup", "EXECUTE")),
):
    with belief_scope(
        "backup_dashboards",
        f"env={request.env_id}, count={len(request.dashboard_ids)}, schedule={request.schedule}",
    ):
        if not request.dashboard_ids:
            logger.error(
                "[backup_dashboards][Coherence:Failed] No dashboard IDs provided"
            )
            raise HTTPException(
                status_code=400, detail="At least one dashboard ID must be provided"
            )

        environments = config_manager.get_environments()
        env = next((e for e in environments if e.id == request.env_id), None)

        if not env:
            logger.error(
                f"[backup_dashboards][Coherence:Failed] Environment not found: {request.env_id}"
            )
            raise HTTPException(status_code=404, detail="Environment not found")

        try:
            task_params = {
                "env": request.env_id,
                "dashboards": request.dashboard_ids,
                "schedule": request.schedule,
            }

            task_obj = await task_manager.create_task(
                plugin_id="superset-backup", params=task_params
            )

            logger.info(
                f"[backup_dashboards][Coherence:OK] Backup task created: {task_obj.id} for {len(request.dashboard_ids)} dashboards"
            )

            return TaskResponse(task_id=str(task_obj.id))

        except Exception as e:
            logger.error(
                f"[backup_dashboards][Coherence:Failed] Failed to create backup task: {e}"
            )
            raise HTTPException(
                status_code=503, detail=f"Failed to create backup task: {e!s}"
            )


# #endregion backup_dashboards
# #endregion DashboardActionRoutes
