"""Spaces API endpoints."""

from __future__ import annotations

import re
import sqlite3
from typing import Any

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel, field_validator

router = APIRouter(tags=["spaces"])

_NAME_PATTERN = re.compile(r"^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$")


class SpaceCreateRequest(BaseModel):
    name: str
    file_path: str
    file_hash: str = ""

    @field_validator("name")
    @classmethod
    def validate_name(cls, v: str) -> str:
        if not _NAME_PATTERN.match(v):
            raise ValueError(f"Invalid space name: {v!r}")
        return v

    @field_validator("file_path")
    @classmethod
    def validate_file_path(cls, v: str) -> str:
        if "/../" in v or v.startswith("../"):
            raise ValueError("Path traversal not allowed")
        return v


@router.get("/spaces")
async def list_spaces(request: Request) -> list[dict[str, Any]]:
    from ..services.space_storage import list_spaces as db_list_spaces

    db = request.app.state.db
    return db_list_spaces(db)


@router.post("/spaces")
async def create_space(request: Request, body: SpaceCreateRequest) -> dict[str, Any]:
    from ..services.space_storage import create_space as db_create_space
    from ..services.space_storage import get_space_by_name

    db = request.app.state.db

    existing = get_space_by_name(db, body.name)
    if existing:
        raise HTTPException(status_code=409, detail=f"Space already exists: {body.name}")

    try:
        return db_create_space(db, body.name, body.file_path, body.file_hash)
    except sqlite3.IntegrityError:
        raise HTTPException(status_code=409, detail=f"Space already exists: {body.name}")


@router.get("/spaces/{space_id}")
async def get_space(request: Request, space_id: str) -> dict[str, Any]:
    from ..services.space_storage import get_space as db_get_space

    db = request.app.state.db
    space = db_get_space(db, space_id)
    if not space:
        raise HTTPException(status_code=404, detail="Space not found")
    return space


@router.delete("/spaces/{space_id}")
async def delete_space(request: Request, space_id: str) -> dict[str, str]:
    from ..services.space_storage import delete_space as db_delete_space

    db = request.app.state.db
    if not db_delete_space(db, space_id):
        raise HTTPException(status_code=404, detail="Space not found")
    return {"status": "deleted"}
