package logic

import (
	"context"
	"encoding/json"
	"errors"
	"juwan-backend/app/shop/rpc/internal/models/schema"
	"juwan-backend/app/snowflake/rpc/snowflake"
	pb2 "juwan-backend/app/users/rpc/pb"
	"slices"
	"strings"

	"juwan-backend/app/shop/rpc/internal/svc"
	"juwan-backend/app/shop/rpc/pb"

	"github.com/shopspring/decimal"
	"github.com/zeromicro/go-zero/core/logx"
)

type AddShopsLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewAddShopsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddShopsLogic {
	return &AddShopsLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

var allowedRoles = []string{"owner", "admin"}
var allowedCommissionTypes = []string{"fixed", "percentage"}
var allowedDispatchModes = []string{"manual", "auto"}

// -----------------------shops-----------------------
func (l *AddShopsLogic) AddShops(in *pb.AddShopsReq) (*pb.AddShopsResp, error) {
	user, err := l.svcCtx.UsersRpc.GetUsersById(l.ctx, &pb2.GetUsersByIdReq{
		Id: in.OwnerId,
	})
	if err != nil {
		logx.Errorf("add shops err: %v", err)
		return nil, errors.New("user not found")
	}

	if !slices.Contains(allowedRoles, user.Users.CurrentRole) {
		logx.Errorf("add shops err: user %v has no permission to add shop", in.OwnerId)
		return nil, errors.New("no permission to add shop")
	}

	idResp, err := l.svcCtx.Snowflake.NextId(l.ctx, &snowflake.NextIdReq{})
	if err != nil {
		logx.Errorf("addPlayerServices err:%v", err)
		return nil, errors.New("create player service id failed")
	}

	var templateConfig map[string]interface{}
	err = json.Unmarshal([]byte(in.TemplateConfig), &templateConfig)
	if err != nil {
		logx.Errorf("addPlayerServices err:%v", err)
		return nil, errors.New("invalid template config")
	}

	rating, err := decimal.NewFromString(in.Rating)
	if err != nil {
		logx.Errorf("addPlayerServices new from string err:%v", err)
		return nil, errors.New("invalid rating")
	}
	commissionValue, err := decimal.NewFromString(in.CommissionValue)
	if err != nil {
		logx.Errorf("addPlayerServices new from string err:%v", err)
		return nil, errors.New("invalid commissionValue")
	}

	commissionType := strings.ToLower(strings.TrimSpace(in.CommissionType))
	if commissionType == "" {
		commissionType = "percentage"
	}
	if !slices.Contains(allowedCommissionTypes, commissionType) {
		logx.Errorf("addPlayerServices contains err: invalid commissionType %v", in.CommissionType)
		return nil, errors.New("invalid commissionType")
	}

	dispatchMode := strings.ToLower(strings.TrimSpace(in.DispatchMode))
	if dispatchMode == "" {
		dispatchMode = "manual"
	}
	if !slices.Contains(allowedDispatchModes, dispatchMode) {
		logx.Errorf("addPlayerServices contains err: invalid dispatchMode %v", in.DispatchMode)
		return nil, errors.New("invalid dispatchMode")
	}

	announcements := schema.TextArray{Elements: in.Announcements, Valid: true}
	if announcements.Elements == nil {
		announcements.Elements = []string{}
	}

	_, err = l.svcCtx.ShopModelRW.Shops.Create().
		SetID(idResp.Id).
		SetOwnerID(in.OwnerId).
		SetName(in.Name).
		SetBanner(in.Banner).
		SetDescription(in.Description).
		SetRating(rating).
		SetTotalOrders(int(in.TotalOrders)).
		SetPlayerCount(int(in.PlayerCount)).
		SetCommissionType(commissionType).
		SetCommissionValue(commissionValue).
		SetAllowMultiShop(in.AllowMultiShop).
		SetAllowIndependentOrders(in.AllowIndependentOrders).
		SetDispatchMode(dispatchMode).
		SetAnnouncements(announcements).
		SetTemplateConfig(templateConfig).
		Save(l.ctx)

	if err != nil {
		logx.Errorf("addPlayerServices err:%v", err)
		return nil, errors.New("add player service failed")
	}
	logx.Debugf("shop created with id: %v", idResp.Id)
	return &pb.AddShopsResp{}, nil
}
