import asyncio
import logging
from typing import TYPE_CHECKING

import nats
import sentry_sdk
import structlog
from csirtmu.core.temporal.config import create_temporal_client
from redis import Redis

if TYPE_CHECKING:
    from nats.aio.client import Client
    from nats.aio.subscription import Subscription
    from nats.js import JetStreamContext

    from csirtmu.beta.handler import Handler
from csirtmu.core.logging import setup_logging

from csirtmu.beta.config import AppConfig
from csirtmu.beta.handler_builder import HandlerBuilder

logger: logging.Logger = structlog.getLogger()


async def main() -> None:
    config = AppConfig.get()
    setup_logging(
        config.logging.level_const,
        config.logging.pretty_print_exceptions,
        config.logging.verbose_origin,
        config.logging.formatter_const,
        [],
    )

    if config.monitoring is not None:
        sentry_sdk.init(
            dsn=config.monitoring.dsn,
            traces_sample_rate=config.monitoring.traces_sample_rate,
            profiles_sample_rate=config.monitoring.profiles_sample_rate,
        )
    nc: Client = await nats.connect(
        config.nats.host,
        name=config.nats.subscriber_name,
        user=config.nats.username,
        password=config.nats.password,
    )
    tc = await create_temporal_client(config.temporal, config.temporal.default_task_queue)
    redis = Redis(config.redis.host, config.redis.port, username=config.redis.username, password=config.redis.password)
    handler: Handler = HandlerBuilder(tc, redis).build(config.queue_mapping)

    if config.transaction_retention.use_jetstream:
        js: JetStreamContext = nc.jetstream()
        sub: Subscription = await js.subscribe(config.nats.subject, cb=handler.process_transaction, manual_ack=True)
    else:
        sub: Subscription = await nc.subscribe(config.nats.subject, cb=handler.process_transaction)

    while True:
        logger.info(f"Accepted {sub.delivered} transactions in current run")
        await asyncio.sleep(5)


if __name__ == "__main__":
    asyncio.run(main())
