from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from app.services.arduino_cli import ArduinoCLIService

router = APIRouter()
arduino_cli = ArduinoCLIService()


class SketchFile(BaseModel):
    name: str
    content: str


class CompileRequest(BaseModel):
    # New multi-file API
    files: list[SketchFile] | None = None
    # Legacy single-file API (kept for backward compat)
    code: str | None = None
    board_fqbn: str = "arduino:avr:uno"


class CompileResponse(BaseModel):
    success: bool
    hex_content: str | None = None
    binary_content: str | None = None  # base64-encoded .bin for RP2040
    binary_type: str | None = None     # 'bin' or 'uf2'
    stdout: str
    stderr: str
    error: str | None = None
    core_install_log: str | None = None


@router.post("/", response_model=CompileResponse)
async def compile_sketch(request: CompileRequest):
    """
    Compile Arduino sketch and return hex/binary.
    Accepts either `files` (multi-file) or legacy `code` (single file).
    Auto-installs the required board core if not present.
    """
    # Resolve files list
    if request.files:
        files = [{"name": f.name, "content": f.content} for f in request.files]
    elif request.code is not None:
        files = [{"name": "sketch.ino", "content": request.code}]
    else:
        raise HTTPException(
            status_code=422,
            detail="Provide either 'files' or 'code' in the request body.",
        )

    try:
        core_status = await arduino_cli.ensure_core_for_board(request.board_fqbn)
        core_log = core_status.get("log", "")

        if core_status.get("needed") and not core_status.get("installed"):
            return CompileResponse(
                success=False,
                stdout="",
                stderr=core_log,
                error=f"Failed to install required core: {core_status.get('core_id')}",
            )

        result = await arduino_cli.compile(files, request.board_fqbn)
        return CompileResponse(
            success=result["success"],
            hex_content=result.get("hex_content"),
            binary_content=result.get("binary_content"),
            binary_type=result.get("binary_type"),
            stdout=result.get("stdout", ""),
            stderr=result.get("stderr", ""),
            error=result.get("error"),
            core_install_log=core_log if core_log else None,
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/setup-status")
async def setup_status():
    return await arduino_cli.get_setup_status()


@router.post("/ensure-core")
async def ensure_core(request: CompileRequest):
    fqbn = request.board_fqbn
    result = await arduino_cli.ensure_core_for_board(fqbn)
    return result


@router.get("/boards")
async def list_boards():
    boards = await arduino_cli.list_boards()
    return {"boards": boards}
