from __future__ import annotations

from typing import TYPE_CHECKING

import bcrypt
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import JSONResponse, Response

if TYPE_CHECKING:
    from relay.server.db import RelayDB
    from relay.server.state import RelayState


async def _authorize_request(request: Request, db: RelayDB) -> list[str]:
    groups_raw = request.headers.get("x-groups", "")
    if not groups_raw:
        return []
    authorized: list[str] = []
    seen: set[str] = set()
    for pair in groups_raw.split(","):
        parts = pair.strip().split(":", 1)
        if len(parts) != 2:
            continue
        group_id, password = parts
        if group_id in seen:
            continue
        seen.add(group_id)
        stored_hash = await db.get_group_password_hash(group_id)
        if stored_hash is None:
            continue
        if bcrypt.checkpw(password.encode("utf-8"), stored_hash.encode("utf-8")):
            authorized.append(group_id)
    return authorized


def register_api_routes(mcp: FastMCP, state: RelayState, db: RelayDB) -> None:
    @mcp.custom_route("/auth/groups/{group_id}/messages", methods=["GET"])
    async def get_messages(request: Request) -> Response:
        authorized = await _authorize_request(request, db)
        group_id = request.path_params["group_id"]
        if group_id not in authorized:
            return JSONResponse({"error": "unauthorized"}, status_code=401)

        since_seq = int(request.query_params.get("since_seq", "0"))
        limit = int(request.query_params.get("limit", "100"))

        rows = await db.get_messages_after(group_id, since_seq)
        messages = [
            {
                "message_id": row.message_id,
                "group_id": row.group_id,
                "from_peer": row.from_peer,
                "from_display": row.from_display,
                "content": row.content,
                "timestamp": row.timestamp.isoformat(),
                "seq": row.seq,
            }
            for row in rows[:limit]
        ]
        return JSONResponse({"messages": messages})

    @mcp.custom_route("/auth/groups/{group_id}/peers", methods=["GET"])
    async def get_peers(request: Request) -> Response:
        authorized = await _authorize_request(request, db)
        group_id = request.path_params["group_id"]
        if group_id not in authorized:
            return JSONResponse({"error": "unauthorized"}, status_code=401)

        peers = await state.list_peers(group_id)
        peer_list = [
            {
                "peer_id": p.peer_id,
                "display_name": p.display_name,
                "online": p.online,
            }
            for p in peers
        ]
        return JSONResponse({"peers": peer_list})
