# scraper2_hj3415/app/nfs/adapters/out/sinks/nfs_mongo_sink.py
from __future__ import annotations

from collections.abc import Iterable

from contracts_hj3415.common.envelope import NfsEnvelopeDTO
from db2_hj3415.common.types import MongoDoc
from db2_hj3415.nfs import mappers, repo
from db2_hj3415.nfs.domain import NfsLatestDoc, NfsSnapshotDoc
from logging_hj3415 import logger
from pymongo.asynchronous.database import AsyncDatabase
from scraper2_hj3415.app.nfs.ports.sinks.nfs_sink_port import NfsSinkPort


class NfsMongoSink(NfsSinkPort):
    _db: AsyncDatabase[MongoDoc]

    def __init__(self, db: AsyncDatabase[MongoDoc]):
        self._db = db

    async def write(self, env: NfsEnvelopeDTO) -> None:
        code = env.get("key")
        if not code:
            return

        latest_doc = mappers.envelope_to_latest_doc(env)
        snapshot_doc = mappers.envelope_to_snapshot_doc(env)
        _ = await repo.upsert_latest_doc(self._db, doc=latest_doc)
        _ = await repo.insert_snapshot_doc(self._db, doc=snapshot_doc)

    async def write_many(self, envs: Iterable[NfsEnvelopeDTO]) -> None:
        latest_out: list[NfsLatestDoc] = []
        snapshot_out: list[NfsSnapshotDoc] = []
        for env in envs:
            code = env.get("key")
            if not code:
                continue
            latest_doc = mappers.envelope_to_latest_doc(env)
            snapshot_doc = mappers.envelope_to_snapshot_doc(env)
            latest_out.append(latest_doc)
            snapshot_out.append(snapshot_doc)

        if latest_out:
            res = await repo.upsert_latest_docs(self._db, docs=latest_out)
            logger.info(f"latest inserted: {res}")
        if snapshot_out:
            res = await repo.insert_snapshot_docs(self._db, docs=snapshot_out)
            logger.info(f"snapshots inserted: {res}")
