"""Bluesky CRDT document builder.

Builds pycrdt Doc objects from ParsedBlueSkyDocument models.
"""

from __future__ import annotations

import json
from typing import Any

from pycrdt import Doc, XmlElement

from marqetive.utils.crdt.builders.base import BaseCRDTBuilder
from marqetive.utils.crdt.models import ParsedBlueSkyDocument


class BlueskyCRDTBuilder(BaseCRDTBuilder[ParsedBlueSkyDocument]):
    """Builder for Bluesky CRDT documents."""

    @property
    def platform_name(self) -> str:
        return "bluesky"

    @property
    def root_node_type(self) -> str:
        return "blueskycard"

    def build_document(
        self, parsed: ParsedBlueSkyDocument, fragment_name: str = "default"
    ) -> Doc[Any]:
        """Build a Bluesky CRDT Doc from a parsed document.

        Creates blueskycard nodes for each card, and optionally a
        blueskythread node if auto_number_config is present.
        """
        children: list[XmlElement] = []

        # Build blueskythread node if auto_number_config present
        if parsed.auto_number_config is not None:
            config = parsed.auto_number_config
            config_dict = {
                "enabled": config.enabled,
                "position": config.position,
                "formatStyle": config.format_style,
                "skipFirst": config.skip_first,
                "skipLast": config.skip_last,
            }
            thread_attrs = {"autoNumberConfig": json.dumps(config_dict)}
            children.append(XmlElement("blueskythread", attributes=thread_attrs))

        # Build card nodes
        for i, card in enumerate(parsed.cards):
            attrs: dict[str, str] = {}
            if card.id is not None:
                attrs["id"] = card.id
            else:
                attrs["id"] = f"card_{i}"

            if card.media:
                attrs["media"] = self._build_media_attribute(card.media)

            if card.og is not None:
                attrs["og"] = card.og

            paragraphs = self._build_text_paragraphs(card.text)
            children.append(
                XmlElement("blueskycard", attributes=attrs, contents=paragraphs)
            )

        return self._create_doc_with_fragment(fragment_name, children)
