import logging
from fastapi import APIRouter, Query
from sqlmodel import Session
from src.config.database import engine
from src.models.entities import CanvasDB
from src.models.schemas import ResponseModel, CanvasState
from src.mappers import CanvasMapper
from src.utils.errors import BusinessException, ErrorCode

router = APIRouter(tags=["canvas"])
logger = logging.getLogger(__name__)

@router.get("/canvas", response_model=ResponseModel)
async def get_canvas_state(id: str = "default", projectId: str = Query(None)):
    """Get canvas state by ID
    
    Returns empty default state if canvas not found.
    
    Raises:
        BusinessException: Failed to fetch canvas
    """
    try:
        with Session(engine) as session:
            canvas_db = session.get(CanvasDB, id)
            
            if not canvas_db:
                # If not found, return empty default state
                return ResponseModel(data=CanvasState(id=id, projectId=projectId))
                
            # Map to CanvasState
            canvas_state = CanvasState(
                id=canvas_db.id,
                projectId=canvas_db.project_id,
                nodes=canvas_db.nodes,
                connections=canvas_db.connections,
                groups=canvas_db.groups,
                history=canvas_db.history,
                historyIndex=canvas_db.history_index, 
                updated_at=canvas_db.updated_at
            )
            return ResponseModel(data=canvas_state)
    except Exception as e:
        logger.error(f"Failed to fetch canvas {id}: {e}", exc_info=True)
        raise BusinessException(
            ErrorCode.CANVAS_NOT_FOUND,
            "Failed to fetch canvas state",
            {"canvas_id": id, "reason": str(e)}
        )

@router.post("/canvas", response_model=ResponseModel)
async def save_canvas_state(state: CanvasState):
    """Save canvas state
    
    Raises:
        BusinessException: Failed to save canvas
    """
    try:
        with Session(engine) as session:
            # Use merge to handle both insert and update gracefully
            canvas_db = CanvasDB(
                id=state.id,
                project_id=state.projectId,
                nodes=state.nodes,
                connections=state.connections,
                groups=state.groups,
                history=state.history,
                history_index=state.history_index,
                updated_at=state.updated_at
            )
            
            session.merge(canvas_db)
            session.commit()
            
            return ResponseModel(data={"id": state.id, "updated": True})
    except Exception as e:
        logger.error(f"Failed to save canvas {state.id}: {e}", exc_info=True)
        raise BusinessException(
            ErrorCode.UNKNOWN_ERROR,
            "Failed to save canvas state",
            {"canvas_id": state.id, "reason": str(e)}
        )
