package notification

import (
	"context"

	"github.com/prometheus/alertmanager/template"

	"github.com/pingcap-inc/clinic_cloud_server/pkg/alert/repo"
	"github.com/pingcap-inc/clinic_cloud_server/pkg/client/account"
	"github.com/pingcap-inc/clinic_cloud_server/pkg/entity"
)

type Interface interface {
	Push(
		ctx context.Context,
		alert template.Alert,
		subscribers []entity.AlertSubscribersItem,
		alertMeta AlertMeta,
		dryRun bool,
	) error

	PushAsync(
		ctx context.Context,
		alert template.Alert,
		subscribers []entity.AlertSubscribersItem,
		alertMeta AlertMeta,
		dryRun bool,
	)
}

type Client struct {
	email     Interface
	slack     Interface
	zoom      Interface
	flashduty Interface
	pagerduty Interface
	webhook   Interface
	lark      Interface
}

func New(accountClient *account.Client) Interface {
	return &Client{
		email: NewEmailNotification(accountClient, &repo.AlertNotificationRepo{}),
		slack: &SlackNotification{
			notificationRepo: &repo.AlertNotificationRepo{},
		},
		zoom: &ZoomNotification{
			notificationRepo: &repo.AlertNotificationRepo{},
		},
		flashduty: &FlashDutyNotification{
			notificationRepo: &repo.AlertNotificationRepo{},
		},
		pagerduty: &PagerDutyNotification{
			notificationRepo: &repo.AlertNotificationRepo{},
		},
		webhook: &WebhookNotification{
			notificationRepo: &repo.AlertNotificationRepo{},
		},
		lark: &LarkNotification{
			notificationRepo: &repo.AlertNotificationRepo{},
		},
	}
}

func (c *Client) Push(
	ctx context.Context,
	alert template.Alert,
	subscribers []entity.AlertSubscribersItem,
	alertMeta AlertMeta,
	dryRun bool,
) error {
	if err := c.email.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	if err := c.slack.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	if err := c.zoom.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	if err := c.flashduty.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	if err := c.pagerduty.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	if err := c.webhook.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	if err := c.lark.Push(ctx, alert, subscribers, alertMeta, dryRun); err != nil {
		return err
	}
	return nil
}

func (c *Client) PushAsync(
	ctx context.Context,
	alert template.Alert,
	subscribers []entity.AlertSubscribersItem,
	alertMeta AlertMeta,
	dryRun bool,
) {
	c.email.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
	c.slack.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
	c.zoom.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
	c.flashduty.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
	c.pagerduty.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
	c.webhook.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
	c.lark.PushAsync(ctx, alert, subscribers, alertMeta, dryRun)
}
