package business_profile

import (
	"context"
	"errors"
	"github.com/UpmeshLTD/urus-aio/infrastructure/db/entities"
	"github.com/UpmeshLTD/urus-aio/infrastructure/utils"
	"gorm.io/gorm"
	"log"
	"strings"
)

type Service interface {
	CreateBusinessProfile(ctx context.Context, profile *entities.BusinessProfile) (*entities.BusinessProfile, error)
	UpdateBusinessProfile(ctx context.Context, id string, profile *entities.BusinessProfile) error
	DeleteBusinessProfile(ctx context.Context, id string) error
	GetBusinessProfile(ctx context.Context, req *entities.BusinessProfile) (*entities.BusinessProfile, error)
}

type serviceImpl struct {
	repo Repository
}

func NewService(repo Repository) Service {
	return &serviceImpl{
		repo: repo,
	}
}

func (s *serviceImpl) CreateBusinessProfile(ctx context.Context, profile *entities.BusinessProfile) (*entities.BusinessProfile, error) {
	return s.repo.CreateBusinessProfile(ctx, profile)
}

func (s *serviceImpl) UpdateBusinessProfile(ctx context.Context, id string, profile *entities.BusinessProfile) error {
	return s.repo.UpdateBusinessProfile(ctx, id, profile)
}

func (s *serviceImpl) DeleteBusinessProfile(ctx context.Context, id string) error {
	return s.repo.DeleteBusinessProfile(ctx, id)
}

func (s *serviceImpl) GetBusinessProfile(ctx context.Context, req *entities.BusinessProfile) (*entities.BusinessProfile, error) {
	profile, err := s.repo.GetBusinessProfileByID(ctx, req.ID)
	if errors.Is(err, gorm.ErrRecordNotFound) {
		profile, err = s.repo.CreateBusinessProfile(ctx, &entities.BusinessProfile{
			ID:          req.ID,
			WorkspaceID: req.WorkspaceID,
		})
		if err != nil && !strings.Contains(err.Error(), "business_profiles_pkey") {
			log.Println("[GetBusinessProfile] CreateBusinessProfile", err.Error())
			return nil, errors.New("failed to create business profile")
		}
	}
	if utils.IsEmpty(profile.MerchantCode) {
		for i := 0; i < 3; i++ {
			code := utils.GenerateNumber()
			err = s.repo.UpdateBusinessProfile(ctx, req.ID, &entities.BusinessProfile{
				MerchantCode: &code,
			})
			if err == nil {
				profile.MerchantCode = &code
				break
			} else if !strings.Contains(err.Error(), "business_profiles_merchant_code_key") {
				log.Println("[GetBusinessProfile] UpdateBusinessProfile", err.Error())
				return nil, errors.New("failed to update business profile")
			}
		}
		if utils.IsEmpty(profile.MerchantCode) {
			return nil, errors.New("failed to update merchant code due to duplicated key")
		}
	}
	return profile, nil
}
