package user

import (
	"context"
	"errors"
	"fmt"
	"time"

	"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
	"github.com/SamuelTariku/FortuneBet-Backend/internal/pkgs/helpers"
	afro "github.com/amanuelabay/afrosms-go"
	"github.com/resend/resend-go/v2"
	"golang.org/x/crypto/bcrypt"
)

func (s *Service) SendOtp(ctx context.Context, sentTo string, otpFor domain.OtpFor, medium domain.OtpMedium) error {
	otpCode := helpers.GenerateOTP()

	message := fmt.Sprintf("Welcome to Fortune bets, your OTP is %s please don't share with anyone.", otpCode)

	switch medium {
	case domain.OtpMediumSms:
		if err := s.SendSMSOTP(ctx, sentTo, message); err != nil {
			return err
		}
	case domain.OtpMediumEmail:
		if err := s.SendEmailOTP(ctx, sentTo, message); err != nil {
			return err
		}
	}

	otp := domain.Otp{
		SentTo:    sentTo,
		Medium:    medium,
		For:       otpFor,
		Otp:       otpCode,
		Used:      false,
		CreatedAt: time.Now(),
		ExpiresAt: time.Now().Add(OtpExpiry),
	}

	return s.otpStore.CreateOtp(ctx, otp)
}

func hashPassword(plaintextPassword string) ([]byte, error) {
	hash, err := bcrypt.GenerateFromPassword([]byte(plaintextPassword), 12)
	if err != nil {
		return []byte{}, err
	}

	return hash, nil
}

func (s *Service) SendSMSOTP(ctx context.Context, receiverPhone, message string) error {
	apiKey := s.config.AFRO_SMS_API_KEY
	senderName := s.config.AFRO_SMS_SENDER_NAME
	hostURL := s.config.ADRO_SMS_HOST_URL
	endpoint := "/api/send"

	// API endpoint has been updated
	// TODO: no need for package for the afro message operations (pretty simple stuff)
	request := afro.GetRequest(apiKey, endpoint, hostURL)
	request.BaseURL = "https://api.afromessage.com/api/send"

	request.Method = "GET"
	request.Sender(senderName)
	request.To(receiverPhone, message)

	response, err := afro.MakeRequestWithContext(ctx, request)
	if err != nil {
		return err
	}

	if response["acknowledge"] == "success" {
		return nil
	} else {
		fmt.Println(response["response"].(map[string]interface{}))
		return errors.New("SMS delivery failed")
	}
}

func (s *Service) SendEmailOTP(ctx context.Context, receiverEmail, message string) error {
	apiKey := s.config.ResendApiKey
	client := resend.NewClient(apiKey)
	formattedSenderEmail := "FortuneBets <" + s.config.ResendSenderEmail + ">"
	params := &resend.SendEmailRequest{
		From:    formattedSenderEmail,
		To:      []string{receiverEmail},
		Subject: "FortuneBets - One Time Password",
		Text:    message,
	}

	_, err := client.Emails.Send(params)
	if err != nil {
		return err
	}

	return nil
}
