from typing import List
from uuid import UUID

import inject
from sqlmodel import Session, select

from src.core.events import EventDescription
from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError
from src.core.models import Client, Context, CreateClient, QueryClient, UpdateClient
from src.core.services import Streamer


@inject.params(streamer=Streamer)
def create(session: Session, schema: CreateClient, context: Context, streamer: Streamer) -> Client:
    if session.exec(select(Client).where(Client.email == schema.email)).first():
        raise DatabaseError("Já existe um cliente cadastrado com o email: %s" % schema.email)

    if session.exec(select(Client).where(Client.phone == schema.phone)).first():
        raise DatabaseError("Já existe um cliente cadastrado com o telefone: %s" % schema.phone)

    client = Client(**schema.dict(), owner_id=context.user_id)
    session.add(client)
    session.commit()
    streamer.send_event(EventDescription.CREATE_USER, context=context, client=client.dict())

    return client


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

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

    return session.exec(select(Client).where(*args)).all()


def get_by_id(session: Session, client_id: UUID, context: Context) -> Client:
    client = session.exec(select(Client).where(Client.id == client_id)).first()

    if not client:
        raise NotFoundError(f"Não foi possível localizar o Client com ID: {client_id}")

    if not context.user_is_super_user and client.owner_id != context.user_id:
        raise NotAuthorizedError(f"Você não possui permissão para consultar os dados do cliente com ID {client_id}!")

    return client


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

    if not client:
        raise NotFoundError(f"Não foi possível localizar o Cliente com ID: {client_id}")

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

    session.delete(client)
    session.commit()

    streamer.send_event(description=EventDescription.DELETE_CLIENT, context=context, client=client.dict())

    return client


@inject.params(streamer=Streamer)
def update(session: Session, data: UpdateClient, context: Context, streamer: Streamer) -> Client:
    client = session.exec(select(Client).where(Client.id == data.id)).first()

    if not client:
        raise NotFoundError(f"Não foi possível localizar o Client com ID: {data.id}")

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

    columns = client.__table__.columns.keys()

    for key, value in data:
        if key not in columns:
            continue

        setattr(client, key, value)

    session.add(client)
    session.commit()

    streamer.send_event(
        description=EventDescription.UPDATE_CLIENT,
        context=context,
        data={"client_data": client.dict(), "update_schema": data.dict()},
    )

    return client

src.core.helpers.exceptions.NotFoundError sqlmodel.select src.core.helpers.exceptions.DatabaseError inject.params src.core.helpers.exceptions.NotAuthorizedError
[((360, 392), 'inject.params', 'inject.params', ([], {'streamer': 'Streamer'}), '(streamer=Streamer)\n', (373, 392), False, 'import inject\n'), ((1819, 1851), 'inject.params', 'inject.params', ([], {'streamer': 'Streamer'}), '(streamer=Streamer)\n', (1832, 1851), False, 'import inject\n'), ((2500, 2532), 'inject.params', 'inject.params', ([], {'streamer': 'Streamer'}), '(streamer=Streamer)\n', (2513, 2532), False, 'import inject\n'), ((588, 667), 'src.core.helpers.exceptions.DatabaseError', 'DatabaseError', (["('Já existe um cliente cadastrado com o email: %s' % schema.email)"], {}), "('Já existe um cliente cadastrado com o email: %s' % schema.email)\n", (601, 667), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((764, 851), 'src.core.helpers.exceptions.DatabaseError', 'DatabaseError', (["('Já existe um cliente cadastrado com o telefone: %s' % schema.phone)"], {}), "('Já existe um cliente cadastrado com o telefone: %s' % schema\n    .phone)\n", (777, 851), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((1526, 1599), 'src.core.helpers.exceptions.NotFoundError', 'NotFoundError', (['f"""Não foi possível localizar o Client com ID: {client_id}"""'], {}), "(f'Não foi possível localizar o Client com ID: {client_id}')\n", (1539, 1599), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((1693, 1806), 'src.core.helpers.exceptions.NotAuthorizedError', 'NotAuthorizedError', (['f"""Você não possui permissão para consultar os dados do cliente com ID {client_id}!"""'], {}), "(\n    f'Você não possui permissão para consultar os dados do cliente com ID {client_id}!'\n    )\n", (1711, 1806), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((2061, 2135), 'src.core.helpers.exceptions.NotFoundError', 'NotFoundError', (['f"""Não foi possível localizar o Cliente com ID: {client_id}"""'], {}), "(f'Não foi possível localizar o Cliente com ID: {client_id}')\n", (2074, 2135), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((2229, 2325), 'src.core.helpers.exceptions.NotAuthorizedError', 'NotAuthorizedError', (['f"""Você não possui permissão para excluir o Cliente com ID: {client_id}"""'], {}), "(\n    f'Você não possui permissão para excluir o Cliente com ID: {client_id}')\n", (2247, 2325), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((2743, 2814), 'src.core.helpers.exceptions.NotFoundError', 'NotFoundError', (['f"""Não foi possível localizar o Client com ID: {data.id}"""'], {}), "(f'Não foi possível localizar o Client com ID: {data.id}')\n", (2756, 2814), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((2908, 3002), 'src.core.helpers.exceptions.NotAuthorizedError', 'NotAuthorizedError', (['f"""Você não possui permissão para excluir o Cliente com ID: {data.id}"""'], {}), "(\n    f'Você não possui permissão para excluir o Cliente com ID: {data.id}')\n", (2926, 3002), False, 'from src.core.helpers.exceptions import DatabaseError, NotAuthorizedError, NotFoundError\n'), ((513, 527), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (519, 527), False, 'from sqlmodel import Session, select\n'), ((689, 703), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (695, 703), False, 'from sqlmodel import Session, select\n'), ((1297, 1311), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (1303, 1311), False, 'from sqlmodel import Session, select\n'), ((1438, 1452), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (1444, 1452), False, 'from sqlmodel import Session, select\n'), ((1973, 1987), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (1979, 1987), False, 'from sqlmodel import Session, select\n'), ((2657, 2671), 'sqlmodel.select', 'select', (['Client'], {}), '(Client)\n', (2663, 2671), False, 'from sqlmodel import Session, select\n')]