package com.cpop.mall.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cpop.common.utils.StringUtils;
import com.cpop.common.utils.bean.BeanUtils;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.utils.SecurityUtils;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.sql.SqlUtils;
import com.cpop.mall.business.bo.MallRoleBo;
import com.cpop.mall.business.bo.MallRolePageBo;
import com.cpop.mall.business.entity.RoleBrand;
import com.cpop.mall.business.mapper.RoleBrandMapper;
import com.cpop.mall.business.service.RoleBrandService;
import com.cpop.mall.business.vo.MallRolePageVo;
import com.cpop.system.business.bo.RoleStatusBo;
import com.cpop.system.business.entity.Role;
import com.cpop.system.business.entity.RoleMenu;
import com.cpop.system.business.service.RoleMenuService;
import com.cpop.system.business.service.RoleService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static com.cpop.mall.business.entity.table.RoleBrandTableDef.ROLE_BRAND;
import static com.cpop.mall.business.entity.table.StaffTableDef.STAFF;
import static com.cpop.system.business.entity.table.BrandTableDef.BRAND;
import static com.cpop.system.business.entity.table.MenuTableDef.MENU;
import static com.cpop.system.business.entity.table.RoleMenuTableDef.ROLE_MENU;
import static com.cpop.system.business.entity.table.RoleTableDef.ROLE;
import static com.mybatisflex.core.query.QueryMethods.distinct;
import static com.mybatisflex.core.query.QueryMethods.groupConcat;

/**
 * 商城-角色-品牌id 服务层实现。
 *
 * @author DB
 * @since 2023-10-19
 */
@Service("roleBrandService")
public class RoleBrandServiceImpl extends ServiceImpl<RoleBrandMapper, RoleBrand> implements RoleBrandService {

    /**
     * @descriptions 查询商城角色分页列表
     * @author DB
     * @date 2023/09/10 16:51
     * @param bo 请求参数
     * @return R<PageVo<SysRolePageVo>>
     */
    @Override
    public Page<MallRolePageVo> getMallRolePageList(MallRolePageBo bo) {
        //获取当前登录用户信息
        JSONObject staffInfo = SecurityUtils.getInstance().getLoginUserInfo();
        //获取分页参数
        PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
        return this.mapper.paginateAs(pageDomain.getPageNum(), pageDomain.getPageSize(),
                QueryWrapper.create()
                        .select(distinct(ROLE_BRAND.ALL_COLUMNS))
                        //角色信息
                        .select(ROLE.ROLE_NAME, ROLE.ROLE_VALUE, ROLE.STATUS, ROLE.REMARK, ROLE.ORDER_NO, ROLE.CREATE_TIME)
                        .select(groupConcat(MENU.ID).as(MallRolePageVo::getMenuIds))
                        .leftJoin(STAFF).on(STAFF.ROLE_BRAND_ID.eq(ROLE_BRAND.ID))
                        .leftJoin(ROLE).on(ROLE.ID.eq(ROLE_BRAND.ROLE_ID))
                        //左联品牌表
                        .leftJoin(BRAND).on(ROLE_BRAND.ID.eq(ROLE_BRAND.BRAND_ID))
                        //角色菜单中甲表
                        .leftJoin(ROLE_MENU).on(ROLE_MENU.ROLE_ID.eq(ROLE_BRAND.ROLE_ID))
                        .leftJoin(MENU).on(MENU.ID.eq(ROLE_MENU.MENU_ID))
                        .where(ROLE_BRAND.BRAND_ID.eq(staffInfo.getString("roleBrandId")))
                        .and(ROLE.ROLE_NAME.like(bo.getRoleName()))
                        .and(ROLE.STATUS.eq(bo.getStatus()))
                        .groupBy(ROLE_BRAND.ID)
                        .orderBy(ROLE.ORDER_NO.asc())
                , MallRolePageVo.class);
    }

    /**
     * @descriptions 新增角色
     * @author DB
     * @date 2023/10/12 10:48
     * @param bo 请求参数
     * @return: com.cpop.core.base.R<java.lang.Void>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertMallRole(MallRoleBo bo) {
        Role role = BeanUtils.mapToClass(bo, Role.class);
        SpringUtils.getBean(RoleService.class).save(role);
        //将菜单信息录入中间表
        if (!bo.getMenuIds().isEmpty()) {
            List<RoleMenu> roleMenus = new ArrayList<>();
            bo.getMenuIds().forEach(item -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setMenuId(item);
                roleMenu.setRoleId(role.getId());
                roleMenus.add(roleMenu);
            });
            SpringUtils.getBean(RoleMenuService.class).saveBatch(roleMenus);
        }
        //录入商城角色品牌表
        RoleBrand roleBrand = new RoleBrand();
        if (StringUtils.isBlank(bo.getBrandId())){
            JSONObject loginStaffInfo = SecurityUtils.getInstance().getLoginUserInfo();
            roleBrand.setRoleId(role.getId())
                    .setBrandId(loginStaffInfo.getString("brandId"));
        } else {
            roleBrand.setRoleId(role.getId())
                    .setBrandId(bo.getBrandId());
        }
        this.save(roleBrand);
    }

    /**
     * @descriptions 修改角色
     * @author DB
     * @date 2023/09/10 17:45
     * @param bo 请求参数
     * @return com.jambox.core.base.R<java.lang.Void>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMallRole(MallRoleBo bo) {
        Role entity = new Role();
        BeanUtils.copyBeanProp(entity, bo);
        entity.setId(bo.getRoleId());
        SpringUtils.getBean(RoleService.class).updateById(entity);
        //将菜单信息录入中间表
        if (!bo.getMenuIds().isEmpty()) {
            //先删后存
            RoleMenuService sysRoleMenuService = SpringUtils.getBean(RoleMenuService.class);
            sysRoleMenuService.remove(QueryWrapper.create()
                    .where(ROLE_MENU.ROLE_ID.eq(entity.getId())));
            List<RoleMenu> roleMenus = new ArrayList<>();
            bo.getMenuIds().forEach(item -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setMenuId(item);
                roleMenu.setRoleId(entity.getId());
                roleMenus.add(roleMenu);
            });
            sysRoleMenuService.saveBatch(roleMenus);
        }
    }

    /**
     * @Description: 删除商城角色
     * @param id 主键
     * @return
     * @Author DB
     * @Date: 2023/10/19 22:34
     */
    @Override
    public void removeMallRole(String id) {
        //获取中间表
        RoleBrand roleBrand = this.queryChain().where(ROLE_BRAND.ID.eq(id)).one();
        //删除角色
        SpringUtils.getBean(RoleService.class).removeById(roleBrand.getRoleId());
        //删除相关联菜单
        SpringUtils.getBean(RoleMenuService.class).remove(QueryWrapper.create().where(ROLE_MENU.ROLE_ID.eq(roleBrand.getRoleId())));
        this.removeById(id);
    }

    /**
     * @Description: 设置角色状态
     * @param bo 请求参数
     * @return: R<Void>
     * @Author: DB
     * @Date: 2023/5/9 14:13
     **/
    @Override
    public void setMallRoleStatus(RoleStatusBo bo) {
        //获取中间表
        RoleBrand roleBrand = this.queryChain().where(ROLE_BRAND.ID.eq(bo.getId())).one();
        SpringUtils.getBean(RoleService.class).updateChain()
                .set(ROLE.STATUS, bo.getStatus())
                .where(ROLE.ID.eq(roleBrand.getRoleId()))
                .update();
    }
}
