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

from temporalio import activity, workflow

from csirtmu.beta_temporal.commons.actions.temporal_common_actions import TemporalCommonActions
from csirtmu.beta_temporal.config import AppConfig
from csirtmu.beta_temporal.constants import WorkflowReference
from csirtmu.beta_temporal.external_services.rt import structs
from csirtmu.beta_temporal.external_services.rt.client import RTClient
from csirtmu.beta_temporal.workflows.logging import LoggedActivities, LoggedWorkflow


class ChangeSubjectOfAutomaticReportOnCorrespondActivities(LoggedActivities):
    def __init__(self, rt_client: RTClient) -> None:
        self.rt_client = rt_client

    def get_activities(self) -> Sequence[Callable[..., Any]]:
        return [self.is_automatic_report, self.change_subject_on_automatic_report]

    @activity.defn
    async def is_automatic_report(self, transaction: structs.TransactionStruct) -> bool:
        self.log_activity()
        return (
            transaction.ticket_obj is not None
            and transaction.interface is not None
            and transaction.interface.lower() != "web"
            and transaction.ticket_obj.subject == "Automatic ticket placeholder"
        )

    @activity.defn
    async def change_subject_on_automatic_report(self, transaction: structs.TransactionStruct) -> None:
        self.log_activity()
        if (
            transaction.ticket_obj is None
            or (ticket_data := self.rt_client.get_ticket_data(transaction)) is None
            or len(ticket_data.attachments) == 0
        ):
            return
        subject = ticket_data.attachments[0].subject
        self.rt_client.edit_ticket(transaction.ticket_obj.id, Subject=re.sub(r"\[.*]\s*", "", subject))


class ChangeSubjectOfAutomaticReportOnCorrespond(
    LoggedWorkflow, workflow_name=WorkflowReference.CHANGE_SUBJECT_OF_AUTOMATIC_REPORT_ON_CORRESPOND
):
    @classmethod
    def get_activities(cls) -> Sequence[Callable[..., Awaitable[Any]]]:
        config = AppConfig.get()
        local_activities = ChangeSubjectOfAutomaticReportOnCorrespondActivities(RTClient(config.rt))
        temporal = TemporalCommonActions(config.temporal)
        return [*local_activities.get_activities(), *temporal.get_activities()]

    @workflow.run
    async def run(self, transaction: structs.TransactionStruct) -> None:
        self.log_workflow()
        config = AppConfig.get()
        if await workflow.execute_activity(
            ChangeSubjectOfAutomaticReportOnCorrespondActivities.is_automatic_report,
            args=(transaction,),
            retry_policy=config.temporal.retry_policy,
            start_to_close_timeout=config.temporal.activity_timeout,
        ):
            await workflow.execute_activity(
                ChangeSubjectOfAutomaticReportOnCorrespondActivities.change_subject_on_automatic_report,
                args=(transaction,),
                retry_policy=config.temporal.retry_policy,
                start_to_close_timeout=config.temporal.activity_timeout,
            )
        elif config.temporal.allow_internal_cancels:
            await workflow.execute_activity(
                TemporalCommonActions.cancel_workflow,
                args=(workflow.info().workflow_id, workflow.info().task_queue),
                retry_policy=config.temporal.retry_policy,
                start_to_close_timeout=config.temporal.activity_timeout,
            )
