package dictionary

import (
	"context"
	"git.noahlan.cn/n-admin/n-admin-server/dal/errx"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent/dictionary"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/svc"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/utils/entx"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/internal/utils/hander"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/types/core"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus/code"
	"git.noahlan.cn/noahlan/ntool-biz/core/nstatus/msg"
	"git.noahlan.cn/noahlan/ntool-biz/core/orm/nent/types"
)

type UpdateDictionaryLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUpdateDictionaryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateDictionaryLogic {
	return &UpdateDictionaryLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UpdateDictionaryLogic) UpdateDictionary(in *core.DictionaryInfo) (*core.BaseResp, error) {
	if err := entx.WithTx(l.ctx, l.svcCtx.DB, func(tx *ent.Tx) error {
		var err error
		if err := l.preCheck(tx, in); err != nil {
			return err
		}
		update := tx.Dictionary.Update().Where(dictionary.IDEQ(in.ID))
		update.SetNotEmptyTitle(in.Title).
			SetNotEmptyName(in.Name).
			SetNotEmptyDescription(in.Description)
		if in.Status != "" {
			update.SetStatus(types.ParseStatus(in.Status))
		}
		err = update.Exec(l.ctx)
		if err != nil {
			return hander.HandleEntErr(err, in)
		}
		return nil
	}); err != nil {
		return nil, err
	}
	return &core.BaseResp{
		Code: code.StatusOK,
		Msg:  msg.UpdateSuccess,
	}, nil
}

func (l *UpdateDictionaryLogic) preCheck(tx *ent.Tx, in *core.DictionaryInfo) error {
	if in.Name == "" {
		return nstatus.NewBizErrWithCode(errx.DictionaryNameNotEmpty)
	} else {
		exist, err := tx.Dictionary.Query().Where(dictionary.NameEQ(in.Name)).Exist(l.ctx)
		if err != nil {
			return hander.HandleEntErr(err, in)
		}
		if exist {
			return nstatus.NewBizErrWithCode(errx.DictionaryNameInUsed)
		}
	}
	return nil
}
