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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jxiop.api.dto.CompanyTreeDto;
import com.yeejoin.amos.boot.module.jxiop.api.dto.HouseholdPvDistrictDto;
import com.yeejoin.amos.boot.module.jxiop.api.entity.HouseholdPvDistrict;
import com.yeejoin.amos.boot.module.jxiop.api.mapper.HouseholdPvDistrictMapper;
import com.yeejoin.amos.boot.module.jxiop.api.service.IHouseholdPvDistrictService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.UserOrgTreeModel;
import org.apache.commons.lang3.ObjectUtils;
import org.joda.time.LocalDateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2023-03-17
 */
@Service
public class HouseholdPvDistrictServiceImpl extends BaseService<HouseholdPvDistrictDto, HouseholdPvDistrict, HouseholdPvDistrictMapper> implements IHouseholdPvDistrictService {

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    HouseholdPvDistrictMapper householdPvDistrictMapper;

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

    /**
     * 列表查询 示例
     */
    public List<HouseholdPvDistrictDto> queryForHouseholdPvDistrictList() {

        Privilege.companyClient.queryOrgTree(null);
        return this.queryForList("", false);
    }

    @Override
    public HouseholdPvDistrict treeAdd(Long parentId, String name) {
        String random = "" + Math.random();
        String substring = random.substring(random.length() - 4);
        HouseholdPvDistrict householdPvDistrict = new HouseholdPvDistrict();
        householdPvDistrict.setName(name);
        householdPvDistrict.setParentId(parentId);
        householdPvDistrict.setCreateTime(LocalDateTime.now().toDate());
        HouseholdPvDistrict parentDetail = householdPvDistrictMapper.selectById(parentId);
        if (ObjectUtils.isEmpty(parentDetail)) {
            FeignClientResult<CompanyModel> companyModelFeignClientResult = Privilege.companyClient.seleteOne(parentId);
            CompanyModel result = companyModelFeignClientResult.getResult();
            if (!ObjectUtils.isEmpty(result)) {
                householdPvDistrict.setBizOrgCode(result.getOrgCode() + "*" + substring);
            }
        } else {
            householdPvDistrict.setBizOrgCode(parentDetail.getBizOrgCode() + "*" + substring);
        }
        householdPvDistrictMapper.insert(householdPvDistrict);
        return householdPvDistrict;
    }

    @Override
    public HouseholdPvDistrict treeUpdate(Long id, String name) {
        HouseholdPvDistrict householdPvDistrict = new HouseholdPvDistrict();
        householdPvDistrict.setSequenceNbr(id);
        householdPvDistrict.setName(name);
        this.updateById(householdPvDistrict);
        return householdPvDistrict;
    }

    @Override
    public void treeNodesRemove(Long id) {
        Integer treeNodes = householdPvDistrictMapper.countTreeNodesById(id);
        Integer integer = householdPvDistrictMapper.countHouseholdById(id);
        if (treeNodes > 0) {
            throw new BadRequest("该节点存在子节点");
        } else if (integer > 0) {
            throw new BadRequest("该节点已绑定户用光伏信息");
        }
        this.removeById(id);
    }

    @Override
    public List<CompanyTreeDto> getTree() {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        Long sequenceNbr = reginParams.getCompany().getSequenceNbr();
        FeignClientResult<Collection<UserOrgTreeModel>> collectionFeignClientResult = Privilege.companyClient.queryOrgTree(sequenceNbr);
        List<CompanyTreeDto> list = householdPvDistrictMapper.getList();
        if (collectionFeignClientResult != null) {
            Collection<UserOrgTreeModel> result = collectionFeignClientResult.getResult();
            change(result, list);
        }
        return list.stream().filter(a -> list.stream().noneMatch(c -> c.getId().equals(a.getParentId()))).peek(b -> b.setChildren(getCompanyBuildingChildrenTree(b.getId(), list))).collect(Collectors.toList());
    }

    @Override
    public List<CompanyTreeDto> getBusinessTree() {
        List<CompanyTreeDto> list = householdPvDistrictMapper.getList();
        return list.stream().filter(a -> list.stream().noneMatch(c -> c.getId().equals(a.getParentId()))).peek(b -> b.setChildren(getCompanyBuildingChildrenTree(b.getId(), list))).collect(Collectors.toList());
    }

    private void change(Collection<UserOrgTreeModel> data, List<CompanyTreeDto> result) {
        data.forEach(item -> {
            CompanyTreeDto dto = new CompanyTreeDto();
            BeanUtils.copyProperties(item, dto, "children");
            Map<String, Object> detail = (Map<String, Object>) item.getObject();
            if (!ObjectUtils.isEmpty(detail)) {
                dto.setLevel(detail.getOrDefault("level", "").toString());
            }
            result.add(dto);
            if (!ObjectUtils.isEmpty(item.getChildren())) {
                change(item.getChildren(), result);
            }
        });
    }


    private List<CompanyTreeDto> getCompanyBuildingChildrenTree(String parentId, List<CompanyTreeDto> all) {
        return all.stream().filter(a -> parentId.equals(a.getParentId())).peek(a -> {
            a.setChildren(getCompanyBuildingChildrenTree(a.getId(), all));
        }).collect(Collectors.toList());
    }
}