package com.tuoheng.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tuoheng.common.ServiceException;
import com.tuoheng.constant.*;
import com.tuoheng.mapper.*;
import com.tuoheng.model.dto.*;
import com.tuoheng.model.param.*;
import com.tuoheng.model.po.AuthoritiesPo;
import com.tuoheng.model.po.ClientUserRolePo;
import com.tuoheng.model.po.TenantPo;
import com.tuoheng.model.po.UserPo;
import com.tuoheng.model.query.TenantQuery;
import com.tuoheng.model.query.UserQuery;
import com.tuoheng.model.vo.BusinessSystemVo;
import com.tuoheng.model.vo.TenantVo;
import com.tuoheng.model.vo.UserVo;
import com.tuoheng.service.ClientUserSevice;
import com.tuoheng.until.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author chenjiandong
 * @description: TODO
 * @date 2022/10/8 11:35
 */
@Service
@Slf4j
public class ClientUserServiceImpl implements ClientUserSevice {

    @Autowired
    private ClientUserMapper clientUserMapper;

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private AuthoritiesMapper authoritiesMapper;

    @Autowired
    private ClientUserRoleMapper clientUserRoleMapper;

    @Override
    @Transactional(readOnly = true)
    public JsonResult judgeCreate(String username) {
        if (clientUserMapper.judgeCreateByUserName(username) > 0) {
            return JsonResult.success(false);
        }
        return JsonResult.success(true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult createClientUser(CreateClientUserDto createClientUserDto, LoginUser loginUser) {

        log.info("请求参数:{}", createClientUserDto.toString());
        if (clientUserMapper.judgeCreateByUserName(createClientUserDto.getUsername()) > 0) {
            return JsonResult.error("该账号已存在");
        } else {
            UserPo userPo = new UserPo()
                    .setUsername(createClientUserDto.getUsername())
                    .setPassword("{bcrypt}" + new BCryptPasswordEncoder().encode(createClientUserDto.getPassword()));
            userPo.setCreateUser(loginUser.getUserId());
            //租户逻辑新增 start
            if (createClientUserDto.getTenantFlag() != null) {
                if (createClientUserDto.getTenantFlag() == 1) {
                    userPo.setIsTenant(1);
                } else {
                    userPo.setIsTenant(0);
                    UserPo po = clientUserMapper.getUserByUserName(createClientUserDto.getTenantName());
                    if (po != null) {
                        userPo.setTenantId(po.getId());
                    }
                }
            }
            //租户逻辑新增 end
            clientUserMapper.insertClientUser(userPo);
            if (createClientUserDto.getTenantFlag() != null) {
                if (createClientUserDto.getTenantFlag() == 1) {
                    TenantPo tenantPo = new TenantPo();
                    tenantPo.setUserId(userPo.getId());
                    //添加租户code
                    tenantPo.setCode(createClientUserDto.getCode());
                    tenantPo.setName(createClientUserDto.getName());
                    tenantPo.setProvinceCode(createClientUserDto.getProvinceCode());
                    tenantPo.setProvinceName(createClientUserDto.getProvinceName());
                    tenantPo.setDistrictCode(createClientUserDto.getDistrictCode());
                    tenantPo.setDistrictName(createClientUserDto.getDistrictName());
                    tenantPo.setCityCode(createClientUserDto.getCityCode());
                    tenantPo.setCityName(createClientUserDto.getCityName());
                    log.debug("信息:" + tenantPo.toString());
                    tenantMapper.insertTenant(tenantPo);
                }
            }
            return getObjectJsonResult(createClientUserDto, loginUser);
        }
    }

    /**
     * 用户/租户更新关联关系
     *
     * @param createClientUserDto
     * @param loginUser
     * @return
     */
    private JsonResult getObjectJsonResult(CreateClientUserDto createClientUserDto, LoginUser loginUser) {
        UserPo userPo = clientUserMapper.getUserByUserName(createClientUserDto.getUsername());
        if (ObjectUtil.isNull(userPo)) {
            return JsonResult.error("此用户不存在");
        }
        List<AuthoritiesPo> authoritiesPos = new ArrayList<>();
        List<ClientUserRolePo> clientUserRolePoArrayList = new ArrayList<>();
        for (ClientRoleDto clientRoleDto : createClientUserDto.getClientRoleDtoList()) {
            AuthoritiesPo authoritiesPo = new AuthoritiesPo()
                    .setUserId(userPo.getId())
                    .setUsername(createClientUserDto.getUsername())
                    .setAuthority(clientRoleDto.getClientId());
            authoritiesPo.setCreateUser(loginUser.getUserId());
            authoritiesPos.add(authoritiesPo);

            ClientUserRolePo clientUserRolePo = new ClientUserRolePo()
                    .setUserId(userPo.getId())
                    .setClientId(clientRoleDto.getClientId())
                    .setRoleId(clientRoleDto.getRoleId());
            clientUserRolePo.setCreateUser(loginUser.getUserId());
            clientUserRolePoArrayList.add(clientUserRolePo);

        }
        authoritiesMapper.batchInsert(authoritiesPos);
        clientUserRoleMapper.batchInsert(clientUserRolePoArrayList);
        return JsonResult.success(userPo.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateUserPassword(UpdateUserPassDto updateUserPassDto, LoginUser loginUser) {

        if (clientUserMapper.getUserByUserName(updateUserPassDto.getUsername()) == null) {
            return JsonResult.error("该用户不存在！");
        }
        UserPo userPo = new UserPo()
                .setUsername(updateUserPassDto.getUsername())
                .setPassword("{bcrypt}" + new BCryptPasswordEncoder().encode(updateUserPassDto.getPassword()));
        userPo.setUpdateUser(loginUser.getUserId());
        clientUserMapper.updatePass(userPo);
        return JsonResult.success(true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateUserClientRole(UpdateUserClientRoleDto updateUserClientRoleDto, LoginUser loginUser) {
        UserPo userPo = clientUserMapper.getUserByUserName(updateUserClientRoleDto.getUsername());
        if (userPo == null) {
            return JsonResult.error("该用户不存在！");
        }
        List<ClientRoleDto> clientRoleDtoList = updateUserClientRoleDto.getClientRoleDtoList();
        for (ClientRoleDto dto : clientRoleDtoList) {
            ClientUserRolePo clientUserRolePo = new ClientUserRolePo()
                    .setUserId(userPo.getId())
                    .setClientId(dto.getClientId())
                    .setRoleId(dto.getRoleId());
            clientUserRolePo.setUpdateUser(loginUser.getUserId());
            if (clientUserRoleMapper.updateUserClientRole(clientUserRolePo) == 0) {
                ClientUserRolePo insert = new ClientUserRolePo();
                insert.setUserId(userPo.getId())
                        .setClientId(dto.getClientId())
                        .setRoleId(dto.getRoleId())
                        .setCreateUser(loginUser.getUserId());
                clientUserRoleMapper.insert(insert);
            }
        }
        return JsonResult.success(true);
    }
}
