# Python imports
import json

# Django imports
from django.utils import timezone

# Third-party imports
from bs4 import BeautifulSoup

# Module imports
from plane.db.models import Page, PageLog
from celery import shared_task
from plane.utils.exception_logger import log_exception


def extract_components(value, tag):
    try:
        mentions = []
        html = value.get("description_html")
        soup = BeautifulSoup(html, "html.parser")
        mention_tags = soup.find_all(tag)

        for mention_tag in mention_tags:
            mention = {
                "id": mention_tag.get("id"),
                "entity_identifier": mention_tag.get("entity_identifier"),
                "entity_name": mention_tag.get("entity_name"),
            }
            mentions.append(mention)

        return mentions
    except Exception:
        return []


@shared_task
def page_transaction(new_value, old_value, page_id):
    try:
        page = Page.objects.get(pk=page_id)
        new_page_mention = PageLog.objects.filter(page_id=page_id).exists()

        old_value = json.loads(old_value) if old_value else {}

        new_transactions = []
        deleted_transaction_ids = set()

        # TODO - Add "issue-embed-component", "img", "todo" components
        components = ["mention-component"]
        for component in components:
            old_mentions = extract_components(old_value, component)
            new_mentions = extract_components(new_value, component)

            new_mentions_ids = {mention["id"] for mention in new_mentions}
            old_mention_ids = {mention["id"] for mention in old_mentions}
            deleted_transaction_ids.update(old_mention_ids - new_mentions_ids)

            new_transactions.extend(
                PageLog(
                    transaction=mention["id"],
                    page_id=page_id,
                    entity_identifier=mention["entity_identifier"],
                    entity_name=mention["entity_name"],
                    workspace_id=page.workspace_id,
                    created_at=timezone.now(),
                    updated_at=timezone.now(),
                )
                for mention in new_mentions
                if mention["id"] not in old_mention_ids or not new_page_mention
            )

        # Create new PageLog objects for new transactions
        PageLog.objects.bulk_create(
            new_transactions, batch_size=10, ignore_conflicts=True
        )

        # Delete the removed transactions
        PageLog.objects.filter(transaction__in=deleted_transaction_ids).delete()
    except Page.DoesNotExist:
        return
    except Exception as e:
        log_exception(e)
        return
