package admin_role

import (
	"context"

	"tydata-server/app/main/api/internal/svc"
	"tydata-server/app/main/api/internal/types"
	"tydata-server/app/main/model"
	"tydata-server/common/xerr"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
)

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

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

func (l *CreateRoleLogic) CreateRole(req *types.CreateRoleReq) (resp *types.CreateRoleResp, err error) {
	// 检查角色编码是否已存在
	roleModel, err := l.svcCtx.AdminRoleModel.FindOneByRoleCode(l.ctx, req.RoleCode)
	if err != nil && err != model.ErrNotFound {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建角色失败: %v", err)
	}
	if roleModel != nil && roleModel.RoleName == req.RoleName {
		return nil, errors.Wrapf(xerr.NewErrMsg("角色名称已存在"), "创建角色失败, 角色名称已存在: %v", err)
	}
	// 创建角色
	role := &model.AdminRole{
		RoleName:    req.RoleName,
		RoleCode:    req.RoleCode,
		Description: req.Description,
		Status:      req.Status,
		Sort:        req.Sort,
	}
	var roleId int64
	// 使用事务创建角色和关联菜单
	err = l.svcCtx.AdminRoleModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		// 创建角色
		result, err := l.svcCtx.AdminRoleModel.Insert(ctx, session, role)
		if err != nil {
			return errors.New("插入新角色失败")
		}
		roleId, err = result.LastInsertId()
		if err != nil {
			return errors.New("获取新角色ID失败")
		}

		// 创建角色菜单关联
		if len(req.MenuIds) > 0 {
			for _, menuId := range req.MenuIds {
				roleMenu := &model.AdminRoleMenu{
					RoleId: roleId,
					MenuId: menuId,
				}
				_, err = l.svcCtx.AdminRoleMenuModel.Insert(ctx, session, roleMenu)
				if err != nil {
					return errors.New("插入角色菜单关联失败")
				}
			}
		}

		return nil
	})
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建角色失败: %v", err)
	}

	return &types.CreateRoleResp{
		Id: roleId,
	}, nil
}
