import datetime
from collections.abc import Awaitable, Callable, Sequence
from typing import Any

from structlog import getLogger
from temporalio import workflow
from temporalio.exceptions import CancelledError, TemporalError

from csirtmu.beta_temporal.config import AppConfig
from csirtmu.beta_temporal.constants import WorkflowReference
from csirtmu.beta_temporal.external_services.rt.structs import TransactionStruct
from csirtmu.beta_temporal.workflows.logging import LoggedWorkflow

logger = getLogger()


class HandleTransaction(LoggedWorkflow, workflow_name=WorkflowReference.HANDLE_TRANSACTION):
    @classmethod
    def get_activities(cls) -> Sequence[Callable[..., Awaitable[Any]]]:
        return []

    @workflow.run
    async def run(
        self, transaction: TransactionStruct, workflows: list[tuple[WorkflowReference, dict[str, Any] | None]]
    ) -> None:
        self.log_workflow()
        config = AppConfig.get()
        logger.info(f"Processing transaction {transaction.id}")
        for workflow_name, params in workflows:
            try:
                args = (transaction, params) if params else (transaction,)
                await workflow.execute_child_workflow(
                    workflow_name,
                    args=args,
                    id=f"{transaction.id}|{workflow_name}",
                    task_queue=config.temporal.beta_tasks_queue,
                    run_timeout=datetime.timedelta(seconds=config.temporal.child_workflow_timeout),
                )
            except TemporalError as e:
                if not isinstance(e.cause, CancelledError):
                    raise
        logger.info(f"Finished processing transaction {transaction.id}")
