package com.cpop.oam.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.LoginUser;
import com.cpop.core.base.entity.PageDomain;
import com.cpop.core.base.entity.loginInfo.OamStaffLoginInfo;
import com.cpop.core.base.enums.InitRoleEnum;
import com.cpop.core.base.enums.SourceType;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.SysUser;
import com.cpop.core.service.CoreService;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.*;
import com.cpop.core.utils.sql.SqlUtils;
import com.cpop.core.utils.uuid.IdUtils;
import com.cpop.oam.business.bo.MallStaffBo;
import com.cpop.oam.business.bo.MallStaffPageBo;
import com.cpop.oam.business.bo.StaffBo;
import com.cpop.oam.business.entity.Staff;
import com.cpop.oam.business.service.OamMallService;
import com.cpop.oam.business.vo.MallStaffPageVo;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

import static com.cpop.core.base.table.table.SysUserTableDef.SYS_USER;
import static com.cpop.system.business.entity.table.RoleTableDef.ROLE;

/**
 * @author DB
 * @createTime 2023/11/09 14:42
 * @description
 */
@Service("oamMallService")
public class OamMallServiceImpl implements OamMallService {

    /**
     * @descriptions 查询商城管理员分页列表
     * @author DB
     * @date 2023/11/09 14:47
     * @return: com.mybatisflex.core.paginate.Page<com.cpop.oam.business.vo.MallStaffPageVo>
     */
    @Override
    public Page<MallStaffPageVo> getMallStaffPage(String brandIds, String name) {
        PageDomain pageDomain = SqlUtils.getInstance().getPageDomain();
        QueryWrapper queryWrapper = QueryWrapper.create();
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.and("name like ?", name + "%");
        }
        if (StringUtils.isNotBlank(brandIds)) {
            queryWrapper.in("cp_mall_role_brand.brand_id", Arrays.asList(brandIds.split(",")));
        }
        Page<Row> rowPage = Db.paginate("cp_mall_staff", pageDomain.getPageNum(), pageDomain.getPageSize(),
                queryWrapper.select("cp_mall_staff.*")
                        .select(SYS_USER.USER_NAME, SYS_USER.AVATAR, SYS_USER.EMAIL, SYS_USER.NICK_NAME, SYS_USER.PASSWORD, SYS_USER.PHONE_NUMBER, SYS_USER.SEX, SYS_USER.STATUS)
                        //角色
                        .select("cp_sys_role.role_name", "cp_sys_role.id as roleId")
                        //品牌
                        .select("cp_sys_brand.id as brandId", "cp_sys_brand.brand_name")
                        .from("cp_mall_staff")
                        .leftJoin(SYS_USER).on("cp_sys_user.id = cp_mall_staff.user_id")
                        .leftJoin("cp_mall_role_brand").on("cp_mall_role_brand.id = cp_mall_staff.role_brand_id")
                        .leftJoin("cp_sys_role").on("cp_sys_role.id = cp_mall_role_brand.role_id")
                        .leftJoin("cp_sys_brand").on("cp_sys_brand.id = cp_mall_role_brand.brand_id")
                        .where(SYS_USER.USER_TYPE.eq(UserType.MALL_USER))
                        .and("cp_mall_staff.is_delete = 0"));
        return rowPage.map(item -> RowUtil.toEntity(item, MallStaffPageVo.class));
    }

    /**
     * @descriptions 新增管理员
     * @author DB
     * @date 2023/11/10 12:14
     * @param bo 请求参数
     * @return: void
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertAdmin(MallStaffBo bo) {
        //先添加用户信息
        SysUser sysUser;
        if (validatedUserInfo(bo)) {
            throw new ServiceException(MessageUtils.message("i18n_alert_userOrPhoneOrEmailIsExist"));
        } else {
            //用户名-手机-邮箱都需要做唯一校验
            sysUser = BeanUtils.mapToClass(bo, SysUser.class);
            //解密与重设密码
            decryptAndResetPasswords(sysUser);
            sysUser.setId(IdUtils.fastSimpleUUID());
            //获取当前创建人员信息
            LoginUser loginUser = SecurityUtils.getInstance().getLoginUser();
            sysUser.setCreateUserId(loginUser.getUserId());
            sysUser.setUpdateUserId(loginUser.getUserId());
            sysUser.setUserType(UserType.MALL_USER.toString());
            SpringUtils.getBean(CoreService.class).insertSysUser(sysUser);
        }
        LocalDateTime now = LocalDateTime.now();
        //创建中间表
        Row roleBrand = Row.ofKey(RowKey.SNOW_FLAKE_ID);
        roleBrand.set("brand_id", bo.getBrandId())
                .set("role_id", InitRoleEnum.SUPER_MALL_ROLE.getId())
                .set("create_time", now)
                .set("update_time", now)
                .set("create_user_id", 1)
                .set("update_user_id", 1);
        Db.insert("cp_mall_role_brand",roleBrand);
        Row mallStaff = Row.ofKey(RowKey.SNOW_FLAKE_ID);
        mallStaff.set("name", bo.getName())
                .set("role_brand_id", roleBrand.getString("id"))
                .set("user_id", sysUser.getId())
                .set("create_time", now)
                .set("update_time", now)
                .set("create_user_id", 1)
                .set("update_user_id", 1);
        long count = DbChain.table("cp_j_brand_extend").where("brand_id = ?", bo.getBrandId()).count();
        if (count > 0) {
            mallStaff.set("source_type", SourceType.JAMBOX.toString());
        } else {
            mallStaff.set("source_type", SourceType.COMMON.toString());
        }
        Db.insert("cp_mall_staff", mallStaff);
    }

    /**
     * @descriptions 删除管理员
     * @author DB
     * @date 2023/11/10 14:34
     * @param id 主键
     * @return: void
     */
    @Override
    public void removeAdmin(String id) {
        //查询员工信息
        Row staff = DbChain.table("cp_mall_staff").where("id = ?", id).one();
        if (null != staff) {
            DbChain.table("cp_mall_staff")
                    .set("is_delete", 1)
                    .where("id = ?", id)
                    .update();
            DbChain.table("cp_mall_role_brand")
                    .where("id = ?", staff.getString("roleBrandId"))
                    .remove();
            //删除系统用户
            SpringUtils.getBean(CoreService.class).removeSysUserById(staff.getString("userId"));
        }
    }

    /**
     * @Description: 用户名-手机-邮箱都需要做唯一校验
     * @param bo 请求参数
     * @return Boolean 通过/未通过
     * @Author DB
     * @Date: 2023/5/11 11:02
     **/
    private Boolean validatedUserInfo(MallStaffBo bo) {
        long count = DbChain.table(SYS_USER)
                //用户名
                .where(SYS_USER.USER_NAME.eq(bo.getUserName()))
                //手机号
                .or(SYS_USER.PHONE_NUMBER.eq(bo.getPhoneNumber()))
                .count();
        if (StringUtils.isNotBlank(bo.getUserId())) {
            return count > 1;
        } else {
            return count > 0;
        }
    }

    /**
     * @Description: 解密与重设密码
     * @param sysUser 系统用户
     * @Author: DB
     * @Date: 2023/5/11 11:03
     **/
    private void decryptAndResetPasswords(SysUser sysUser) {
        //先用rsa解密
        String password = SpringUtils.getBean(RsaUtils.class).decrypt(sysUser.getPassword());
        //再加密
        sysUser.setPassword(SpringUtils.getBean(PasswordEncoder.class).encode(password));
    }
}
