from fastapi import APIRouter, Depends, HTTPException, Query
from typing import List, Optional
import logging
import pydantic

from ..db_engine import db, DraftList, Team, model_to_dict, chunked
from ..dependencies import oauth2_scheme, valid_token, PRIVATE_IN_SCHEMA, handle_db_errors

logger = logging.getLogger('discord_app')

router = APIRouter(
    prefix='/api/v3/draftlist',
    tags=['draftlist']
)


class DraftListModel(pydantic.BaseModel):
    season: int
    team_id: int
    rank: int
    player_id: int


class DraftListList(pydantic.BaseModel):
    count: int
    draft_list: List[DraftListModel]


@router.get('', include_in_schema=PRIVATE_IN_SCHEMA)
@handle_db_errors
async def get_draftlist(
        season: Optional[int], team_id: list = Query(default=None), token: str = Depends(oauth2_scheme)):
    if not valid_token(token):
        logger.warning(f'get_draftlist - Bad Token: {token}')
        raise HTTPException(status_code=401, detail='Unauthorized')

    all_list = DraftList.select()

    if season is not None:
        all_list = all_list.where(DraftList.season == season)
    if team_id is not None:
        all_list = all_list.where(DraftList.team_id << team_id)

    r_list = {
        'count': all_list.count(),
        'picks': [model_to_dict(x) for x in all_list]
    }

    db.close()
    return r_list


@router.get('/team/{team_id}', include_in_schema=PRIVATE_IN_SCHEMA)
@handle_db_errors
async def get_team_draftlist(team_id: int, token: str = Depends(oauth2_scheme)):
    if not valid_token(token):
        logger.warning(f'post_draftlist - Bad Token: {token}')
        raise HTTPException(status_code=401, detail='Unauthorized')

    this_team = Team.get_or_none(Team.id == team_id)
    if this_team is None:
        raise HTTPException(status_code=404, detail=f'Team ID {team_id} not found')

    this_list = DraftList.select().where(DraftList.team == this_team)
    r_list = {
        'count': this_list.count(),
        'picks': [model_to_dict(x) for x in this_list]
    }

    db.close()
    return r_list


@router.post('', include_in_schema=PRIVATE_IN_SCHEMA)
@handle_db_errors
async def post_draftlist(draft_list: DraftListList, token: str = Depends(oauth2_scheme)):
    if not valid_token(token):
        logger.warning(f'post_draftlist - Bad Token: {token}')
        raise HTTPException(status_code=401, detail='Unauthorized')

    new_list = []
    this_team = Team.get_or_none(Team.id == draft_list.draft_list[0].team_id)
    if this_team is None:
        raise HTTPException(status_code=404, detail=f'Team ID {draft_list.draft_list[0].team_id} not found')

    DraftList.delete().where(DraftList.team == this_team).execute()

    for x in draft_list.draft_list:
        new_list.append(x.dict())

    with db.atomic():
        for batch in chunked(new_list, 15):
            DraftList.insert_many(batch).on_conflict_ignore().execute()

    db.close()
    return f'Inserted {len(new_list)} list values'


@router.delete('/team/{team_id}', include_in_schema=PRIVATE_IN_SCHEMA)
@handle_db_errors
async def delete_draftlist(team_id: int, token: str = Depends(oauth2_scheme)):
    if not valid_token(token):
        logger.warning(f'delete_draftlist - Bad Token: {token}')
        raise HTTPException(status_code=401, detail='Unauthorized')
    
    count = DraftList.delete().where(DraftList.team_id == team_id).execute()
    db.close()
    return f'Deleted {count} list values'
