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

from temporalio import activity, workflow

from csirtmu.beta_temporal.config import AppConfig
from csirtmu.beta_temporal.constants import WorkflowReference
from csirtmu.beta_temporal.external_services.rt.client import RTClient
from csirtmu.beta_temporal.workflows.logging import LoggedActivities, LoggedScheduledWorkflow


class OpenStalledOverdueTicketsActivities(LoggedActivities):
    def __init__(self, rt_client: RTClient, queues: list[str]) -> None:
        self.rt_client = rt_client
        self.queues = queues

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

    @activity.defn
    async def open_stalled_overdue_tickets(self) -> None:
        self.log_activity()
        time = datetime.datetime.now(tz=datetime.UTC).strftime("%Y-%m-%d %H:%M:%S")
        data = self.rt_client.search(
            raw_query="("
            + " OR ".join([f"Queue = '{queue}'" for queue in self.queues])
            + f") AND Status = 'stalled' AND Due < '{time}'"
        )
        for ticket in data:
            self.rt_client.edit_ticket(ticket["id"], Status="act")


class OpenStalledOverdueTickets(LoggedScheduledWorkflow, workflow_name=WorkflowReference.OPEN_STALLED_OVERDUE_TICKETS):
    @classmethod
    def get_schedule_interval(cls) -> timedelta:
        return datetime.timedelta(hours=AppConfig.get().periodic_workflow_config.interval_hours)

    @classmethod
    def get_schedule_args(cls) -> tuple[Any, ...]:
        return ()

    @classmethod
    def get_schedule_task_queue(cls) -> str:
        return AppConfig.get().temporal.periodic_tasks_queue

    @classmethod
    def get_activities(cls) -> Sequence[Callable[..., Awaitable[Any]]]:
        config = AppConfig.get()
        return OpenStalledOverdueTicketsActivities(
            RTClient(config.rt), config.periodic_workflow_config.queues
        ).get_activities()

    @workflow.run
    async def run(self) -> None:
        self.log_workflow()
        config = AppConfig.get()
        await workflow.execute_activity(
            OpenStalledOverdueTicketsActivities.open_stalled_overdue_tickets,
            args=(),
            retry_policy=config.temporal.retry_policy,
            start_to_close_timeout=config.temporal.activity_timeout,
        )
