from typing import List
from uuid import UUID

import inject
from sqlalchemy.sql.expression import desc
from sqlmodel import Session, between, select

from src.core.events import EventDescription
from src.core.helpers.exceptions import NotAuthorizedError, NotFoundError
from src.core.models import Balance, Context, CreateBalance, QueryBalance
from src.core.services import Streamer


@inject.params(streamer=Streamer)
def create(session: Session, schema: CreateBalance, context: Context, streamer: Streamer) -> Balance:
    balance = Balance(**schema.dict(), owner_id=context.user_id)
    session.add(balance)
    streamer.send_event(EventDescription.CREATE_BALANCE, context=context, client=balance.dict())

    return balance


def get_all(session: Session, query_schema: QueryBalance, context: Context) -> List[Balance]:
    args = []

    if not context.user_is_super_user:
        args.append(Balance.owner_id == context.user_id)

    if query_schema.start_date is not None and query_schema.end_date is not None:
        args.append(between(Balance.created_at, query_schema.start_date, query_schema.end_date))

    return session.exec(select(Balance).where(*args).order_by(desc(Balance.created_at))).all()


@inject.params(streamer=Streamer)
def delete(session: Session, balance_id: UUID, context: Context, streamer: Streamer) -> Balance:
    balance = session.exec(select(Balance).where(Balance.id == balance_id)).first()

    if not balance:
        raise NotFoundError(f"Não foi possível localizar o edtalhamento ID: {balance_id}")

    if not context.user_is_super_user and balance.owner_id != context.user_id:
        raise NotAuthorizedError(f"Você não possui permissão para excluir o detalhamento com ID: {balance_id}")

    session.delete(balance)
    session.commit()

    streamer.send_event(description=EventDescription.DELETE_BALANCE, context=context, balance=balance.dict())

    return balance

src.core.helpers.exceptions.NotAuthorizedError inject.params sqlalchemy.sql.expression.desc sqlmodel.between src.core.helpers.exceptions.NotFoundError sqlmodel.select
[((386, 418), 'inject.params', 'inject.params', ([], {'streamer': 'Streamer'}), '(streamer=Streamer)\n', (399, 418), False, 'import inject\n'), ((1214, 1246), 'inject.params', 'inject.params', ([], {'streamer': 'Streamer'}), '(streamer=Streamer)\n', (1227, 1246), False, 'import inject\n'), ((1463, 1539), 'src.core.helpers.exceptions.NotFoundError', 'NotFoundError', (['f"""Não foi possível localizar o edtalhamento ID: {balance_id}"""'], {}), "(f'Não foi possível localizar o edtalhamento ID: {balance_id}')\n", (1476, 1539), False, 'from src.core.helpers.exceptions import NotAuthorizedError, NotFoundError\n'), ((1634, 1741), 'src.core.helpers.exceptions.NotAuthorizedError', 'NotAuthorizedError', (['f"""Você não possui permissão para excluir o detalhamento com ID: {balance_id}"""'], {}), "(\n    f'Você não possui permissão para excluir o detalhamento com ID: {balance_id}'\n    )\n", (1652, 1741), False, 'from src.core.helpers.exceptions import NotAuthorizedError, NotFoundError\n'), ((1038, 1113), 'sqlmodel.between', 'between', (['Balance.created_at', 'query_schema.start_date', 'query_schema.end_date'], {}), '(Balance.created_at, query_schema.start_date, query_schema.end_date)\n', (1045, 1113), False, 'from sqlmodel import Session, between, select\n'), ((1178, 1202), 'sqlalchemy.sql.expression.desc', 'desc', (['Balance.created_at'], {}), '(Balance.created_at)\n', (1182, 1202), False, 'from sqlalchemy.sql.expression import desc\n'), ((1371, 1386), 'sqlmodel.select', 'select', (['Balance'], {}), '(Balance)\n', (1377, 1386), False, 'from sqlmodel import Session, between, select\n'), ((1140, 1155), 'sqlmodel.select', 'select', (['Balance'], {}), '(Balance)\n', (1146, 1155), False, 'from sqlmodel import Session, between, select\n')]