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

from temporalio import activity

from csirtmu.beta_temporal.external_services.mattermost.client import MattermostClient
from csirtmu.beta_temporal.external_services.rt import structs
from csirtmu.beta_temporal.workflows.logging import LoggedActivities


class MattermostActions(LoggedActivities):
    def __init__(self, rt_host: str, client: MattermostClient) -> None:
        self.rt_host = rt_host + ("" if rt_host.endswith("/") else "/")
        self.client = client

    def get_activities(self) -> Sequence[Callable[..., Any]]:
        return [
            self.notify_mattermost_on_email_ticket_create,
            self.notify_mattermost_on_testing_ticket,
            self.notify_mattermost_on_priority_ticket,
            self.notify_mattermost_on_analytics_category,
            self.notify_mattermost_on_pentest_ticket,
            self.notify_mattermost_on_certificate_ticket,
            self.notify_mattermost_on_failed_transactions,
        ]

    def _notify_mattermost(self, message: str) -> None:
        self.client.send_message(message)

    @activity.defn
    async def notify_mattermost_on_email_ticket_create(self, transaction: structs.TransactionStruct) -> None:
        self.log_activity()
        if transaction.ticket_obj is None:
            raise ValueError(f"TicketObj in transaction: {transaction} is None.")
        self._notify_mattermost(f"New email ticket {self.rt_host}Ticket/Display.html?id={transaction.ticket_obj.id}")

    @activity.defn
    async def notify_mattermost_on_testing_ticket(self, transaction: structs.TransactionStruct) -> None:
        self.log_activity()
        if transaction.ticket_obj is None:
            raise ValueError(f"TicketObj in transaction: {transaction} is None.")
        self._notify_mattermost(f"New testing ticket {self.rt_host}Ticket/Display.html?id={transaction.ticket_obj.id}")

    @activity.defn
    async def notify_mattermost_on_analytics_category(
        self, transaction: structs.TransactionStruct, channel: str
    ) -> None:
        self.log_activity()
        if transaction.ticket_obj is None:
            raise ValueError(f"TicketObj in transaction: {transaction} is None.")
        self.client.send_message(
            f"@all: Ticket for analytics: {transaction.ticket_obj.subject}, link: {self.rt_host}Ticket/Display.html?id={transaction.ticket_obj.id}",
            channel=channel,
            username="rt_bot",
            icon_emoji="sauron",
        )

    @activity.defn
    async def notify_mattermost_on_priority_ticket(self, transaction: structs.TransactionStruct, channel: str) -> None:
        self.log_activity()
        if transaction.ticket_obj is None:
            return
        if transaction.type == structs.TransactionTypeEnum.CREATE:
            message = "@channel: New priority ticket: "
        elif transaction.type == structs.TransactionTypeEnum.CORRESPOND:
            message = "@channel: Priority ticket update: "
        else:
            return
        message += (
            f"{transaction.ticket_obj.subject}, link: {self.rt_host}Ticket/Display.html?id={transaction.ticket_obj.id}"
        )
        self.client.send_message(message, channel=channel, username="rt_bot", icon_emoji="sauron")

    @activity.defn
    async def notify_mattermost_on_pentest_ticket(self, transaction: structs.TransactionStruct, channel: str) -> None:
        self.log_activity()
        if transaction.ticket_obj is None:
            return
        message = (
            "New ticket: "
            if transaction.type == structs.TransactionTypeEnum.CREATE
            else "New correspondence in ticket: "
        )
        message += (
            f"{transaction.ticket_obj.subject}, link: {self.rt_host}Ticket/Display.html?id={transaction.ticket_obj.id}"
        )
        self.client.send_message(message, channel=channel, username="rt_bot", icon_emoji="sauron")

    @activity.defn
    async def notify_mattermost_on_certificate_ticket(
        self, transaction: structs.TransactionStruct, channel: str
    ) -> None:
        self.log_activity()
        if transaction.ticket_obj is None:
            return
        message = f"@channel: New priority ticket: {transaction.ticket_obj.subject}, link: {self.rt_host}Ticket/Display.html?id={transaction.ticket_obj.id}"
        self.client.send_message(message, channel=channel, username="rt_bot")

    @activity.defn
    async def notify_mattermost_on_failed_transactions(self, channel: str, count: int) -> None:
        self.log_activity()
        self.client.send_message(
            f"Beta has established connection after an outage. Number of transactions stored in redis: {count}",
            channel=channel,
            username="rt_bot",
        )
