"""API router for import/sync operations between OpenSpec and Beads."""

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel

from hangar.dependencies import get_importsync_service
from hangar.services.importsync import ImportSyncService

router = APIRouter(prefix="/api/sync", tags=["sync"])


# ── Request/Response models ────────────────────────────────────────


class ImportRequest(BaseModel):
    tasks: list[str]  # task numbers to import
    dependencies: list[tuple[str, str]]  # confirmed (from, to) edges


class ParsedTaskResponse(BaseModel):
    number: str
    title: str
    phase: str
    phase_index: int
    checked: bool
    beads_id: str | None
    test_hint: str | None


class SuggestedDepResponse(BaseModel):
    from_number: str
    to_number: str
    reason: str


class ImportPreviewResponse(BaseModel):
    change_name: str
    tasks: list[ParsedTaskResponse]
    suggested_deps: list[SuggestedDepResponse]
    already_imported: list[str]
    to_import: list[str]


class ImportResultResponse(BaseModel):
    created: list[tuple[str, str]]
    deps_wired: int
    tasks_md_updated: bool


class SyncResultResponse(BaseModel):
    synced: list[tuple[str, str]]
    tasks_md_updated: bool


class ChangeCompletionResponse(BaseModel):
    change_name: str
    total: int
    closed: int
    in_progress: int
    open: int


# ── Endpoints ──────────────────────────────────────────────────────


@router.get("/{change_name}/preview")
async def preview_import(
    change_name: str,
    service: ImportSyncService = Depends(get_importsync_service),
) -> ImportPreviewResponse:
    """Parse tasks.md, show what would be imported."""
    try:
        preview = await service.preview_import(change_name)
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e))
    return ImportPreviewResponse(
        change_name=preview.change_name,
        tasks=[
            ParsedTaskResponse(
                number=t.number,
                title=t.title,
                phase=t.phase,
                phase_index=t.phase_index,
                checked=t.checked,
                beads_id=t.beads_id,
                test_hint=t.test_hint,
            )
            for t in preview.tasks
        ],
        suggested_deps=[
            SuggestedDepResponse(
                from_number=d.from_number,
                to_number=d.to_number,
                reason=d.reason,
            )
            for d in preview.suggested_deps
        ],
        already_imported=preview.already_imported,
        to_import=preview.to_import,
    )


@router.post("/{change_name}/import")
async def execute_import(
    change_name: str,
    body: ImportRequest,
    service: ImportSyncService = Depends(get_importsync_service),
) -> ImportResultResponse:
    """Execute confirmed import — creates beads tasks, wires deps, stamps IDs."""
    try:
        result = await service.execute_import(
            change_name,
            task_numbers=body.tasks,
            dependencies=body.dependencies,
        )
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e))
    return ImportResultResponse(
        created=result.created,
        deps_wired=result.deps_wired,
        tasks_md_updated=result.tasks_md_updated,
    )


@router.post("/{change_name}/sync")
async def sync_status(
    change_name: str,
    service: ImportSyncService = Depends(get_importsync_service),
) -> SyncResultResponse:
    """Sync beads status to tasks.md checkboxes."""
    try:
        result = await service.sync_status(change_name)
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e))
    return SyncResultResponse(
        synced=result.synced,
        tasks_md_updated=result.tasks_md_updated,
    )


@router.get("/{change_name}/completion")
async def get_completion(
    change_name: str,
    service: ImportSyncService = Depends(get_importsync_service),
) -> ChangeCompletionResponse:
    """Get beads-sourced completion stats for a change."""
    try:
        completion = await service.get_change_completion(change_name)
    except ValueError as e:
        raise HTTPException(status_code=422, detail=str(e))
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except RuntimeError as e:
        raise HTTPException(status_code=502, detail=str(e))
    return ChangeCompletionResponse(
        change_name=completion.change_name,
        total=completion.total,
        closed=completion.closed,
        in_progress=completion.in_progress,
        open=completion.open,
    )
