from ssb_pubmd.adapters.content_parser import ContentParser
from ssb_pubmd.adapters.document_processor import DocumentProcessor
from ssb_pubmd.adapters.publish_client import PublishClient
from ssb_pubmd.adapters.storage import Storage

USER_KEY_PREFIX = "user:"
DOCUMENT_KEY = "app:document"

def sync_document(
    raw_document_content: str,
    document_processor: DocumentProcessor,
    content_parser: ContentParser,
    storage: Storage,
    publish_client: PublishClient,
) -> str:
    document_processor.load(raw_document_content)

    document_metadata = document_processor.extract_metadata(target_key="ssb")
    document_metadata["content_type"] = "article"

    document_publish_path = storage.get(DOCUMENT_KEY).get("publish_path")
    if not document_publish_path:
        content = content_parser.parse(metadata=document_metadata, html=None)
        response = publish_client.send_content(content)
        storage.update(
            DOCUMENT_KEY,
            {"publish_id": response.publish_id, "publish_path": response.publish_path},
        )
        document_publish_path = response.publish_path

    document_elements = document_processor.extract_elements(target_class="ssb")
    for id_, html in document_elements:
        key = USER_KEY_PREFIX + id_
        metadata = storage.get(key) | {"publish_folder": document_publish_path}
        component = content_parser.parse(metadata, html)
        response = publish_client.send_content(component)
        storage.update(key, {"publish_id": response.publish_id})
        document_processor.replace_element(id_, response.publish_html)

    article_metadata = document_metadata | {
        "publish_id": storage.get(DOCUMENT_KEY).get("publish_id")
    }
    html = document_processor.extract_html()
    article = content_parser.parse(metadata=article_metadata, html=html)
    response = publish_client.send_content(article)
    return response.publish_url
