package com.yeejoin.amos.boot.module.hygf.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.boot.biz.common.constants.CommonConstant;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.biz.common.utils.TreeParser;
import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.hygf.api.dto.CommerceInfoDto;
import com.yeejoin.amos.boot.module.hygf.api.dto.UnitRegisterDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.CommerceInfo;
import com.yeejoin.amos.boot.module.hygf.api.entity.UnitInfo;
import com.yeejoin.amos.boot.module.hygf.api.fegin.PrivilegeFeginService;
import com.yeejoin.amos.boot.module.hygf.api.mapper.UnitInfoMapper;
import com.yeejoin.amos.boot.module.hygf.api.service.IUnitInfoService;
import com.yeejoin.amos.boot.module.hygf.api.dto.UnitInfoDto;
import com.yeejoin.amos.component.feign.config.TokenOperation;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 经销商人员信息服务实现类
 *
 * @author system_generator
 * @date 2023-07-07
 */
@Service
public class UnitInfoServiceImpl extends BaseService<UnitInfoDto,UnitInfo,UnitInfoMapper> implements IUnitInfoService {

    String COMPANY_TREE_REDIS_KEY = "REGULATOR_UNIT_TREE";

    @Value("${regulator.unit.code}")
    private String code;

    @Value("${dealer.appcode}")
    private String appCodes;

    @Autowired
    RedisUtils redisUtil;

    @Autowired
    PrivilegeFeginService privilegeFeginService;

    @Autowired
    CommerceInfoServiceImpl commerceInfoService;

    /**
     * 分页查询
     */
    public Page<UnitInfoDto> queryForUnitInfoPage(Page<UnitInfoDto> page)   {
        return this.queryForPage(page, null, false);
    }

    /**
     * 列表查询 示例
     */
    public List<UnitInfoDto> queryForUnitInfoList()   {
        return this.queryForList("" , false);
    }

    @Override
    public Collection getManagementUnitTree(String orgCode) {
        List<LinkedHashMap> companyModels = (List<LinkedHashMap>) redisUtil.get(COMPANY_TREE_REDIS_KEY);
        if (ValidationUtil.isEmpty(companyModels)) {
            companyModels = creatTree();
        }
        if (!ValidationUtil.isEmpty(orgCode)) {
            companyModels = findNodesByCondition(companyModels, "orgCode", orgCode, "children");
            companyModels = (List<LinkedHashMap>) companyModels.get(0).get("children");
        }
        return companyModels;
    }

    @Override
    public UnitRegisterDto registerUnit(UnitRegisterDto model) {
        UnitInfoDto regUnitInfo = model.getUnitInfoDto();
        try {
            // 1. 调用平台进行创建单位、用户信息
            this.createCompanyAndUser(regUnitInfo);
            // 2.插入单位表
            regUnitInfo = this.createWithModel(regUnitInfo);
            CommerceInfoDto commerceInfo = model.getCommerceInfoDto();
            commerceInfo.setUnitSeq(regUnitInfo.getSequenceNbr());
            commerceInfo = commerceInfoService.createWithModel(commerceInfo);
            model.setCommerceInfoDto(commerceInfo);
            model.setUnitInfoDto(regUnitInfo);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            // 失败后回滚：删除已经创建的企业信息
            if (!ObjectUtils.isEmpty(regUnitInfo.getAmosCompanySeq())) {
                FeignClientResult<CompanyModel> feignClientResult = Privilege.companyClient
                        .seleteOne(regUnitInfo.getAmosCompanySeq());
                if (feignClientResult != null) {
                    Privilege.companyClient.deleteCompany(regUnitInfo.getAmosCompanySeq().toString());
                }
            }
            // 失败后回滚：删除已经创建的管理员账号
            if (StringUtils.isNotEmpty(regUnitInfo.getAdminUserId())) {
                FeignClientResult<AgencyUserModel> feignClientResult = Privilege.agencyUserClient
                        .queryByUserId(regUnitInfo.getAdminUserId());
                if (feignClientResult != null) {
                    Privilege.agencyUserClient.multDeleteUser(regUnitInfo.getAdminUserId());
                }
            }
            throw new RuntimeException(e.getMessage());
        }
        return model;
    }

    private static List<LinkedHashMap> findNodesByCondition(List<LinkedHashMap> nodes, String conditionName,
                                                           String condition, String childName) {
        return nodes.stream()
                .flatMap(node -> Stream.concat(
                        node.get(conditionName).equals(condition) ? Stream.of(node) : Stream.empty(),
                        node.get(childName) != null ? findNodesByCondition((List<LinkedHashMap>) node.get(childName),
                                conditionName, condition, condition).stream() :
                                Stream.empty()
                ))
                .collect(Collectors.toList());
    }

    private List<LinkedHashMap> creatTree() {
        FeignClientResult tree = privilegeFeginService.tree(RequestContext.getToken(),RequestContext.getAppKey(),RequestContext.getProduct());
        List<LinkedHashMap> result = (List<LinkedHashMap>) tree.getResult();
        List<LinkedHashMap> treeData = deleteRegulatorTreeData(result);
        List<LinkedHashMap> supervisionTree = treeData.stream().filter(e -> code.equals(e.get("orgCode"))).collect(Collectors.toList());
        List<LinkedHashMap> resultTree = updateNullChildren(supervisionTree);
        redisUtil.set(COMPANY_TREE_REDIS_KEY, resultTree);
        return resultTree;
    }

    /**
     * 将管辖机构树中children为[]的修改为null
     *
     * @param result
     * @return
     */
    private List<LinkedHashMap> updateNullChildren(List<LinkedHashMap> result) {
        Iterator it = result.iterator();
        while (it.hasNext()) {
            LinkedHashMap e = (LinkedHashMap) it.next();
            //将管辖机构树中children为[]的修改为null
            if (e.get("children") != null) {
                if (((List<LinkedHashMap>) e.get("children")).size() == 0) {
                    e.put("children", null);
                }
            }
            if (!ObjectUtils.isEmpty(e.get("children"))) {
                updateNullChildren((List<LinkedHashMap>) e.get("children"));
            }
        }
        return result;
    }

    /**
     * 删除管辖机构树中level为使用单位的数据
     * @param result 管辖机构树
     * @return 筛选过滤后不包含使用单位的管辖机构树
     */
    private List<LinkedHashMap> deleteRegulatorTreeData(List<LinkedHashMap> result) {
        Iterator it = result.iterator();
        while (it.hasNext()) {
            LinkedHashMap e = (LinkedHashMap) it.next();
            //删除使用单位
            if ("company".equals(e.get("level"))) {
                it.remove();
            }
            if (e.get("companyName").toString().contains("行政审批局")) {
                it.remove();
            }
            if (!ObjectUtils.isEmpty(e.get("children"))) {
                deleteRegulatorTreeData((List<LinkedHashMap>) e.get("children"));
            }
        }
        return result;
    }

    private void createCompanyAndUser(UnitInfoDto regUnitInfo) {
        CompanyModel companyInfo = new CompanyModel();
        FeignClientResult<AgencyUserModel> userResult = null;
        try {
            FeignClientResult<List<RoleModel>> roleListResult = Privilege.roleClient.queryRoleList(null, null);
            List<RoleModel> allRoleList = roleListResult.getResult();
            List<RoleModel> userRoleList = new ArrayList<>();
            List<Long> roleIds = new ArrayList<>();
            // 1创建公司
            companyInfo.setAddress(regUnitInfo.getRegisterPcd());
            companyInfo.setAgencyCode("JXIOP");
            companyInfo.setParentId(Long.parseLong(regUnitInfo.getManagementUnitId()));
            companyInfo.setLevel("station");
            companyInfo.setCompanyName(regUnitInfo.getName());
//            companyInfo.setCompanyCode(regUnitInfo.getUnitTypeCode());
            companyInfo.setContact(regUnitInfo.getHeadName());
            companyInfo.setCompanyType(regUnitInfo.getUnitType());
            companyInfo.setLandlinePhone(regUnitInfo.getHeadPhone());
            FeignClientResult<CompanyModel> companyResult = Privilege.companyClient.create(companyInfo);
            if (companyResult == null || companyResult.getResult() == null) {
                throw new BadRequest("单位注册失败");
            }
            String adminUserName = regUnitInfo.getAdminUserName();
            String loginName = regUnitInfo.getAdminLoginName();
            String pwd = regUnitInfo.getAdminLoginPwd();
            String adminTel = regUnitInfo.getAdminPhone();
            // 2 创建平台用户
            companyInfo = companyResult.getResult();
            AgencyUserModel agencyUserModel = new AgencyUserModel();
            agencyUserModel.setUserName(loginName);
            agencyUserModel.setRealName(adminUserName);
            agencyUserModel.setLockStatus("UNLOCK");
            agencyUserModel.setPassword(pwd);
            agencyUserModel.setRePassword(pwd);
            agencyUserModel.setAgencyCode("JXIOP");
            agencyUserModel.setMobile(adminTel);
            List<String> split = Arrays.asList(StringUtils.split(appCodes, ','));
            Map<Long, List<Long>> roleSeqMap = new HashMap<>();
            Map<Long, List<RoleModel>> orgRoles = new HashMap<>();
            userRoleList = allRoleList.stream().filter(r -> r.getRoleName().equals(regUnitInfo.getUnitTypeCode()))
                    .collect(Collectors.toList());
            userRoleList.forEach(r -> {
                if (!roleIds.contains(r.getSequenceNbr())) {
                    roleIds.add(r.getSequenceNbr());
                }
            });
            roleSeqMap.put(companyInfo.getSequenceNbr(), roleIds);
            orgRoles.put(companyInfo.getSequenceNbr(), userRoleList);
            agencyUserModel.setAppCodes(split);
            agencyUserModel.setOrgRoles(orgRoles);
            agencyUserModel.setOrgRoleSeqs(roleSeqMap);
            userResult = Privilege.agencyUserClient.create(agencyUserModel);
            if (userResult == null || userResult.getResult() == null) {
                throw new BadRequest("单位注册失败");
            }
            String[] userIds = { userResult.getResult().getUserId() };
            regUnitInfo.setAdminUserId(userResult.getResult().getUserId());
            regUnitInfo.setAmosCompanySeq(companyInfo.getSequenceNbr());
        } catch (Exception e) {
            // 删除已经创建的 企业信息
            if (companyInfo != null && companyInfo.getSequenceNbr() != null) {
                Privilege.companyClient.deleteCompany(companyInfo.getSequenceNbr() + "");
            }
            if (userResult != null && userResult.getResult() != null
                    && StringUtils.isNotEmpty(userResult.getResult().getUserId())) {
                Privilege.agencyUserClient.multDeleteUser(userResult.getResult().getUserId());
            }
            log.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage());
        }
    }
}