from fastapi import APIRouter, Depends
from ..utils import engine, get_session
from sqlmodel import Session, select
from sqlalchemy.exc import NoResultFound
from ..models.client import Client
from ..models.epic import Epic
from datetime import datetime

router = APIRouter(prefix="/api/clients", tags=["client"])


@router.post("/")
async def post_client(*, client: Client, session: Session = Depends(get_session)):
    """
    Post a new client.

    Parameters
    ----------
    client : Client
        Client that is to be added to the database.
    session : Session
        SQL session that is to be used to add the client.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.name == client.name)
    try:
        result = session.exec(statement).one()
        return False
    except NoResultFound:
        session.add(client)
        session.commit()
        session.refresh(client)
        return client


@router.get("/")
async def read_clients(session: Session = Depends(get_session)):
    """
    Get a list of all clients.

    Parameters
    ----------
    session : Session
        SQL session that is to be used to get a list of the clients.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client)
    results = session.exec(statement).all()
    return results


@router.get("/active")
async def read_clients(session: Session = Depends(get_session)):
    """
    Get a list of all active clients.

    Parameters
    ----------
    session : Session
        SQL session that is to be used to get a list of all of the active clients.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.is_active == True).order_by(Client.id.asc())
    results = session.exec(statement).all()
    return results


@router.get("/{client_id}")
async def read_clients(
    *, client_id: int = None, session: Session = Depends(get_session)
):
    """
    Get a client by client_id.

    Parameters
    ----------
    client_id : int
        ID of client that is to be read.
    session : Session
        SQL session that is to be used to read a client.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.id == client_id)
    try:
        result = session.exec(statement).one()
        return result
    except NoResultFound:
        msg = f"""There is no client with id = {client_id}"""
        return msg


@router.get("/names/{name}")
async def read_clients_by_name(
    *, name: str = None, session: Session = Depends(get_session)
):
    """
    Get a client by client_name.

    Parameters
    ----------
    name : str
        Name of client to be read.
    session : Session
        SQL session that is to be used to read a client.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.name == name)
    result = session.exec(statement).one()
    return result


@router.get("/{client_id}/epics/")
async def read_clients_epics(
    client_id: int = None, session: Session = Depends(get_session)
):
    """
    Get epics from a client_id.

    Parameters
    ----------
    client_id : int
        ID of client that is to be used to pull epics from.
    session : Session
        SQL session that is to be used to pull the epics.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = (
        select(Client.id, Client.name, Epic.name)
        .select_from(Client)
        .join(Epic)
        .where(Client.id == client_id)
    )
    results = session.exec(statement).all()
    return results


@router.put("/{client_id}/deactivate-client")
async def update_clients(
    *,
    client_id: int,
    session: Session = Depends(get_session),
):
    """Deactivate a client"""
    statement = select(Client).where(Client.id == client_id)
    client_to_update = session.exec(statement).one()
    client_to_update.active = False
    statement2 = select(Epic).join(Client)
    client_to_update = session.exec(statement).one()
    client_to_update.active = False

    session.add(client_to_update)
    session.commit()
    session.refresh(client_to_update)
    return client_to_update


@router.put("/{client_id}/activate")
async def activate_clients(
    *,
    client_id: int,
    session: Session = Depends(get_session),
):
    """
    Activate a client using its id as a key.

    Parameters
    ----------
    client_id : int
        ID of the client to be activated.
    session : Session
        SQL session that is to be used to activate a client.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.id == client_id)
    client_to_update = session.exec(statement).one()
    client_to_update.is_active = True
    client_to_update.updated_at = datetime.now()
    session.add(client_to_update)
    session.commit()
    session.refresh(client_to_update)
    return client_to_update


@router.put("/{client_id}/deactivate")
async def deactivate_clients(
    *,
    client_id: int,
    session: Session = Depends(get_session),
):
    """
    Deactivate a client using its id as a key.

    Parameters
    ----------
    client_id : int
        ID of the client to be deactivated.
    session : Session
        SQL session that is to be used to deactivate a client.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.id == client_id)
    client_to_update = session.exec(statement).one()
    client_to_update.is_active = False
    client_to_update.updated_at = datetime.now()
    session.add(client_to_update)

    session.commit()
    session.refresh(client_to_update)
    return client_to_update


@router.put("/{client_id}/deactivate-epics")
async def update_clients_and_epics(
    *,
    client_id: int,
    session: Session = Depends(get_session),
):
    """Deactivate a client and its epics"""
    """
    Deactivate a client and its epics using the client's ID as a key.

    Parameters
    ----------
    client_id : int
        ID of the client to deactivate.
    session : Session
        SQL session that is to be used to deactivate the client and its respective epics.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement1 = select(Client).where(Client.id == client_id)
    client_to_update = session.exec(statement1).one()
    client_to_update.is_active = False
    client_to_update.updated_at = datetime.now()
    session.add(client_to_update)
    statement2 = select(Epic).where(Epic.client_id == client_id)
    epics_to_update = session.exec(statement2).all()
    for epic in epics_to_update:
        epic.is_active = False
        session.add(epic)
    session.commit()
    return True


@router.put("/{client_id}")
async def update_clients(
    *,
    client_id: int = None,
    new_client_name: str = None,
    is_active: bool = None,
    session: Session = Depends(get_session),

):
    """
    Update a client from a client_id.

    Parameters
    ----------
    client_id : int
        ID of the client to update.
    new_client_name : str
        New name of the client.
    session : Session
        SQL session that is to be used to update a client.
        Defaults to creating a dependency on the running SQL model session.
    """
    statement = select(Client).where(Client.id == client_id)
    client_to_update = session.exec(statement).one()
    if new_client_name != None:
        client_to_update.name = new_client_name
    if is_active != None:
        client_to_update.is_active = is_active
    client_to_update.updated_at = datetime.now()
    session.add(client_to_update)
    session.commit()
    session.refresh(client_to_update)
    return client_to_update

datetime.datetime.now fastapi.APIRouter fastapi.Depends sqlmodel.select
[((263, 312), 'fastapi.APIRouter', 'APIRouter', ([], {'prefix': '"""/api/clients"""', 'tags': "['client']"}), "(prefix='/api/clients', tags=['client'])\n", (272, 312), False, 'from fastapi import APIRouter, Depends\n'), ((393, 413), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (400, 413), False, 'from fastapi import APIRouter, Depends\n'), ((1050, 1070), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (1057, 1070), False, 'from fastapi import APIRouter, Depends\n'), ((1334, 1348), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (1340, 1348), False, 'from sqlmodel import Session, select\n'), ((1479, 1499), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (1486, 1499), False, 'from fastapi import APIRouter, Depends\n'), ((2023, 2043), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (2030, 2043), False, 'from fastapi import APIRouter, Depends\n'), ((2694, 2714), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (2701, 2714), False, 'from fastapi import APIRouter, Depends\n'), ((3235, 3255), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (3242, 3255), False, 'from fastapi import APIRouter, Depends\n'), ((3923, 3943), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (3930, 3943), False, 'from fastapi import APIRouter, Depends\n'), ((4499, 4519), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (4506, 4519), False, 'from fastapi import APIRouter, Depends\n'), ((5023, 5037), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (5035, 5037), False, 'from datetime import datetime\n'), ((5280, 5300), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (5287, 5300), False, 'from fastapi import APIRouter, Depends\n'), ((5811, 5825), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (5823, 5825), False, 'from datetime import datetime\n'), ((6081, 6101), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (6088, 6101), False, 'from fastapi import APIRouter, Depends\n'), ((6704, 6718), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (6716, 6718), False, 'from datetime import datetime\n'), ((7172, 7192), 'fastapi.Depends', 'Depends', (['get_session'], {}), '(get_session)\n', (7179, 7192), False, 'from fastapi import APIRouter, Depends\n'), ((7855, 7869), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (7867, 7869), False, 'from datetime import datetime\n'), ((730, 744), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (736, 744), False, 'from sqlmodel import Session, select\n'), ((2357, 2371), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (2363, 2371), False, 'from sqlmodel import Session, select\n'), ((3019, 3033), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (3025, 3033), False, 'from sqlmodel import Session, select\n'), ((3994, 4008), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (4000, 4008), False, 'from sqlmodel import Session, select\n'), ((4145, 4157), 'sqlmodel.select', 'select', (['Epic'], {}), '(Epic)\n', (4151, 4157), False, 'from sqlmodel import Session, select\n'), ((4853, 4867), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (4859, 4867), False, 'from sqlmodel import Session, select\n'), ((5640, 5654), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (5646, 5654), False, 'from sqlmodel import Session, select\n'), ((6532, 6546), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (6538, 6546), False, 'from sqlmodel import Session, select\n'), ((6770, 6782), 'sqlmodel.select', 'select', (['Epic'], {}), '(Epic)\n', (6776, 6782), False, 'from sqlmodel import Session, select\n'), ((7570, 7584), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (7576, 7584), False, 'from sqlmodel import Session, select\n'), ((1784, 1798), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (1790, 1798), False, 'from sqlmodel import Session, select\n'), ((3600, 3641), 'sqlmodel.select', 'select', (['Client.id', 'Client.name', 'Epic.name'], {}), '(Client.id, Client.name, Epic.name)\n', (3606, 3641), False, 'from sqlmodel import Session, select\n')]