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 DeleteRoleLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

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

func (l *DeleteRoleLogic) DeleteRole(req *types.DeleteRoleReq) (resp *types.DeleteRoleResp, err error) {
	// 检查角色是否存在
	_, err = l.svcCtx.AdminRoleModel.FindOne(l.ctx, req.Id)
	if err != nil {
		if errors.Is(err, model.ErrNotFound) {
			return nil, errors.Wrapf(xerr.NewErrMsg("角色不存在"), "删除角色失败, 角色不存在err: %v", err)
		}
		return nil, err
	}

	// 使用事务删除角色和关联数据
	err = l.svcCtx.AdminRoleModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
		// 删除角色菜单关联
		builder := l.svcCtx.AdminRoleMenuModel.SelectBuilder().
			Where("role_id = ?", req.Id)
		menus, err := l.svcCtx.AdminRoleMenuModel.FindAll(ctx, builder, "id ASC")
		if err != nil {
			return err
		}
		for _, menu := range menus {
			err = l.svcCtx.AdminRoleMenuModel.Delete(ctx, session, menu.Id)
			if err != nil {
				return err
			}
		}

		// 删除角色用户关联
		builder = l.svcCtx.AdminUserRoleModel.SelectBuilder().
			Where("role_id = ?", req.Id)
		users, err := l.svcCtx.AdminUserRoleModel.FindAll(ctx, builder, "id ASC")
		if err != nil {
			return err
		}
		for _, user := range users {
			err = l.svcCtx.AdminUserRoleModel.Delete(ctx, session, user.Id)
			if err != nil {
				return err
			}
		}

		// 删除角色
		err = l.svcCtx.AdminRoleModel.Delete(ctx, session, req.Id)
		if err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "删除角色失败err: %v", err)
	}

	return &types.DeleteRoleResp{
		Success: true,
	}, nil
}
