from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional, List
from utils.utils import get_db
from . import handler
from .schema import (
    WatchlistCreate,
    WatchlistUpdate,
    WatchlistResponse,
    WatchlistitemCreate,
    WatchlistitemUpdate,
    WatchlistitemResponse,
    WatchlistDetailResponse,
)

router = APIRouter(prefix="/watchlists", tags=["Watchlists"])


@router.post(
    "/",
    response_model=WatchlistResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Watchlist",
    description="Creates a new watchlist for a user. Validates that the user exists, the watchlist name is unique per user, and the user has not exceeded the maximum of 10 watchlists. Returns 404 if user not found, 409 if name already exists, or 400 if limit exceeded.",
)
def create_watchlist_route(data: WatchlistCreate, db: Session = Depends(get_db)):
    return handler.create_watchlist(db, data)


@router.get(
    "/",
    response_model=List[WatchlistResponse],
    summary="List Watchlists",
    description="Returns a paginated list of watchlists. Supports optional filtering by user_id and is_default flag. Results are ordered by sort_order ascending.",
)
def list_watchlists_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = None,
    is_default: Optional[bool] = None,
    db: Session = Depends(get_db),
):
    return handler.list_watchlists(db, limit, offset, user_id, is_default)


@router.get(
    "/{watchlist_id}",
    response_model=WatchlistResponse,
    summary="Get Watchlist",
    description="Retrieves a single watchlist by ID. Returns 404 if the watchlist does not exist.",
)
def get_watchlist_route(watchlist_id: str, db: Session = Depends(get_db)):
    return handler.get_watchlist(db, watchlist_id)


@router.put(
    "/{watchlist_id}",
    response_model=WatchlistResponse,
    summary="Update Watchlist",
    description="Updates a watchlist's details. Only provided fields are updated. Validates that the new name (if provided) is unique per user. Returns 404 if watchlist not found or 409 if name conflict.",
)
def update_watchlist_route(
    watchlist_id: str, data: WatchlistUpdate, db: Session = Depends(get_db)
):
    return handler.update_watchlist(db, watchlist_id, data)


@router.delete(
    "/{watchlist_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Watchlist",
    description="Deletes a watchlist and all its associated watchlist items. Validates that the watchlist is not marked as default. Returns 404 if watchlist not found or 400 if attempting to delete default watchlist.",
)
def delete_watchlist_route(watchlist_id: str, db: Session = Depends(get_db)):
    return handler.delete_watchlist(db, watchlist_id)


@router.get(
    "/{watchlist_id}/details",
    response_model=WatchlistDetailResponse,
    summary="Get Watchlist With Details",
    description="Retrieves a watchlist with all its stocks and their details including sector and exchange information. Uses eager loading to prevent N+1 queries. Returns 404 if watchlist not found.",
)
def get_watchlist_details_route(watchlist_id: str, db: Session = Depends(get_db)):
    return handler.get_watchlist_with_details(db, watchlist_id)


@router.post(
    "/{watchlist_id}/add-stock",
    response_model=WatchlistitemResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Add Stock To Watchlist",
    description="Adds a stock to a watchlist. Validates that the watchlist and stock exist, the stock is not already in the watchlist, and the watchlist has not exceeded the maximum of 100 stocks. Returns 404 if watchlist or stock not found, 409 if stock already exists in watchlist, or 400 if limit exceeded.",
)
def add_stock_to_watchlist_route(
    watchlist_id: str,
    stock_id: str = Query(...),
    notes: Optional[str] = Query(None),
    db: Session = Depends(get_db),
):
    return handler.add_stock_to_watchlist(db, watchlist_id, stock_id, notes)


@router.delete(
    "/{watchlist_id}/remove-stock/{stock_id}",
    status_code=status.HTTP_200_OK,
    summary="Remove Stock From Watchlist",
    description="Removes a stock from a watchlist. Returns 404 if the watchlist or stock association does not exist.",
)
def remove_stock_from_watchlist_route(
    watchlist_id: str, stock_id: str, db: Session = Depends(get_db)
):
    return handler.remove_stock_from_watchlist(db, watchlist_id, stock_id)


@router.post(
    "/items",
    response_model=WatchlistitemResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Watchlist Item",
    description="Creates a new watchlist item linking a stock to a watchlist. Validates that the watchlist and stock exist, the stock is not already in the watchlist, and the watchlist has not exceeded the maximum of 100 stocks. Returns 404 if watchlist or stock not found, 409 if stock already exists in watchlist, or 400 if limit exceeded.",
)
def create_watchlistitem_route(data: WatchlistitemCreate, db: Session = Depends(get_db)):
    return handler.create_watchlistitem(db, data)


@router.get(
    "/items",
    response_model=List[WatchlistitemResponse],
    summary="List Watchlist Items",
    description="Returns a paginated list of watchlist items. Supports optional filtering by watchlist_id and stock_id. Results are ordered by sort_order ascending.",
)
def list_watchlistitems_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    watchlist_id: Optional[str] = None,
    stock_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_watchlistitems(db, limit, offset, watchlist_id, stock_id)


@router.get(
    "/items/{item_id}",
    response_model=WatchlistitemResponse,
    summary="Get Watchlist Item",
    description="Retrieves a single watchlist item by ID. Returns 404 if the item does not exist.",
)
def get_watchlistitem_route(item_id: str, db: Session = Depends(get_db)):
    return handler.get_watchlistitem(db, item_id)


@router.put(
    "/items/{item_id}",
    response_model=WatchlistitemResponse,
    summary="Update Watchlist Item",
    description="Updates a watchlist item's details (notes and sort_order). Only provided fields are updated. Returns 404 if item not found.",
)
def update_watchlistitem_route(
    item_id: str, data: WatchlistitemUpdate, db: Session = Depends(get_db)
):
    return handler.update_watchlistitem(db, item_id, data)


@router.delete(
    "/items/{item_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Watchlist Item",
    description="Deletes a watchlist item, removing the stock from the watchlist. Returns 404 if item not found.",
)
def delete_watchlistitem_route(item_id: str, db: Session = Depends(get_db)):
    return handler.delete_watchlistitem(db, item_id)