"""Workspace git API endpoints."""

import uuid

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from src.auth.dependencies import get_current_user_id, get_db_session
from src.models import Workspace
from src.services.git.git_operations import GitOperations

router = APIRouter(prefix="/workspaces/{workspace_id}/git")


async def _get_workspace(
    session: AsyncSession,
    workspace_id: uuid.UUID,
    user_id: uuid.UUID,
) -> Workspace:
    from sqlalchemy import select

    result = await session.execute(
        select(Workspace).where(
            Workspace.id == workspace_id,
            Workspace.user_id == user_id,
        )
    )
    workspace = result.scalar_one_or_none()
    if not workspace:
        raise HTTPException(status_code=404, detail="Workspace not found")
    return workspace


@router.get("/status")
async def git_status(
    workspace_id: uuid.UUID,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Get git status for the workspace."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    git = GitOperations(workspace)
    try:
        status = await git.status()
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {
        "branch": status.branch,
        "modified": status.modified,
        "added": status.added,
        "deleted": status.deleted,
        "untracked": status.untracked,
        "ahead": status.ahead,
        "behind": status.behind,
    }


@router.get("/branches")
async def git_branches(
    workspace_id: uuid.UUID,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """List branches for the workspace."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    git = GitOperations(workspace)
    try:
        branches, current = await git.branches()
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {
        "branches": branches,
        "current_branch": current,
    }


@router.post("/commit")
async def git_commit(
    workspace_id: uuid.UUID,
    data: dict,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Stage all changes and commit."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    message = data.get("message", "").strip()
    if not message:
        raise HTTPException(status_code=400, detail="Commit message is required")

    git = GitOperations(workspace)
    try:
        await git.commit(message)
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {"status": "committed"}


@router.post("/push")
async def git_push(
    workspace_id: uuid.UUID,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Push current branch."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    git = GitOperations(workspace)
    try:
        await git.push()
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {"status": "pushed"}


@router.post("/pull")
async def git_pull(
    workspace_id: uuid.UUID,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Pull current branch."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    git = GitOperations(workspace)
    try:
        await git.pull()
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {"status": "pulled"}


@router.post("/fetch")
async def git_fetch(
    workspace_id: uuid.UUID,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Fetch from origin."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    git = GitOperations(workspace)
    try:
        await git.fetch()
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {"status": "fetched"}


@router.post("/checkout")
async def git_checkout(
    workspace_id: uuid.UUID,
    data: dict,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Checkout a branch."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    branch = data.get("branch", "").strip()
    if not branch:
        raise HTTPException(status_code=400, detail="Branch name is required")

    git = GitOperations(workspace)
    try:
        await git.checkout(branch)
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    workspace.branch = branch
    await session.commit()

    return {"status": "checked_out", "branch": branch}


@router.get("/history")
async def git_history(
    workspace_id: uuid.UUID,
    path: str | None = None,
    limit: int = 50,
    user_id: uuid.UUID = Depends(get_current_user_id),
    session: AsyncSession = Depends(get_db_session),
) -> dict:
    """Get commit history."""
    workspace = await _get_workspace(session, workspace_id, user_id)
    git = GitOperations(workspace)
    try:
        commits = await git.history(path, limit)
    except RuntimeError as exc:
        raise HTTPException(status_code=500, detail=str(exc)) from exc

    return {
        "commits": [
            {
                "hash": c.hash,
                "message": c.message,
                "author": c.author,
                "date": c.date,
            }
            for c in commits
        ],
    }
