package com.usky.system.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.system.domain.*;
import com.usky.system.mapper.SysTenantMapper;
import com.usky.system.mapper.SysUserTenantMapper;
import com.usky.system.service.ISysDeptService;
import com.usky.system.service.ISysRoleService;
import com.usky.system.service.SysTenantPlatformService;
import com.usky.system.service.SysTenantService;
import com.usky.system.service.vo.SysTenantOneVo;
import com.usky.system.service.vo.SysTenantTwoVo;
import com.usky.system.service.vo.SysTenantVo;
import com.usky.system.service.vo.TenantPlatformVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 租户信息表 服务实现类
 * </p>
 *
 * @author ya
 * @since 2022-05-05
 */
@Service
public class SysTenantServiceImpl extends AbstractCrudService<SysTenantMapper, SysTenant> implements SysTenantService {

    @Autowired
    private ISysDeptService iSysDeptService;
    @Autowired
    private SysUserTenantMapper sysUserTenantMapper;
    @Autowired
    private SysTenantMapper sysTenantMapper;
    @Autowired
    private SysTenantPlatformService sysTenantPlatformService;
    @Autowired
    private ISysRoleService roleService;

    @Override
    public List<SysTenantVo> getUserData() {
        Integer userId = SecurityUtils.getUserId().intValue();
        List<SysTenantVo> list = baseMapper.getUserData(userId);
        return list;
    }

    /**
     * 手机端APP租户管理-权限配置-目录查询
     *
     * @param domain
     * @return
     */
    @Override
    public List<SysTenant> getAppData(String domain){
        List<SysTenant> list = baseMapper.getAppData(domain);
        return list;
    }

    /**
     * 租户管理-租户列表查询
     *
     * @param sysTenantOneVo
     * @return
     */
    @Override
    public CommonPage<SysTenantTwoVo> getTenantData(SysTenantOneVo sysTenantOneVo) {
        if (sysTenantOneVo.getStatus() == null || sysTenantOneVo.getStatus().equals("") || sysTenantOneVo.getStatus().equals("null")) {
            sysTenantOneVo.setStatus("0");
        }
        List<SysTenantTwoVo> list1 = baseMapper.getTenantData(sysTenantOneVo.getTenantName(),
                sysTenantOneVo.getTenantManager(),
                sysTenantOneVo.getTenantType(),
                sysTenantOneVo.getStatus(),
                sysTenantOneVo.getPlatformName(),
                sysTenantOneVo.getStartTime(),
                sysTenantOneVo.getEndTime(), null, null, sysTenantOneVo.getId());
        int total = 0;
        if (list1.size() > 0) {
            total = list1.size();
        }
        Integer current = null;
        if (sysTenantOneVo.getPage() != null && sysTenantOneVo.getSize() > 0) {
            current = (sysTenantOneVo.getPage() - 1) * sysTenantOneVo.getSize();
        }
        List<SysTenantTwoVo> list = baseMapper.getTenantData(sysTenantOneVo.getTenantName(),
                sysTenantOneVo.getTenantManager(),
                sysTenantOneVo.getTenantType(),
                sysTenantOneVo.getStatus(),
                sysTenantOneVo.getPlatformName(),
                sysTenantOneVo.getStartTime(),
                sysTenantOneVo.getEndTime(),
                current,
                sysTenantOneVo.getSize(),
                sysTenantOneVo.getId());
        return new CommonPage<>(list, total, sysTenantOneVo.getSize(), sysTenantOneVo.getPage());
    }

    @Override
    public void addTenantData(SysTenant sysTenant) {
        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        sysTenant.setTenantCode(uuid);
//        sysTenant.setStatus("0");
        sysTenant.setCreateBy(SecurityUtils.getUsername());
        sysTenant.setCreateTime(LocalDateTime.now());
        this.save(sysTenant);
        Integer tenantId = sysTenant.getId();
        SysDept sysDept = new SysDept();
        sysDept.setTenantId(tenantId);
        sysDept.setDeptName(sysTenant.getTenantName());
        sysDept.setOrderNum("0");
        sysDept.setEmail(sysTenant.getEmail());
        sysDept.setPhone(sysTenant.getPhoneNumber());
        sysDept.setCreateBy(SecurityUtils.getUsername());
        iSysDeptService.insertDept(sysDept);

        //base_space
        sysTenantMapper.insertBaseSpace(sysTenant.getTenantName(),tenantId);

        TenantPlatformVo tenantPlatformVo = new TenantPlatformVo();
        tenantPlatformVo.setPlatformIds(new Integer[]{Integer.parseInt(sysTenant.getSystemName())});
        tenantPlatformVo.setRequestId(0);
        tenantPlatformVo.setTenantId(tenantId);
        sysTenantPlatformService.updateTenantPlatform(tenantPlatformVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cloneTenantData(SysTenant sysTenant) {
        Integer originalTenantId = sysTenant.getOriginalTenantId();

        String uuid = UUID.randomUUID().toString();
        uuid = uuid.replace("-", "");
        sysTenant.setTenantCode(uuid);
        sysTenant.setCreateBy(SecurityUtils.getUsername());
        sysTenant.setCreateTime(LocalDateTime.now());
        this.save(sysTenant);
        Integer tenantId = sysTenant.getId();

        SysDept sysDept = new SysDept();
        sysDept.setTenantId(tenantId);
        sysDept.setDeptName(sysTenant.getTenantName());
        sysDept.setOrderNum("0");
        sysDept.setEmail(sysTenant.getEmail());
        sysDept.setPhone(sysTenant.getPhoneNumber());
        sysDept.setCreateBy(SecurityUtils.getUsername());
        iSysDeptService.insertDept(sysDept);

        //base_space
        sysTenantMapper.insertBaseSpace(sysTenant.getTenantName(),tenantId);

        //在用户租户表中添加克隆账号id与租户id绑定关系
        SysUserTenant sysUserTenant = new SysUserTenant();
        sysUserTenant.setUserId(SecurityUtils.getUserId());
        sysUserTenant.setTenantId(tenantId);
        int userCount = sysUserTenantMapper.checkUserIdUnique(sysUserTenant.getTenantId(), sysUserTenant.getUserId());
        if (userCount > 0){
            throw new BusinessException("用户已绑定，无法重复绑定！");
        }else {
            sysUserTenantMapper.insert(sysUserTenant);
        }

        //克隆系统配置
        sysTenantMapper.cloneSysTenantConfig(originalTenantId,tenantId,SecurityUtils.getUsername());
        sysTenantMapper.cloneSysTenantMenu(originalTenantId,tenantId);
        sysTenantMapper.cloneSysMobileTenantConfig(originalTenantId,tenantId,SecurityUtils.getUsername());
        sysTenantMapper.cloneSysMobileBanner(originalTenantId,tenantId,SecurityUtils.getUsername());
        //克隆应用授权和权限配置
        sysTenantMapper.cloneSysTenantPlatform(originalTenantId,tenantId);
        sysTenantMapper.cloneSysMobileTenantMenu(originalTenantId,tenantId);
        //克隆用户角色和租户用户角色
        //sys_role
        List<SysUserRole> sysUserRoleList = sysTenantMapper.selectSysUserRoleList(originalTenantId,SecurityUtils.getUserId());
        if(sysUserRoleList.size()>0){
            for (int i = 0; i < sysUserRoleList.size(); i++) {
                SysRole role = new SysRole();
                long originalRoleId = sysUserRoleList.get(i).getRoleId();
                LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.select(SysRole::getRoleName,SysRole::getRoleKey,SysRole::getRoleSort,SysRole::getDataScope,SysRole::getStatus).eq(SysRole::getRoleId, originalRoleId);
                SysRole one = roleService.getOne(queryWrapper);
                role.setRoleName(one.getRoleName());
                role.setRoleKey(one.getRoleKey());
                role.setRoleSort(one.getRoleSort());
                role.setDataScope(one.getDataScope());
                role.setStatus(one.getStatus());
                role.setCreateBy(SecurityUtils.getUsername());
                role.setCreateTime(DateTime.now());
                role.setTenantId(tenantId);
                roleService.insertRole(role);
                long roleId = role.getRoleId();
                //sys_role_menu
                sysTenantMapper.cloneSysRoleMenu(originalRoleId,roleId);
                //sys_user_role
                sysTenantMapper.insertSysUserRole(SecurityUtils.getUserId(),roleId,tenantId);
            }
        }

        //更新默认应用
        TenantPlatformVo tenantPlatformVo = new TenantPlatformVo();
        tenantPlatformVo.setPlatformIds(new Integer[]{Integer.parseInt(sysTenant.getSystemName())});
        tenantPlatformVo.setRequestId(0);
        tenantPlatformVo.setTenantId(tenantId);
        sysTenantPlatformService.updateTenantPlatform(tenantPlatformVo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delTenantData(Integer tenantId) {
        sysTenantMapper.delSysTenant(tenantId);
        sysTenantMapper.delBaseSpace(tenantId);
        sysTenantMapper.delSysDept(tenantId);
        sysTenantMapper.delSysUser(tenantId);
        sysTenantMapper.delSysUserTenant(tenantId);
        sysTenantMapper.delSysTenantConfig(tenantId);
        sysTenantMapper.delSysTenantMenu(tenantId);
        sysTenantMapper.delSysTenantPlatform(tenantId);
        sysTenantMapper.delSysMobileBanner(tenantId);
        sysTenantMapper.delSysMobileTenantConfig(tenantId);
        sysTenantMapper.delSysMobileTenantMenu(tenantId);

        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(SysRole::getRoleId).eq(SysRole::getTenantId, tenantId);
        List<SysRole> list = roleService.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(list)){
            for (int i = 0; i < list.size(); i++) {
                long roleId = list.get(i).getRoleId();
                sysTenantMapper.delSysRoleMenu(roleId);
            }
        }
        sysTenantMapper.delSysRole(tenantId);
        sysTenantMapper.delSysUserRole(tenantId);
    }

    @Override
    public void updateTenantData(SysTenant sysTenant) {
        sysTenant.setUpdateBy(SecurityUtils.getUsername());
        sysTenant.setUpdateTime(LocalDateTime.now());
        this.updateById(sysTenant);
    }


    @Override
    public CommonPage<SysTenantTwoVo> getTenantDataOne(String tenantName, String tenantManager, Integer page, Integer size) {
        List<SysTenantTwoVo> list1 = baseMapper.getTenantDataOne(tenantName, tenantManager, null, null);
        int total = 0;
        if (list1.size() > 0) {
            total = list1.size();
        }
        Integer current = null;
        if (page != null && size > 0) {
            current = (page - 1) * size;
        }
        List<SysTenantTwoVo> list = baseMapper.getTenantDataOne(tenantName, tenantManager, current, size);
        return new CommonPage<>(list, total, size, page);
    }
}
