from datetime import datetime
from utils import logger, saveImage, safeFilename, deleteImage
from db import CRUD
from db.schemas.toolkit import Toolkit
from sqlalchemy import select
from db.handlers.records import ServiceRecordsHandler


def handleToolkitImage(imageData, title: str):
    title = safeFilename(title)
    fileName = f"tools/{title}.png"
    if not saveImage(imageData, fileName):
        return None
    return fileName


class ToolkitHandler:
    async def add(toolkitData: dict, user_id: int = None):
        title = toolkitData.get("title", None)
        if not title:
            logger.error("Не указано название инструмента")
            return {}

        query = select(Toolkit).where(Toolkit.title == title)
        toolkit = await CRUD.read(query)
        if toolkit:
            logger.error("Инструмент с таким названием уже существует")
            return {}

        try:
            imageDict = {"main": "static/images/tools/default.png", "additional": []}
            if "image" in toolkitData:
                imageData = toolkitData.pop("image")
                mainImage = imageData.get("main")
                imageFileName = handleToolkitImage(mainImage, title)
                if imageFileName:
                    imageDict["main"] = imageFileName
                additionalImages = imageData.get("additional", [])
                if len(additionalImages) > 0:
                    for image in additionalImages:
                        imageFileName = handleToolkitImage(image, title)
                        if imageFileName:
                            imageDict["additional"].append(imageFileName)
            toolkitData["image"] = imageDict
            newToolkit = await Toolkit(**toolkitData).save()
        except Exception as e:
            logger.error(f"Ошибка сохранения инструмента: {str(e)}")
            return {}

        if not newToolkit:
            logger.error("Инструмент не сохранен")
            return {}

        logger.info(f"Инструмент {newToolkit.title} успешно создан")
        await ServiceRecordsHandler.add(user_id, {"Добавлен инструмент": toolkitData})
        return newToolkit

    async def updateMovindDate(toolkitId: int):
        editedToolkit = await ToolkitHandler.edit(toolkitId, moved_at=datetime.now())
        if not editedToolkit:
            logger.error("Инструмент не обновлен")
            return False
        return True

    async def updateRefillDate(toolkitId: int):
        logger.info(f"Обновление даты пополнения инструмента {toolkitId}...")
        editedToolkit = await ToolkitHandler.edit(toolkitId, refilled_at=datetime.now())
        if not editedToolkit:
            logger.error("Инструмент не обновлен")
            return False
        return True

    async def edit(toolkitId: int, **kwargs):
        query = select(Toolkit).where(Toolkit.id == toolkitId)
        toolkit = await CRUD.read(query)
        if not toolkit:
            logger.error("Инструмент не найден")
            return {}
        try:
            if "image" in kwargs:
                title = kwargs.get("title", toolkit.title)

                imageData = kwargs.pop("image")
                imageDict = {"main": "", "additional": []}

                existImagesList = [toolkit.image.get("main")]
                existImagesList.extend(toolkit.image.get("additional"))

                newImagesList = [imageData.get("main")]
                newImagesList.extend(imageData.get("additional"))

                for existImage in existImagesList:
                    if existImage not in newImagesList:
                        deleteImage(existImage)

                if toolkit.image.get("main") != imageData.get("main"):
                    if imageData.get("main") in existImagesList:
                        imageDict["main"] = imageData.get("main")
                    else:
                        imageFileName = handleToolkitImage(imageData.get("main"), title)
                        if imageFileName:
                            imageDict["main"] = imageFileName
                        else:
                            imageDict["main"] = "images/tools/default.png"

                imageDict["additional"].extend(imageData.get("additional"))

                uploadList = imageData.get("upload", [])
                if len(uploadList) > 0:
                    for image in uploadList:
                        imageFileName = handleToolkitImage(image, title)
                        if imageFileName:
                            imageDict["additional"].append(imageFileName)

                kwargs["image"] = imageDict
            user_id = kwargs.pop("user_id", None)
            logger.debug(f"Обновление инструмента {toolkit.title}...")
            editedToolkit = await toolkit.edit(**kwargs)
        except Exception as e:
            logger.error(f"Ошибка обновления инструмента: {str(e)}")
            return {}

        if not editedToolkit:
            logger.error("Инструмент не обновлен")
            return {}

        logger.info(
            f"Инструмент {editedToolkit.title} успешно обновлен, изменены данные: {kwargs.keys()}"
        )
        await ServiceRecordsHandler.add(
            user_id, {f"Обновлен инструмент {toolkit.title}": editedToolkit.toDict()}
        )
        return editedToolkit.toDict()

    async def getAll():
        query = select(Toolkit)
        toolkits = await CRUD.read(query, True)
        return [toolkit.toDict() for toolkit in toolkits] if toolkits else []

    async def get(toolkitId: int):
        query = select(Toolkit).where(Toolkit.id == toolkitId)
        toolkit = await CRUD.read(query)
        if not toolkit:
            logger.error("Инструмент не найден")
            return {}
        return toolkit.toDict()

    async def getSeveral(toolkitIds: list[int]) -> list[dict]:
        query = select(Toolkit).where(Toolkit.id.in_(toolkitIds))
        toolkits = await CRUD.read(query, True)
        return [toolkit.toDict() for toolkit in toolkits] if toolkits else []

    async def delete(toolkitId: int, user_id: int = None):
        query = select(Toolkit).where(Toolkit.id == toolkitId)
        toolkit = await CRUD.read(query)
        if not toolkit:
            logger.error("Инструмент не найден")
            return False
        try:
            toolkitTitle = toolkit.title
            result = await CRUD.delete(toolkit)
        except Exception as e:
            logger.error(f"Ошибка удаления инструмента: {str(e)}")
            return False
        logger.info(
            f"Инструмент {toolkitTitle} {'успешно удален' if result else 'не удален'}"
        )
        await ServiceRecordsHandler.add(
            user_id, {"Удален инструмент": f"Название: {toolkitTitle}"}
        )
        return result

    async def initialize():
        from .categories import CategoryHandler

        logger.info("Инициализация инструментов")
        categoriesList = await CategoryHandler.getAll()
        categories = {category["title"]: category["id"] for category in categoriesList}

        baseToolkits = [
            {
                "title": "Фреза №1",
                "description": "Фреза такая сякая этакая #1",
                "specifications": {
                    "Диаметр": "10",
                    "Длина": "20",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Фрезеровка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Фреза №2",
                "description": "Фреза такая сякая этакая #2",
                "specifications": {
                    "Диаметр": "10",
                    "Длина": "20",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Фрезеровка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Фреза №3",
                "description": "Фреза такая сякая этакая #3",
                "specifications": {
                    "Диаметр": "10",
                    "Длина": "20",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Фрезеровка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Пластина №1",
                "description": "Пластина такая сякая этакая #1",
                "specifications": {
                    "Размер": "10",
                    "Радиус": "0.4",
                    "Ещё что-то": "Ещё столько-то",
                },
                "image": {
                    "main": "static/images/tools/default.png",
                    "additional": [
                        "static/images/users/default.png",
                        "static/images/logo.png",
                    ],
                },
                "category_id": categories["Токарка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Пластина №2",
                "description": "Пластина такая сякая этакая #2",
                "specifications": {
                    "Размер": "10",
                    "Радиус": "0.4",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Токарка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Пластина №3",
                "description": "Пластина такая сякая этакая #3",
                "specifications": {
                    "Размер": "10",
                    "Радиус": "0.4",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Токарка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Сверло №1",
                "description": "Сверло такое сякое этакое #1",
                "specifications": {
                    "Длина": "30",
                    "Диаметр": "5",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Слесарка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Сверло №2",
                "description": "Сверло такое сякое этакое #2",
                "specifications": {
                    "Длина": "30",
                    "Диаметр": "5",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Слесарка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
            {
                "title": "Сверло №3",
                "description": "Сверло такое сякое этакое #3",
                "specifications": {
                    "Длина": "30",
                    "Диаметр": "5",
                    "Ещё что-то": "Ещё столько-то",
                },
                "category_id": categories["Слесарка"],
                "quantity_min": 20,
                "quantity_min_extra": 10,
                "external_link": "https://nazv.ru",
            },
        ]

        for toolkit in baseToolkits:
            await ToolkitHandler.add(toolkit)

        logger.info("Базовые инструменты успешно созданы")
        return
