package com.fjhx.supplier.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.attachment.service.StockAttachmentService;
import com.fjhx.entity.attachment.StockAttachment;
import com.fjhx.entity.attachment.enums.AttachmentTypeEnum;
import com.fjhx.entity.supplier.Supplier;
import com.fjhx.purchase.service.PurchaseContractService;
import com.fjhx.supplier.mapper.SupplierMapper;
import com.fjhx.supplier.service.SupplierService;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 供应商 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-07-12
 */
@Service
public class SupplierServiceImpl extends ServiceImpl<SupplierMapper, Supplier> implements SupplierService {


    @Autowired
    private StockAttachmentService stockAttachmentService;

    @Autowired
    private PurchaseContractService purchaseContractService;

    /**
     * 列表
     *
     * @param condition
     * @return
     * @throws ParseException
     */
    @Override
    public List<Supplier> getList(Map<String, Object> condition) {

        if (ObjectUtil.isNotEmpty(condition.get("TechnologyType")) &&
                StringUtil.equals(condition.get("TechnologyType").toString(), "99")) {
            condition.put("TechnologyType", null);
            return baseMapper.getSumList(condition);
        }

        return baseMapper.getList(condition);
    }

    /**
     * 列表条数
     *
     * @param condition
     * @return
     */
    @Override
    public Integer getListCount(Map<String, Object> condition) {
        if (ObjectUtil.isNotEmpty(condition.get("TechnologyType")) &&
                StringUtil.equals(condition.get("TechnologyType").toString(), "99")) {
            condition.put("TechnologyType", null);
            return baseMapper.getSumListCount(condition);
        }
        return baseMapper.getListCount(condition);
    }

    /**
     * 供应商采购列表
     *
     * @param condition
     * @return
     */
    @Override
    public List<Supplier> getPurList(Map<String, Object> condition) {
        if (ObjectUtil.isNotEmpty(condition.get("TechnologyType")) &&
                StringUtil.equals(condition.get("TechnologyType").toString(), "99")) {
            condition.put("TechnologyType", null);
            return baseMapper.getSumList(condition);
        }
        return baseMapper.getPurList(condition);
    }

    /**
     * 供应商采购列表条数
     *
     * @param condition
     * @return
     */
    @Override
    public Integer getPurListCount(Map<String, Object> condition) {
        if (ObjectUtil.isNotEmpty(condition.get("TechnologyType")) &&
                StringUtil.equals(condition.get("TechnologyType").toString(), "99")) {
            condition.put("TechnologyType", null);
            return baseMapper.getSumListCount(condition);
        }
        return baseMapper.getPurListCount(condition);
    }

    /**
     * 统计物料分类
     *
     * @return
     */
    @Override
    public List<Supplier> statisticsClassify(Map<String, Object> condition) {
        return baseMapper.getGroupByCategory(condition);
    }

    /**
     * 添加
     *
     * @param supplier
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String add(Supplier supplier) {
        supplier.setCreatedTime(new Date());
        //生成code
        if (ObjectUtil.isEmpty(supplier.getCode())) {

            LambdaQueryWrapper<Supplier> wrapper = Wrappers.<Supplier>lambdaQuery()
                    .orderByDesc(Supplier::getCode).last("limit 1");
            Supplier sCode = baseMapper.selectOne(wrapper);

            if (ObjectUtil.isEmpty(sCode)) {
                supplier.setCode("C001");
            } else {
                String code = sCode.getCode();
                if (code == null) {
                    supplier.setCode("c001");
                } else {
                    DecimalFormat decimalFormat = new DecimalFormat("0000");
                    int i = Integer.parseInt(code.substring(1)) + 1;
                    String k = decimalFormat.format(i);
                    supplier.setCode("C" + k);
                }
            }
        }
        save(supplier);
        List<StockAttachment> attr = supplier.getAttr();
        if (CollectionUtil.isNotEmpty(attr)) {
            for (StockAttachment s : attr) {
                s.setBusiId(supplier.getId());
                s.setBusiType(AttachmentTypeEnum.TYPE_TWO.getKey());
                s.setCreatedTime(new Date());
            }
            stockAttachmentService.saveBatch(attr);
        }

        return supplier.getId();
    }

    /**
     * 修改
     *
     * @param supplier
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean edit(Supplier supplier) {
        if (StringUtil.isEmpty(supplier.getId())) {
            throw new ServiceException("参数异常");
        }
        supplier.setUpdatedTime(new Date());
        updateById(supplier);
        List<StockAttachment> attr = supplier.getAttr();
        if (CollectionUtil.isNotEmpty(attr)) {
            //清空文件重新添加
            stockAttachmentService.remove(Wrappers.<StockAttachment>query().lambda().eq(StockAttachment::getBusiId, supplier.getId()));
            for (StockAttachment s : attr) {
                s.setBusiId(supplier.getId());
                s.setBusiType(AttachmentTypeEnum.TYPE_TWO.getKey());
                s.setCreatedTime(new Date());
            }
        }
        stockAttachmentService.saveBatch(attr);
        return true;
    }

    /**
     * 删除
     *
     * @param supplier
     */
    @Override
    public void delete(Supplier supplier) {
        removeById(supplier.getId());
        stockAttachmentService.remove(Wrappers.<StockAttachment>query().lambda().eq(StockAttachment::getBusiId, supplier.getId()));
    }

    /**
     * 详情
     *
     * @param id
     */
    @Override
    public Supplier detail(String id) {
        Supplier supplier = getById(id);
        if (ObjectUtil.isNotEmpty(supplier)) {
            supplier.setAttr(stockAttachmentService.getListByBusi(id));
        }
        return supplier;
    }

    /**
     * 供应商决策辅助详情
     *
     * @param id
     * @return
     */
    @Override
    public Supplier getSuById(String id) {
        return baseMapper.getSuById(id);
    }

    /**
     * 供应商采购分析详情
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Integer> getSuCount(String id) {
        if (StringUtil.isEmpty(id)) {
            throw new ServiceException("参数异常");
        }
        Map<String, Integer> map = new HashMap<>();
        map.put("BackCount", baseMapper.getBackCount(id));
        map.put("MaterialTypeCount", baseMapper.getMaterialTypeCount(id));
        return map;
    }

    /**
     * 供应商采购物料分析
     *
     * @param condition
     * @return
     */
    @Override
    public List<Supplier> spmAnalyse(Map<String, Object> condition) {
        List<Supplier> list = baseMapper.getSuPurMaterialAnalyse(condition);
        for (Supplier s : list) {
            String sumMoney = s.getSumMoney().replace(",", "");
            s.setPurProportion(new BigDecimal(sumMoney).divide(s.getTotalMoney(), 2, BigDecimal.ROUND_HALF_UP));
        }
        return list;
    }

    /**
     * 供应商采购物料分析
     *
     * @param condition
     * @return
     */
    @Override
    public Integer spmAnalyseCount(Map<String, Object> condition) {
        int count = baseMapper.getSuPurMaterialAnalyseCount(condition);
        return count;
    }

    /**
     * 月度退货记录分析
     *
     * @param id
     * @return
     */
    @Override
    public List<Supplier> getBackSumMoneyAndCount(String id, String date) {
        return baseMapper.getBackSumMoneyAndCount(id, date);
    }

    /**
     * 退货记录总数和总金额
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getAllSumMoneyAndCount(String id, String date) {
        return baseMapper.getAllSumMoneyAndCount(id, date);
    }

    /**
     * 月度采购分析
     *
     * @param id
     * @param date
     * @return
     */
    @Override
    public List<Supplier> getMonthSumPurMoney(String id, String date) {
        List<Supplier> list = baseMapper.getMonthSumPurMoney(id, date);
        //统计出所有条数得总额
//        BigDecimal totalMoney = list.stream()
//                .map(Supplier::getMoney)
//                .reduce(BigDecimal.ZERO,BigDecimal::add);
        BigDecimal totalMoney = purchaseContractService.getSumMoney(date);
        for (Supplier s : list) {
            if (s.getMoney().compareTo(BigDecimal.ZERO) == 0 || totalMoney.compareTo(BigDecimal.ZERO) == 0) {
                s.setPurProportion(BigDecimal.ZERO);
            } else {
                s.setPurProportion(s.getMoney().divide(totalMoney, 2, BigDecimal.ROUND_HALF_UP));
            }
        }
        return list;
    }

    /**
     * 下拉列表
     *
     * @param condition
     * @return
     */
    @Override
    public List<Supplier> selectList(Map<String, Object> condition) {
        return baseMapper.selectLists(condition);
    }

    @Override
    public List<Map<String, Object>> getAccountDate() {
        return listMaps(
                Wrappers.<Supplier>query()
                        .select("count(0) count", "AccountDate accountDate")
                        .lambda()
                        .eq(Supplier::getIsDelete, 0)
                        .orderByAsc(Supplier::getAccountDate)
                        .groupBy(Supplier::getAccountDate)
        );
    }

    @Override
    public List<Map<String, Object>> getSafetyWarnDayList() {
        List<Map<String, Object>> safetyWarnDayList = baseMapper.getSafetyWarnDayList();

        /*
        利用map与set去重供应商
        key 天数type
        value 供应商
         */
        Map<Integer, HashSet<String>> safetyWarnDayFactoryIdSet = safetyWarnDayList.stream().collect(Collectors.toMap(
                item -> {
                    int integer = Integer.parseInt(item.get("safetyWarnDay").toString());
                    if (integer < 6) {
                        return 1;
                    }
                    if (integer < 16) {
                        return 2;
                    }
                    if (integer < 31) {
                        return 3;
                    }
                    if (integer < 46) {
                        return 4;
                    }
                    return 5;
                },
                item -> {
                    HashSet<String> factoryIdSet = new HashSet<>();
                    factoryIdSet.add(item.get("factoryId").toString());
                    return factoryIdSet;
                },
                (v1, v2) -> {
                    v1.addAll(v2);
                    return v1;
                }
        ));

        safetyWarnDayFactoryIdSet.putIfAbsent(1, new HashSet<>());
        safetyWarnDayFactoryIdSet.putIfAbsent(2, new HashSet<>());
        safetyWarnDayFactoryIdSet.putIfAbsent(3, new HashSet<>());
        safetyWarnDayFactoryIdSet.putIfAbsent(4, new HashSet<>());
        safetyWarnDayFactoryIdSet.putIfAbsent(5, new HashSet<>());


        List<Map<String, Object>> result = new ArrayList<>();

        safetyWarnDayFactoryIdSet.forEach((k, v) -> {
            HashMap<String, Object> map = new HashMap<>();

            map.put("type", k);
            map.put("count", v.size());
            map.put("name", k == 1 ? "0~5天" : k == 2 ? "6~15天" : k == 3 ? "16~30天" : k == 4 ? "31~45天" : "45天以上");

            result.add(map);
        });

        // 排序
        return result.stream().sorted(Comparator.comparing(item -> Integer.valueOf(item.get("type").toString()))).collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> getSafetyWarnDayBySupplier(String supplierId) {
        return baseMapper.getSafetyWarnDayBySupplier(supplierId);
    }

    @Override
    public BigDecimal paymentGetBackAmount(String purchaseBillNo) {
        return baseMapper.paymentGetBackAmount(purchaseBillNo);
    }

}
