package usecase

import (
	"backend/pkg/notification/domain/repository"
	"backend/pkg/notification/domain/usecase"
	"context"
	"sort"
	"time"
)

// DeliveryUseCaseParam 傳送參數配置
type DeliveryUseCaseParam struct {
	SMSProviders   []usecase.SMSProvider
	EmailProviders []usecase.EmailProvider
}

// DeliveryUseCase 通知
type DeliveryUseCase struct {
	param DeliveryUseCaseParam
}

func MustDeliveryUseCase(param DeliveryUseCaseParam) usecase.DeliveryUseCase {
	return &DeliveryUseCase{
		param: param,
	}
}

func (use *DeliveryUseCase) SendMessage(ctx context.Context, req usecase.SMSMessageRequest) error {
	var err error
	// 根據 Sort 欄位對 SMSProviders 進行排序
	sort.Slice(use.param.SMSProviders, func(i, j int) bool {
		return use.param.SMSProviders[i].Sort < use.param.SMSProviders[j].Sort
	})

	newCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()

	// 依序嘗試發送
	for _, provider := range use.param.SMSProviders {
		if err = provider.Repo.SendSMS(newCtx, repository.SMSMessageRequest{
			PhoneNumber:    req.PhoneNumber,
			RecipientName:  req.RecipientName,
			MessageContent: req.MessageContent,
		}); err == nil {
			return nil // 發送成功
		}
	}

	return err
}

func (use *DeliveryUseCase) SendEmail(ctx context.Context, req usecase.MailReq) error {
	var err error
	// 根據 Sort 欄位對 SMSProviders 進行排序
	sort.Slice(use.param.EmailProviders, func(i, j int) bool {
		return use.param.EmailProviders[i].Sort < use.param.EmailProviders[j].Sort
	})

	newCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()

	// 依序嘗試發送 dreq
	for _, provider := range use.param.EmailProviders {
		if err = provider.Repo.SendMail(newCtx, repository.MailReq{
			From:    req.From,
			To:      req.To,
			Subject: req.Subject,
			Body:    req.Body,
		}); err == nil {
			return nil // 發送成功
		}
	}

	return err
}
