from dataclasses import dataclass

from ssb_pubmd.adapters.cms_client import CmsClient
from ssb_pubmd.adapters.cms_client.models import CmsRequest
from ssb_pubmd.adapters.cms_client.models import CmsResponse
from ssb_pubmd.adapters.document_processor import DocumentProcessor
from ssb_pubmd.adapters.storage import Storage
from ssb_pubmd.interface.component.models import Article

ARTICLE_KEY = "article"


@dataclass
class DocumentPublisher:
    document_processor: DocumentProcessor
    storage: Storage
    cms_client: CmsClient

    def sync_document(self, raw_content: str) -> str:
        self.document_processor.load(raw_content)
        article_metadata = self.document_processor.extract_metadata(target_key="ssb")
        user_data = Article(**article_metadata)

        cms_request = CmsRequest(
            target_folder=article_metadata["path"],
            user_data=user_data,
        )
        cms_response = self._ensure_article_exists(cms_request)

        self._sync_document_elements(cms_response.content_path)

        cms_request.content_id = cms_response.content_id
        cms_request.html = self.document_processor.extract_html()
        cms_response = self.cms_client.send(cms_request)
        self.storage.update(ARTICLE_KEY, cms_response)

        return cms_response.preview_url

    def _ensure_article_exists(self, cms_request: CmsRequest) -> CmsResponse:
        stored_cms_response = self.storage.get_cms_data(ARTICLE_KEY)
        if stored_cms_response is not None:
            return stored_cms_response
        cms_response = self.cms_client.send(cms_request)
        self.storage.update(ARTICLE_KEY, cms_response)
        return cms_response

    def _sync_document_elements(self, article_publish_path: str) -> None:
        elements = self.document_processor.extract_elements(target_class="ssb")
        for element in elements:
            stored_user_data = self.storage.get_user_data(element.id)
            stored_cms_data = self.storage.get_cms_data(element.id)

            cms_request = CmsRequest(
                target_folder=article_publish_path,
                user_data=stored_user_data,
                html=element.inner_html,
            )
            if stored_cms_data is not None:
                cms_request.content_id = stored_cms_data.content_id
            cms_response = self.cms_client.send(cms_request)

            self.storage.update(key=element.id, data=cms_response)
            self.document_processor.replace_element(
                element.id, new_html=cms_response.html_snippet
            )
