# -*- coding: utf-8 -*-
from __future__ import annotations

import logging
import uuid

from celery.result import AsyncResult
from django.utils.timezone import now

from hotpocket_backend.apps.bot.services import BotService
from hotpocket_backend.apps.saves.tasks import process_save

from .saves import SavesService

LOGGER = logging.getLogger(__name__)


class SaveProcessorService:
    class SaveProcessorServiceError(Exception):
        pass

    class SkipReprocessing(SaveProcessorServiceError):
        pass

    def process(self, *, pk: uuid.UUID) -> bool:
        result = True

        try:
            save = SavesService().get_for_processing(pk=pk)
            assert save is not None, ('Could not fetch the save.')

            title: str = save.url
            description: str | None = None
            is_netloc_banned = False

            try:
                bot_result = BotService().handle(url=save.url)

                if bot_result.title is not None:
                    title = bot_result.title

                description = bot_result.description
                is_netloc_banned = bot_result.is_netloc_banned
            except Exception as exception:
                LOGGER.error(
                    'Unhandled exception when fetching save content: %s',
                    exception,
                    exc_info=exception,
                )

                if save.last_processed_at is not None:
                    raise self.SkipReprocessing(
                        'Not re-processing the save fetch error!',
                    ) from exception

            save.title = title
            save.description = description
            save.is_netloc_banned = is_netloc_banned
            save.last_processed_at = now()
            save.save()
        except Exception as exception:
            LOGGER.error(
                'Unhandled exception: pk=`%s`: %s',
                pk,
                exception,
                exc_info=exception,
            )
            result = False

        return result

    def schedule_process_save(self, *, pk: uuid.UUID) -> AsyncResult:
        return process_save.apply_async(
            kwargs={
                'pk': pk,
            },
        )
