package com.patzn.lims.consume.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.google.common.collect.Lists;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.cloud.commons.toolkit.BigDecimalUtils;
import com.patzn.lims.consume.entity.LmsChemical;
import com.patzn.lims.consume.entity.LmsChemicalPurchaseOrder;
import com.patzn.lims.consume.entity.LmsChemicalRelPurchase;
import com.patzn.lims.consume.entity.LmsChemicalUserecord;
import com.patzn.lims.consume.enums.PurchaseOrderEnum;
import com.patzn.lims.consume.enums.PurchaseRelStateEnum;
import com.patzn.lims.consume.enums.RelPurchaseEnum;
import com.patzn.lims.consume.mapper.LmsChemicalRelPurchaseMapper;
import com.patzn.lims.consume.service.ILmsChemicalPurchaseOrderService;
import com.patzn.lims.consume.service.ILmsChemicalRelPurchaseService;
import com.patzn.lims.consume.service.ILmsChemicalService;
import com.patzn.lims.consume.service.ILmsChemicalUserecordService;
import com.patzn.lims.consume.vo.LmsChemicalRelPurchaseVO;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.res.entity.LmsSupplier;
import com.patzn.lims.res.service.ILmsSupplierService;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 试验耗材采购关联表 服务实现类
 * </p>
 *
 * @author wwd
 * @since 2020-03-21
 */
@Service
public class LmsChemicalRelPurchaseServiceImpl extends BaseServiceImpl<LmsChemicalRelPurchaseMapper, LmsChemicalRelPurchase> implements ILmsChemicalRelPurchaseService {

    @Autowired
    private ILmsChemicalService lmsChemicalService;
    @Autowired
    private ILmsSupplierService lmsSupplierService;
    @Autowired
    private ILmsChemicalUserecordService lmsChemicalUserecordService;
    @Autowired
    private ILmsChemicalPurchaseOrderService lmsChemicalPurchaseOrderService;


    @Override
    public Page<LmsChemicalRelPurchaseVO> page(Page<LmsChemicalRelPurchaseVO> page, LmsChemicalRelPurchaseVO lmsChemicalRelPurchase) {
        // 指定出库单 ID , 用户 ID 不作为查询条件
        if (null != lmsChemicalRelPurchase.getOrderId()) {
            lmsChemicalRelPurchase.setUid(null);
        }
        lmsChemicalRelPurchase.setCompanyId(LoginHelper.getAccount().getCompanyId());
        List<LmsChemicalRelPurchaseVO> result = baseMapper.getPageByOrderId(page, lmsChemicalRelPurchase);
        if (CollectionUtils.isNotEmpty(result)) {
            String remark = null;
            for (LmsChemicalRelPurchaseVO vo : result) {
                //处理stateDisplay
                if (0 == vo.getState()) {
                    vo.setStateDisplay("正常");
                } else if (1 == vo.getState()) {
                    vo.setStateDisplay("驳回");
                } else if (2 == vo.getState()) {
                    vo.setStateDisplay("调整");
                } else if (3 == vo.getState()) {
                    vo.setStateDisplay("结束");
                } else if (4 == vo.getState()) {
                    vo.setStateDisplay("采购完成");
                } else if (5 == vo.getState()) {
                    vo.setStateDisplay("已入库");
                }
                List<LmsChemicalUserecord> userList = lmsChemicalUserecordService.list(Wrappers.<LmsChemicalUserecord>query().eq("order_id", vo.getOrderId())
                        .eq("chemical_id", vo.getChemicalId()));
                StringBuilder sb = new StringBuilder();
                if (CollectionUtils.isNotEmpty(userList)) {
                    List<String> reasonList = new ArrayList<>();
                    for (LmsChemicalUserecord userecord : userList) {
                        if (StringUtils.isNotBlank(userecord.getUnqualifiedReason())) {
                            if (!reasonList.contains(userecord.getUnqualifiedReason())) {
                                reasonList.add(userecord.getUnqualifiedReason());
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(reasonList)) {
                        for (String reason : reasonList) {
                            BigDecimal count = new BigDecimal("0");
                            for (LmsChemicalUserecord userecord : userList) {
                                if (Objects.equals(reason, userecord.getUnqualifiedReason())) {
                                    count = count.add(null != userecord.getUnqualifiedQuantity() ? userecord.getUnqualifiedQuantity() : BigDecimal.ZERO);
                                }
                            }
                            sb.append(count).append(StringUtils.isNotBlank(vo.getUnit()) ? vo.getUnit() : "").append(reason).append(";");
                        }
                    }
                }
                if (sb.length() > 0) {
                    vo.setRemark(sb.toString().substring(0, sb.length() - 1));
                }
            }
        }
        return page.setRecords(result);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveByChemicalIds(Long[] chemicalIds, LmsChemicalRelPurchase chemicalRelPurchase) {
        if (ArrayUtils.isEmpty(chemicalIds)) {
            return false;
        }
        BigDecimal quantity = chemicalRelPurchase.getQuantity();

        List<LmsChemical> lmsChemicalList = lmsChemicalService.list(Wrappers.<LmsChemical>query().in("id",chemicalIds));

        for (LmsChemical  lmsChemical: lmsChemicalList) {
            if (null != lmsChemical) {
               Long chemicalId = lmsChemical.getId();

                LmsChemicalRelPurchase lcrp = getOne(Wrappers.<LmsChemicalRelPurchase>
                        query().eq("status",0).eq("chemical_id",chemicalId).
                        isNull("supplier_id").eq("uid", LoginHelper.getAccount().getUserId()).last("LIMIT 1"));
                if (null == lcrp) {
                    // 初次新增一条记录
                    lcrp = new LmsChemicalRelPurchase();
                    lcrp.setChemicalId(chemicalId);
                    lcrp.setChemicalNum(lmsChemical.getNum());
                    lcrp.setChemicalName(lmsChemical.getName());
                    lcrp.setQuantity(quantity == null ? BigDecimal.ONE : quantity);
                    lcrp.setSupplierId(chemicalRelPurchase.getSupplierId());
                    lcrp.setSupplier(chemicalRelPurchase.getSupplier());
                    lcrp.setManufacturer(StringUtils.isEmpty(chemicalRelPurchase.getManufacturer()) ? lmsChemical.getManufacturer() : chemicalRelPurchase.getManufacturer());
                    if (null == chemicalRelPurchase.getPrice()) {
                        // 未主动输入取耗材上的价格
                        lcrp.setPrice(lmsChemical.getUnitPrice());
                    } else {
                        lcrp.setPrice(chemicalRelPurchase.getPrice());
                    }
                    if (null == chemicalRelPurchase.getSpec()) {
                        // 未主动输入取耗材上的规格
                        lcrp.setSpec(lmsChemical.getSpec());
                    } else {
                        lcrp.setSpec(chemicalRelPurchase.getSpec());
                    }
                    lcrp.setRemark(chemicalRelPurchase.getRemark());
                    //单位
                    lcrp.setUnit(lmsChemical.getUnit());
                    //密度
                    lcrp.setQuality(lmsChemical.getQuality());
                    //验证是否存在供应商
                    validSuperIsExsit(lcrp);
                    save(lcrp);
                } else {
                    // 再次添加总数加一
                    lcrp.setChemicalNum(lmsChemical.getNum());
                    lcrp.setChemicalName(lmsChemical.getName());
                    if (null != chemicalRelPurchase.getSupplierId()) {
                        lcrp.setSupplierId(chemicalRelPurchase.getSupplierId());
                        lcrp.setSupplier(chemicalRelPurchase.getSupplier());
                    }
                    if (null != chemicalRelPurchase.getPrice()) {
                        lcrp.setPrice(chemicalRelPurchase.getPrice());
                    }
                    if (null != chemicalRelPurchase.getSpec()) {
                        lcrp.setSpec(chemicalRelPurchase.getSpec());
                    }
                    if (null != chemicalRelPurchase.getManufacturer()) {
                        lcrp.setManufacturer(chemicalRelPurchase.getManufacturer());
                    }
                    lcrp.setRemark(chemicalRelPurchase.getRemark());
                    lcrp.setQuantity(quantity == null ? BigDecimalUtils.add(lcrp.getQuantity(), BigDecimal.ONE) : quantity);
                    updateById(lcrp);
                }
            }
        }
        return true;
    }

    @Override
    public Page<LmsChemicalRelPurchaseVO> pageTemp(Page page, LmsChemicalRelPurchaseVO lmsChemicalRelPurchase) {
        // 临时采购列表
        lmsChemicalRelPurchase.setStatus(0);
        // 指定出库单 ID , 用户 ID 不作为查询条件
        if (null != lmsChemicalRelPurchase.getOrderId()) {
            lmsChemicalRelPurchase.setUid(null);
        }
        lmsChemicalRelPurchase.setCompanyId(LoginHelper.getAccount().getCompanyId());
        return page.setRecords(baseMapper.getPageByOrderId(page, lmsChemicalRelPurchase));
    }

    @Override
    public Integer updateOrderStatus(Long orderId, Long uid) {
        LmsChemicalRelPurchase lcrp = new LmsChemicalRelPurchase();
        lcrp.setOrderId(orderId);
        // 改为采购状态
        lcrp.setStatus(RelPurchaseEnum.WAIT_ORDER_APPROVAL.getValue());
        return baseMapper.update(lcrp, Wrappers.<LmsChemicalRelPurchase>query().eq("uid", uid).eq("status", 0));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean finishPurchase(Long[] ids) {
        PtAssert.fail(ArrayUtils.isEmpty(ids), "id不能为空");
        List<LmsChemicalRelPurchase> dbTempList = super.list(Wrappers.<LmsChemicalRelPurchase>query().in("id", ids));
        PtAssert.fail(CollectionUtils.isEmpty(dbTempList), "查询中间表失败");
        List<Long> orderIds = dbTempList.stream().map(o -> o.getOrderId()).collect(Collectors.toList());
        List<LmsChemicalPurchaseOrder> orderList = lmsChemicalPurchaseOrderService.list(Wrappers.<LmsChemicalPurchaseOrder>query().in("id", orderIds));
        PtAssert.fail(CollectionUtils.isEmpty(orderList), "查询采购单失败");
        if (PurchaseOrderEnum.WAIT_APPROVAL.getValue()==(orderList.get(0).getStatus())
                || PurchaseOrderEnum.IN_APPROVAL.getValue()==(orderList.get(0).getStatus())
                || PurchaseOrderEnum.APPROVAL_REJECT.getValue()==(orderList.get(0).getStatus())
                || PurchaseOrderEnum.APPROVAL_FAILED.getValue()==(orderList.get(0).getStatus())) {
            PtAssert.fail("请先申请采购");
        }
        List<LmsChemicalRelPurchase> dbRelList = super.list(Wrappers.<LmsChemicalRelPurchase>query().in("id", ids).in("state", Lists.newArrayList(0,2)));
        PtAssert.fail(CollectionUtils.isEmpty(dbRelList), "所选耗材都已采购完成或被拒绝");
        PtAssert.fail(dbRelList.size() != ids.length, "所选耗材部分已采购完成，请勿重复点击");
        if (CollectionUtils.isNotEmpty(dbRelList)) {
            dbRelList.stream().forEach(o -> o.setState(PurchaseRelStateEnum.END_PURCHASE.getValue()));
            super.updateBatchById(dbRelList);
        }
        LmsChemicalRelPurchase tempRel = getOne(Wrappers.<LmsChemicalRelPurchase>query().in("id", ids).last("limit 1"));
        PtAssert.fail(null == tempRel, "查询采购单下耗材信息失败");
        List<LmsChemicalRelPurchase> checkList = super.list(Wrappers.<LmsChemicalRelPurchase>query().eq("order_id", tempRel.getOrderId()).
                ne("state", 1));
        List<Integer> checkStateList = checkList.stream().map(o -> o.getState()).collect(Collectors.toList());
        PurchaseOrderEnum orderEnum = null;
        //验证该采购单下是否还有“正常”和“调整”状态的耗材，如果有则采购单为采购中
        if (checkStateList.contains(PurchaseRelStateEnum.NORMAL.getValue())
                || checkStateList.contains(PurchaseRelStateEnum.ADJUST.getValue())) {
            orderEnum = PurchaseOrderEnum.PURCHASEING;
        }
        //如果所有关联耗材都是“采购完成”状态，并且无“已入库”和“结束”状态耗材，则将采购单状态设置为“待入库”
        boolean endBl = true;
        for (Integer state : checkStateList) {
            if (state != PurchaseRelStateEnum.END_PURCHASE.getValue()) {
                endBl = false;
            }
        }
        if (endBl) {
            orderEnum = PurchaseOrderEnum.STOCK_WAIT;
        }
        //如果所有关联耗材无“正常”和“调整”状态，并且有部分为“已入库”和“结束”状态耗材，则将采购单状态设置为“部分入库”
        boolean normalAdjustBl = true;
        boolean stockFinishBl = false;
        for (Integer state : checkStateList) {
            if (state == PurchaseRelStateEnum.NORMAL.getValue() || state == PurchaseRelStateEnum.ADJUST.getValue()) {
                normalAdjustBl = false;
            }
            if (state == PurchaseRelStateEnum.STOCK.getValue() || state == PurchaseRelStateEnum.FINISH.getValue()) {
                stockFinishBl = true;
            }
        }
        if (normalAdjustBl && stockFinishBl) {
            orderEnum = PurchaseOrderEnum.STOCK_PART;
        }
        LmsChemicalPurchaseOrder order = new LmsChemicalPurchaseOrder();
        order.setId(tempRel.getOrderId());
        order.setStatus(orderEnum.getValue());
        return lmsChemicalPurchaseOrderService.updateById(order);
    }


    @Override
    public Page<LmsChemicalRelPurchaseVO> getPageByOrderId(Page page, LmsChemicalRelPurchaseVO vo) {
        if (null != vo.getOrderId()) {
            vo.setUid(null);
        }
        List<Integer> stateList = new ArrayList<>();
        stateList.add(PurchaseRelStateEnum.NORMAL.getValue());
        stateList.add(PurchaseRelStateEnum.ADJUST.getValue());
        stateList.add(PurchaseRelStateEnum.END_PURCHASE.getValue());
        stateList.add(PurchaseRelStateEnum.STOCK.getValue());
        stateList.add(PurchaseRelStateEnum.FINISH.getValue());
        vo.setStatusList(stateList);
        vo.setCompanyId(LoginHelper.getAccount().getCompanyId());
        List<LmsChemicalRelPurchaseVO> result = baseMapper.getPageByOrderId(page, vo);
        if (CollectionUtils.isNotEmpty(result)) {
            for (LmsChemicalRelPurchaseVO voo : result) {
                //处理stateDisplay
                if (0 == voo.getState()) {
                    voo.setStateDisplay("正常");
                } else if (1 == voo.getState()) {
                    voo.setStateDisplay("驳回");
                } else if (2 == voo.getState()) {
                    voo.setStateDisplay("调整");
                } else if (3 == voo.getState()) {
                    voo.setStateDisplay("结束");
                } else if (4 == voo.getState()) {
                    voo.setStateDisplay("采购完成");
                } else if (5 == voo.getState()) {
                    voo.setStateDisplay("已入库");
                }
            }
        }
        return page.setRecords(result);
    }

    private void validSuperIsExsit(LmsChemicalRelPurchase lcrp) {
        if (StringUtils.isNoneEmpty(lcrp.getSupplier())
                && lmsSupplierService.listByName(lcrp.getSupplier()).size() == 0) {
            LmsSupplier supplier = new LmsSupplier();
            supplier.setName(lcrp.getSupplier());
            lmsSupplierService.save(supplier);
            lcrp.setSupplierId(supplier.getId());
        }
    }
}
