from time import time

from fastapi import APIRouter
from starlette.requests import Request

from app import mongo
from app.utils.response_util import response

router = APIRouter()


@router.post("/get-all", tags=[""])
async def get_all_transactions(params: dict, page: int = 1, items_per_page: int = 10):
    start_time = time()

    is_income = params.get("isIncome")
    query = {"isIncome": is_income} if is_income is not None else {}

    total = await mongo.transactions_collection.count_documents(query)
    transactions = await mongo.transactions_collection.find(
        query, {"_id": False}
    ).sort("id", mongo.desc).skip((page - 1) * items_per_page).limit(items_per_page).to_list(length=None)

    for transaction in transactions:
        user = await mongo.users_collection.find_one({"id": transaction["createdByUser"]["id"]}, {"_id": False})
        if user:
            transaction["createdByUser"] = user

        tag_ids = [tag["id"] for tag in transaction["tags"]]
        transaction["tags"] = await mongo.transaction_tags_collection.find({"id": {"$in": tag_ids}}, {"_id": False}).to_list(length=None)

    return response({
        "transactions": transactions,
        "total": total,
    }, start_time=start_time)


@router.post("/update", tags=[""])
async def update_transaction(params: dict, request: Request):
    start_time = time()
    data = params["transaction"]
    user_id = request.state.user["id"]

    tags = []
    for tag_name in data.get("tags", []):
        tag = await mongo.transaction_tags_collection.find_one({"name": tag_name}, {"_id": False})
        if not tag:
            tag_id = await mongo.get_next_id(mongo.transaction_tags_collection)
            tag = {
                "id": tag_id,
                "name": tag_name,
                "isIncome": data.get("isIncome", False)
            }

            await mongo.transaction_tags_collection.insert_one(tag)

        tags.append({"id": tag["id"]})

    data["tags"] = tags

    if "id" in data:
        existing = await mongo.transactions_collection.find_one({"id": data["id"]})
        if not existing:
            return response({"message": "Транзакция не найдена", "ok": False}, start_time=start_time)

        await mongo.transactions_collection.update_one({"id": data["id"]}, {"$set": data})
        message = "Транзакция обновлена"
    else:
        data["id"] = await mongo.get_next_id(mongo.transactions_collection)
        data["createdByUser"] = {"id": user_id}
        await mongo.transactions_collection.insert_one(data)
        message = "Транзакция создана"

    return response({
        "message": message,
        "ok": True
    }, start_time=start_time)


@router.delete("/delete/{transaction_id}", tags=[""])
async def delete_transaction(transaction_id: int):
    start_time = time()

    await mongo.transactions_collection.delete_one({"id": transaction_id})
    return response({
        "message": "Транзакция удалена",
        "ok": True
    }, start_time=start_time)


@router.get("/get-all-tags", tags=[""])
async def get_all_transaction_tags():
    start_time = time()

    tags = await mongo.transaction_tags_collection.find(
        {}, {"_id": False}
    ).sort("id", mongo.asc).to_list(length=None)

    return response({
        "tags": tags
    }, start_time=start_time)


@router.get("/get-tags/{is_income}", tags=[""])
async def get_transaction_tags(is_income: bool):
    start_time = time()

    tags = await mongo.transaction_tags_collection.find(
        {"isIncome": is_income}, {"_id": False}
    ).sort("id", mongo.asc).to_list(length=None)

    return response({"tags": tags}, start_time=start_time)


@router.post("/create-tag", tags=[""])
async def create_transaction_tag(params: dict):
    start_time = time()
    data = params["tag"]

    data["id"] = await mongo.get_next_id(mongo.transaction_tags_collection)
    await mongo.transaction_tags_collection.insert_one(data)

    return response({
        "message": "Тег транзакции создан",
        "ok": True
    }, start_time=start_time)


@router.post("/update-tag", tags=[""])
async def update_transaction_tag(params: dict):
    start_time = time()
    data = params["tag"]

    await mongo.transaction_tags_collection.update_one(
        {"id": data["id"]},
        {"$set": data}
    )

    return response({
        "message": "Тег транзакции обновлен",
        "ok": True
    }, start_time=start_time)


@router.delete("/delete-tag/{tag_id}", tags=[""])
async def delete_transaction_tag(tag_id: int):
    start_time = time()

    await mongo.transaction_tags_collection.delete_one({"id": tag_id})
    return response({
        "message": "Тег транзакции удалён",
        "ok": True
    }, start_time=start_time)
