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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.module.hygf.api.dto.DocumentBomDto;
import com.yeejoin.amos.boot.module.hygf.api.entity.DesignInformation;
import com.yeejoin.amos.boot.module.hygf.api.entity.DocumentBom;
import com.yeejoin.amos.boot.module.hygf.api.mapper.DocumentBomMapper;
import com.yeejoin.amos.boot.module.hygf.api.service.IDocumentBomService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 发货单bom服务实现类
 *
 * @author system_generator
 * @date 2023-08-17
 */
@Service
public class DocumentBomServiceImpl extends BaseService<DocumentBomDto,DocumentBom,DocumentBomMapper> implements IDocumentBomService {

    /**
     * 折扣率
     */
    private final static double DISCOUNT_RATE = 1;

    @Autowired
    DesignInformationServiceImpl designInformationService;

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

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

    /**
     * 分页查询 By preparationMoneyId
     */
    public Page<DocumentBomDto> queryForDocumentBomPage(Page<DocumentBomDto> page, Long preparationMoneyId) {
        return this.queryForPage(page, null, false, preparationMoneyId);
    }

    /**
     * 查询 By preparationMoneyId
     */
    public List<DocumentBomDto> listByPreparationMoneyId(Long preparationMoneyId) {
        return this.queryForList(null, false, preparationMoneyId);
    }

    /**
     * 根据发货电站组装BOM清单数据
     *
     *
     * @param powerHouseholdIds powerHouseholdIds
     * @return {@link  List< DocumentBom>}
     * @author Provence
     * @throws
     */
    public List<DocumentBom> assembleDocumentBom(List<Long> powerHouseholdIds) {
        // hygf_design_information
        List<DesignInformation> designInformations = designInformationService.query().in("peasant_household_id", powerHouseholdIds).list();
        // [{"wlbm":"1","Symbol_key":"B1F7FEE3-9377-4A42-81FB-DEB8775EF67C","wlmc":"1","dcpgg":"1"}]
        // 组件-assembly， 逆变器-inverter，电表箱-electricity_meter 根据物料编码 分组
        List<DocumentBom> documentBoms = new ArrayList<>();
        for (DesignInformation designInformation : designInformations) {
            documentBoms.addAll(convertBom(designInformation.getAssembly(), "assembly"));
            documentBoms.addAll(convertBom(designInformation.getInverter(), "inverter"));
            documentBoms.addAll(convertBom(designInformation.getElectricityMeter(), "electricityMeter"));
        }
        // 根据物料编码 分组
        return documentBoms.stream().collect(Collectors.groupingBy(DocumentBom::getMaterialNum)).values().stream()
                .flatMap(list -> Stream.of(list.stream().reduce((o1, o2) -> {
                    o1.setDemandNumber(o1.getDemandNumber() + o2.getDemandNumber());
                    o1.setDiscountTotal(caculateDiscountTotal(o1).add(caculateDiscountTotal(o2)).doubleValue());
                    o1.setDiscountUnitPrice(caculateDiscountUnitPrice(o1).add(caculateDiscountUnitPrice(o2)).doubleValue());
                    return o1;
                }).orElse(null)).filter(Objects::nonNull)).collect(Collectors.toList());
    }

    private BigDecimal caculateTotal(DocumentBom o1) {
        return new BigDecimal(o1.getDemandNumber()).multiply(new BigDecimal(o1.getUnitPrice()));
    }

    private BigDecimal caculateDiscountTotal(DocumentBom o1) {
        // 折扣总额 = 总价 - 折扣总价
        return caculateTotal(o1).subtract(new BigDecimal(o1.getDemandNumber()).multiply(caculateDiscountUnitPrice(o1)));
    }

    private BigDecimal caculateDiscountUnitPrice(DocumentBom o1) {
        // 折扣后单价 = 单价 * 折扣率
        return new BigDecimal(o1.getUnitPrice()).multiply(new BigDecimal(DISCOUNT_RATE));
    }

    /**
     * 设计信息内的组件-assembly， 逆变器-inverter，电表箱-electricity_meter json转成bom清单对象
     *
     *
     * @param objects objects
     * @param materialType materialType
     * @return {@link  List< DocumentBom>}
     * @author Provence
     * @throws
     */
    private List<DocumentBom> convertBom(List<Object> objects, String materialType) {
        if (CollectionUtils.isEmpty(objects)) {
            return Collections.EMPTY_LIST;
        }
        List<DocumentBom> documentBoms = new ArrayList<>();
        JSONArray jsonArray =  JSONArray.parseArray(objects.toString());
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject json = jsonArray.getJSONObject(i);
            documentBoms.add(parseDocumentBom(json));
        }
        return documentBoms;
    }

    private DocumentBom parseDocumentBom(JSONObject json) {
        DocumentBom documentBom = new DocumentBom();
        String materialNum = json.getString("wlbm");//物料编码
        String materialName = json.getString("wlmc");//物料名称
        Integer demandNumber = json.getInteger("pzsl");//配置数量
        Double price = json.getDouble("price");//价格
        if (StringUtils.isAnyBlank(materialNum, materialName)) {
            throw new BadRequest("物料编码和物料名称不能为空");
        }
        if (null == demandNumber || null == price) {
            throw new BadRequest("价格和配置数量不能为空");
        }
        Double power = Double.valueOf(Optional.ofNullable(json.getString("gl")).orElse("0").replace("W", ""));// 去掉功率的单位
        documentBom.setMaterialNum(materialNum);//物料编码
        documentBom.setMaterialName(materialName);//物料名称
        documentBom.setUnitPrice(price);
        documentBom.setDemandNumber(demandNumber);
        documentBom.setPower(power);
         /*
            类型和分组目前没有该字段
            documentBom.setMaterialType(materialType);
            documentBom.setMaterialGroup();*/
        return documentBom;
    }
}