import asyncio
import uuid
from time import time

from fastapi import APIRouter

from app import mongo
from app.providers import wildberries, ozon
from app.utils.response_util import response

router = APIRouter()


async def update_task_status(task_id: str, status: str, message: str):
    await mongo.tasks_collection.update_one(
        {"taskId": task_id},
        {"$set": {"status": status, "message": message, "updatedAt": time()}}
    )


async def process_synchronization(task_id: str, marketplace: dict):
    try:
        if marketplace["baseMarketplaceKey"] == "wb":
            products = wildberries.load_all_products(marketplace["authData"]["Authorization"])
        elif marketplace["baseMarketplaceKey"] == "ozon":
            products = ozon.load_all_products(marketplace["authData"]["Client-Id"], marketplace["authData"]["Api-Key"])
        else:
            products = []

        client_id = marketplace["clientId"]
        client = await mongo.clients_collection.find_one(
            {"id": client_id}, {"_id": False}
        )

        if client and client.get("barcodeTemplate"):
            barcode_template = client["barcodeTemplate"]
        else:
            barcode_template = await mongo.templates_collection.find_one({}, {"_id": False})

        for product in products:
            for barcode in product["barcodes"]:
                product_data = product.copy()
                product_data["clientId"] = client_id
                product_data["barcodes"] = [barcode]
                product_data["barcodeTemplate"] = barcode_template

                barcodes_with_sizes = product_data.get("barcodesWithSizes")
                if barcodes_with_sizes:
                    product_data["size"] = barcodes_with_sizes.get(barcode)

                existing_product = await mongo.products_collection.find_one({"clientId": client_id, "article": product_data["article"], "barcodes": product_data["barcodes"]})

                if existing_product:
                    await mongo.products_collection.update_one(
                        {"_id": existing_product["_id"]},
                        {"$set": product_data}
                    )
                else:
                    product_data["id"] = await mongo.get_next_id(mongo.products_collection)
                    await mongo.products_collection.insert_one(product_data)

        await update_task_status(task_id, "SUCCESS", "Товары успешно синхронизированы")
    except Exception:
        await update_task_status(task_id, "FAILURE", "Ошибка синхронизации товаров")
        raise


@router.post("/synchronize-marketplace", tags=[""])
async def sync(params: dict):
    start_time = time()
    task_id = str(uuid.uuid4())

    marketplace = await mongo.marketplaces_collection.find_one({"id": params["marketplaceId"]})
    if not marketplace:
        return response({"message": "Маркетплейс не найден", "ok": False}, start_time=start_time)

    task = {
        "taskId": task_id,
        "marketplaceId": params["marketplaceId"],
        "status": "STARTED",
        "message": "Синхронизация товаров запущена",
        "createdAt": start_time,
        "updatedAt": start_time
    }

    await mongo.tasks_collection.insert_one(task)
    asyncio.create_task(process_synchronization(task_id, marketplace))

    return response({
        "ok": True,
        "status": task["status"],
        "message": task["message"],
        "taskId": task_id
    }, start_time=start_time)


@router.get("/info/{task_id}")
async def task_info(task_id: str):
    start_time = time()
    task = await mongo.tasks_collection.find_one({"taskId": task_id}, {"_id": False})

    if not task:
        return response({"message": "Задача не найдена", "ok": False}, start_time=start_time)

    return response({
        "ok": True,
        "status": "SUCCESS",
        "message": task["message"],
        "taskId": task_id
    }, start_time=start_time)
