from __future__ import annotations

import traceback

from typing import TYPE_CHECKING

from django_spire.contrib.service import BaseDjangoModelService
from django_spire.core.decorators import close_db_connections
from django_spire.knowledge.entry.version.block.models import EntryVersionBlock
from django_spire.knowledge.exceptions import KnowledgeBaseConversionError

if TYPE_CHECKING:
    from django_spire.knowledge.entry.models import Entry


class EntryAutomationService(BaseDjangoModelService['Entry']):
    obj: Entry

    @close_db_connections
    def convert_files_to_model_objects(self) -> str:
        file_objects = self.obj_class.services.tool.get_files_to_convert()

        entries = self.obj_class.objects.id_in(
            list({file_object.object_id for file_object in file_objects})
        ).select_related('current_version')

        entry_pk_map = {entry.pk: entry for entry in entries}

        errored = []
        for file_object in file_objects:
            try:
                EntryVersionBlock.services.factory.create_blocks_from_file(
                    file=file_object,
                    entry_version=entry_pk_map[file_object.object_id].current_version,
                )
            except Exception as e:
                errored.append({'file': file_object.name, 'error': traceback.format_exc()})
                file_object.set_deleted()
            else:
                file_object.set_deleted()

        message = f'Files Converted: {len(file_objects) - len(errored)}'

        if errored:
            error_string = f'\n{message}\nFiles Errored:'

            for error in errored:
                error_string += f'    File Name: {error["file"]}\n    Error: {error["error"]}'

            raise KnowledgeBaseConversionError(error_string)

        return message
