"""The autopass API (M6, plan §4.4): GET/PUT the session player's OWN
rule for a match — owner-scoped, two dropdowns and a toggle.

Read/write split (same as every M6 surface): GET resolves the VIEWER
(View As shows the target's settings sheet, read-only), PUT acts as the
real session player — a read-only View As can inspect a rule but never
plant one in someone else's name. Sync def (react.md); default-deny
middleware gates both routes.
"""
from __future__ import annotations

import datetime
import uuid

from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel, ConfigDict
from sqlalchemy.orm import Session

from ..auth import current_player
from ..db import get_db
from ..services import autopass as autopass_service
from ..services import board as board_service
from ..services import viewer as viewer_service

router = APIRouter()


class AutopassRuleOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: uuid.UUID
    match_id: uuid.UUID
    owner_player_id: uuid.UUID
    trigger: str  # from_subteam | from_any | from_player
    trigger_player_id: uuid.UUID | None = None
    target_player_id: uuid.UUID
    active: bool
    created_at: datetime.datetime


class AutopassRulesOut(BaseModel):
    rules: list[AutopassRuleOut]


class AutopassRuleIn(BaseModel):
    """PUT body — the whole rule every time (upsert semantics; there is at
    most one rule per player per match, by schema)."""

    trigger: str
    trigger_player_id: uuid.UUID | None = None
    target_player_id: uuid.UUID
    active: bool = True


def _error_response(err: board_service.BoardError) -> JSONResponse:
    return JSONResponse(
        status_code=err.status_code,
        content={
            "error_code": err.error_code,
            "summary": err.summary,
            "detail": err.detail,
        },
    )


@router.get("/api/matches/{slug}/autopass", response_model=AutopassRulesOut)
def list_autopass(slug: str, request: Request, db: Session = Depends(get_db)):
    try:
        match = board_service.get_match_by_slug(db, slug)
    except board_service.BoardError as err:
        return _error_response(err)
    viewer = viewer_service.resolve_viewer(request, db)
    if viewer is None:
        return {"rules": []}  # no Player row -> nothing is theirs
    return {"rules": autopass_service.list_rules(db, match.id, viewer)}


@router.put("/api/matches/{slug}/autopass", response_model=AutopassRuleOut)
def put_autopass(
    slug: str, payload: AutopassRuleIn, request: Request, db: Session = Depends(get_db)
):
    try:
        match = board_service.get_match_by_slug(db, slug)
    except board_service.BoardError as err:
        return _error_response(err)
    actor = current_player(request)
    if actor is None:
        return JSONResponse(
            status_code=403,
            content={
                "error_code": "NOT_A_PLAYER",
                "summary": "You need a player profile in this match to set an autopass.",
                "detail": "Your BW account has no Player row yet — ask the owner to add you.",
            },
        )
    try:
        rule = autopass_service.upsert_rule(db, match, actor, payload.model_dump())
    except board_service.BoardError as err:
        return _error_response(err)
    return rule
