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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.HouseholdPv;
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.mapper.HouseholdPvMapper;
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 java.util.ArrayList;
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;

    @Autowired
    HouseholdPvMapper householdPvMapper;

    static final String STATION_LEVEL = "level";
    /**
     * 分页查询
     */
    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 = householdPvDistrictMapper.selectById(id);
        householdPvDistrict.setSequenceNbr(id);
        householdPvDistrict.setName(name);
        householdPvDistrictMapper.updateById(householdPvDistrict);
        return householdPvDistrict;
    }

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

    @Override
    public String removeCheck(Long id) {
        Integer treeNodes = householdPvDistrictMapper.countTreeNodesById(id);
        LambdaQueryWrapper<HouseholdPv> lambda = new QueryWrapper<HouseholdPv>().lambda();
        lambda.eq(HouseholdPv::getPlatformCompanyId, id);
        Integer integer = householdPvMapper.selectCount(lambda);
        if (treeNodes > 0) {
            return  "该节点存在子节点";
        } else if (integer > 0) {
            return "该节点已绑定户用光伏信息";
        }
        return "ok";
    }

    @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.getListByParentId(reginParams.getCompany().getOrgCode(), null);
        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(Long parentId) {
        String orgCode = getOrgCode(parentId);
        if (ObjectUtils.isEmpty(orgCode)){
            return new ArrayList<>();
        }
        List<CompanyTreeDto> list = householdPvDistrictMapper.getListByParentId(orgCode, parentId);
        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> stationTree() {
        ArrayList<CompanyTreeDto> list = new ArrayList<>();
        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);
        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());
    }

    private String getOrgCode(Long platformCompanyId) {
        String bizOrgCode = null;
        HouseholdPvDistrict parentDetail = householdPvDistrictMapper.selectById(platformCompanyId);
        if (ObjectUtils.isEmpty(parentDetail)) {
            FeignClientResult<CompanyModel> companyModelFeignClientResult = Privilege.companyClient.seleteOne(platformCompanyId);
            CompanyModel result = companyModelFeignClientResult.getResult();
            if (!ObjectUtils.isEmpty(result) && !ObjectUtils.isEmpty(result.getLevel()) && "station".equals(result.getLevel())) {
                bizOrgCode = result.getOrgCode();
            }
        } else {
            bizOrgCode = parentDetail.getBizOrgCode();
        }
        return bizOrgCode;
    }

    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) && !ObjectUtils.isEmpty(detail.get(STATION_LEVEL)) && !detail.get(STATION_LEVEL).equals("debug_division")){
                if (!ObjectUtils.isEmpty(detail)) {
                    dto.setLevel(detail.getOrDefault(STATION_LEVEL, "").toString());
                    if (!ObjectUtils.isEmpty(detail.get(STATION_LEVEL)) && "station".equals(detail.get(STATION_LEVEL))){
                        dto.setDisabled(false);
                    }else {
                        dto.setDisabled(true);
                    }
                }
                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());
    }
}