from typing import Dict, List

from src.internals.database.database import query_db, query_one_db, query_rowcount_db
from src.lib.notification import send_notifications
from src.lib.pagination import Pagination
from src.types.account import Account, AccountRoleChange, NotificationTypes


def get_account(account_id: str) -> Account:
    account = query_one_db(
        """
        SELECT id, username, created_at, role
        FROM account
        WHERE id = %s
        """,
        (account_id,),
    )
    account = Account.init_from_dict(account)
    return account


def count_accounts(queries: Dict[str, str]) -> int:
    role = queries["role"]
    params: tuple[str, ...]
    if queries.get("name"):
        params = (role, queries["name"])
    else:
        params = (role,)
    result = query_one_db(
        f"""
        SELECT COUNT(*) AS total_number_of_accounts
        FROM account
        WHERE
            role = ANY(%s)
            {"AND username LIKE %s" if len(params) > 1 else ""}
    """,
        params,
    )
    return result["total_number_of_accounts"] if result else 0


def get_accounts(pagination: Pagination, queries: Dict[str, str]) -> List[Account]:
    params = (queries["role"], pagination.offset, pagination.limit)
    if queries.get("name"):
        params = (queries["role"], f"%%{queries["name"]}%%", pagination.offset, pagination.limit)

    accounts = query_db(
        f"""
        SELECT id, username, created_at, role
        FROM account
        WHERE
            role = ANY(%s)
            {"AND username LIKE %s" if len(params) > 3 else ""}
        ORDER BY
            created_at DESC,
            username
        OFFSET %s
        LIMIT %s
    """,
        params,
    )
    acc_list = [Account.init_from_dict(acc) for acc in accounts]
    count = count_accounts(queries)
    pagination.add_count(count)
    return acc_list


def change_account_role(account_ids: List[str], extra_info: AccountRoleChange):
    change_role_query = """
        UPDATE account
        SET role = %s
        WHERE id = ANY (%s)
    """
    query_rowcount_db(change_role_query, (extra_info["new_role"], account_ids))
    send_notifications(account_ids, NotificationTypes.ACCOUNT_ROLE_CHANGE, extra_info)
    return True
