"""
Riders Admin API
================
Endpoints for the operations team to manage rider substitutions.

  POST   /api/v1/riders/substitution                              – register one or many substitutions
  GET    /api/v1/riders/substitution                              – list upcoming/active subs
  DELETE /api/v1/riders/substitution/{sub_date}/{absent_rider_id} – cancel one
"""

import logging
from datetime import date
from typing import List

from fastapi import APIRouter, Body, HTTPException, Path
from pydantic import BaseModel, model_validator

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/api/v1/riders",
    tags=["Riders & Substitutions"],
    responses={500: {"description": "Internal server error"}},
)


class SubstitutionEntry(BaseModel):
    sub_date: str
    absent_rider_id: int
    sub_rider_id: int

    @model_validator(mode="after")
    def validate_entry(self):
        try:
            date.fromisoformat(self.sub_date)
        except ValueError:
            raise ValueError(f"Invalid date format '{self.sub_date}'. Use YYYY-MM-DD.")
        if self.absent_rider_id == self.sub_rider_id:
            raise ValueError("absent_rider_id and sub_rider_id must be different.")
        return self


@router.post("/substitution", summary="Register one or multiple rider substitutions")
def register_substitution(entries: List[SubstitutionEntry] = Body(...)):
    """
    Register rider substitutions for the operations team. Accepts a list so
    you can submit all absent riders for a day in one call.

    Example — single:
    ```json
    [{"sub_date": "2026-06-20", "absent_rider_id": 101, "sub_rider_id": 205}]
    ```

    Example — batch (3 riders absent same day):
    ```json
    [
      {"sub_date": "2026-06-20", "absent_rider_id": 101, "sub_rider_id": 205},
      {"sub_date": "2026-06-20", "absent_rider_id": 102, "sub_rider_id": 206},
      {"sub_date": "2026-06-21", "absent_rider_id": 103, "sub_rider_id": 207}
    ]
    ```

    Each sub rider **must** appear in that day's getriderlogs response.
    The assignment engine copies the absent rider's kitchen ownership, soft
    preferences, and home location onto the sub rider automatically — reverts
    the next day with no action needed.

    Posting the same (sub_date, absent_rider_id) again updates sub_rider_id.
    """
    if not entries:
        raise HTTPException(status_code=400, detail="Request body must be a non-empty list.")

    try:
        from app.services.rider.substitution_service import get_substitution_service
        svc = get_substitution_service()
        results = [svc.register(e.sub_date, e.absent_rider_id, e.sub_rider_id) for e in entries]
        return {
            "status": "ok",
            "registered": len(results),
            "substitutions": results,
        }
    except Exception as e:
        logger.error(f"[Riders API] register_substitution: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/substitution", summary="List upcoming and active rider substitutions")
def list_substitutions(from_date: str = None):
    """
    Returns all substitution records on or after `from_date` (default: today).
    Use `?from_date=2026-06-01` to look back further.
    """
    if from_date is not None:
        try:
            date.fromisoformat(from_date)
        except ValueError:
            raise HTTPException(
                status_code=400,
                detail=f"Invalid date format '{from_date}'. Use YYYY-MM-DD.",
            )
    try:
        from app.services.rider.substitution_service import get_substitution_service
        records = get_substitution_service().list_all(from_date)
        return {
            "status": "ok",
            "count": len(records),
            "substitutions": records,
        }
    except Exception as e:
        logger.error(f"[Riders API] list_substitutions: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))


@router.delete(
    "/substitution/{sub_date}/{absent_rider_id}",
    summary="Cancel a rider substitution",
)
def cancel_substitution(
    sub_date: str = Path(..., example="2026-06-20"),
    absent_rider_id: int = Path(..., example=101),
):
    """
    Remove a substitution record. The sub rider will no longer inherit the
    absent rider's profile on that date.
    """
    try:
        date.fromisoformat(sub_date)
    except ValueError:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid date format '{sub_date}'. Use YYYY-MM-DD.",
        )
    try:
        from app.services.rider.substitution_service import get_substitution_service
        removed = get_substitution_service().cancel(sub_date, absent_rider_id)
        if not removed:
            raise HTTPException(
                status_code=404,
                detail=f"No substitution found for absent_rider_id={absent_rider_id} on {sub_date}.",
            )
        return {
            "status": "ok",
            "message": f"Substitution cancelled: rider {absent_rider_id} on {sub_date}.",
        }
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[Riders API] cancel_substitution: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))
