package com.ssj.service.sys.fx.service.impl;

import com.ssj.bean.sys.fx.domain.*;
import com.ssj.bean.weixin.sales.domain.LibOrderDetails;
import com.ssj.dao.sys.fx.dao.FxQueryDao;
import com.ssj.dao.sys.fx.dao.MaterielDao;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.util.ResponseEntity;
import com.ssj.service.sys.fx.service.DeviceActService;
import com.ssj.service.sys.fx.service.MaterielOffDetailService;
import com.ssj.service.sys.fx.service.MaterielOffService;
import com.ssj.service.sys.fx.service.MaterielService;
import com.ssj.service.weixin.sales.service.LibOrderDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static java.math.BigDecimal.ROUND_HALF_DOWN;

@Service
@Transactional
public class MaterielServiceImpl extends BaseServiceImpl<Materiel,String> implements MaterielService {

    @Autowired
    private MaterielDao dao;
    @Autowired
    private FxQueryDao queryDao;

    @Autowired
    private DeviceActService deviceActService;
    @Autowired
    private MaterielOffService materielOffService;
    @Autowired
    private MaterielOffDetailService materielOffDetailService;
    @Autowired
    private LibOrderDetailsService detailsService;

    @Override
    public PagingAndSortingRepository<Materiel, String> getDao() {
        return dao;
    }

    @Override
    public Page<Map<String, Object>> findByPageMap(Map<String, Object> params, Pageable initPage) {
        return queryDao.findByPageMap(params,initPage);
    }

    @Override
    public List<Materiel> findMaterielByCode(String materielCode) {
        return dao.findMaterielByCode(materielCode);
    }

    @Override
    public ResponseEntity saveMaterieDel(MaterielTemplate template, int delNum, String s, int lostNum,int isNew,String loginName) throws  Exception{
        ResponseEntity responseEntity = new ResponseEntity();
        List<TemplateInfo> infoList = template.getInfoList();
        boolean istrue = true;
        //  String tips = "";
        String offId = UUID.randomUUID().toString();
        //需计算每种物料所有数量的均价
        BigDecimal totolMoney = new BigDecimal(0);
        for(TemplateInfo info:infoList){
            Integer costNum = info.getMaterielCount() * delNum+info.getCostCount()*lostNum; //核销+损耗
            List<Materiel> materielList = this.findMaterielByCode(info.getMaterielCode());
            Integer leftNum = 0;
            for(Materiel materiel:materielList){
                //查看物料剩余是否满足
                leftNum +=materiel.getUserdCount();
            }
            if(leftNum>=costNum){
               // leftNum = costNum;
                for(Materiel materiel:materielList){
                    BigDecimal avgPrice = lostNum==0?materiel.getLeafPrice():materiel.getLeafPrice().multiply(new BigDecimal(costNum)).divide(new BigDecimal(delNum),4,ROUND_HALF_DOWN);
                    MaterielOffDetail offDetail = new MaterielOffDetail();
                    offDetail.setCostNum(materiel.getUserdCount()-costNum>=0?costNum:materiel.getUserdCount());
                    offDetail.setMaterieCode(materiel.getMaterieCode());
                    offDetail.setMaterielFlow(materiel.getMaterielFlow());
                    offDetail.setMaterielId(materiel.getId());
                    offDetail.setOffId(offId);
                    offDetail.setMaterielName(materiel.getMaterielName());
                    offDetail.setPrice(avgPrice);
                    offDetail.setType(1);
                    materielOffDetailService.save(offDetail);


                    int tempCount = materiel.getUserdCount()-costNum>0?materiel.getUserdCount()-costNum:0;
                    totolMoney =totolMoney.add(materiel.getLeafPrice().multiply(new BigDecimal(materiel.getUserdCount()-costNum>0?costNum:materiel.getUserdCount())));
                    costNum=costNum-materiel.getUserdCount()>0?costNum-materiel.getUserdCount():0;
                    materiel.setUserdCount(tempCount);
                    this.save(materiel);
                    if(costNum == 0){
                        MaterielOffDetail lossDetail = new MaterielOffDetail();
                        lossDetail.setCostNum(delNum);
                        lossDetail.setMaterieCode(materiel.getMaterieCode());
                        lossDetail.setMaterielFlow(materiel.getMaterielFlow());
                        lossDetail.setMaterielId(materiel.getId());
                        lossDetail.setOffId(offId);
                        lossDetail.setMaterielName(materiel.getMaterielName());
                        lossDetail.setPrice(avgPrice);
                        lossDetail.setLossNum(lostNum);
                        lossDetail.setType(2);
                        materielOffDetailService.save(lossDetail);
                        break;
                    }
                }
            }else{
                istrue = false;
                // tips = "物料"+info.getMaterielName()+"剩余数量不足以核销";
                responseEntity.failure("物料"+info.getMaterielName()+"剩余数量不足以核销");
                break;
            }
        }
        if(istrue){
            MaterielOff off = new MaterielOff();
            off.setId(offId);
            off.setOffNum(delNum);
            off.setLossNum(lostNum);
            off.setOffTime(new Date());
            off.setTemplateId(template.getId());
            off.setTemplateJson(template.getMaterielJson());
            off.setPrice(totolMoney.divide(new BigDecimal(delNum),4,ROUND_HALF_DOWN));
            materielOffService.save(off);

            //看是否需要生成新的物料
            if(isNew ==1){ //需要生成新的物料
                //查询是否有这个模板名称的物料，有取code，没有-生成新的code
                Materiel newMateriel = dao.findMaterielByName(template.getTemplateName());
                Materiel materiel = new Materiel();
                if(newMateriel!=null){
                    materiel.setMaterieCode(newMateriel.getMaterieCode());
                    materiel.setMaterielName(newMateriel.getMaterielName());
                }else{
                    materiel.setMaterieCode("M-"+UUID.randomUUID());
                    materiel.setMaterielName(template.getTemplateName());
                }
                materiel.setCreateTime(new Date());
                materiel.setCreateUser(loginName);
                materiel.setState(1);
                materiel.setLeafPrice(totolMoney.divide(new BigDecimal(delNum),4,ROUND_HALF_DOWN));
                materiel.setUserdCount(delNum);
                materiel.setInCount(delNum);
                this.save(materiel);
            }
            responseEntity.success("核销成功！");
        }
        return  responseEntity;
    }

    @Override
    public Page<Map<String, Object>> findMaterielLeafByPageMap(Map<String, Object> params, Pageable initPage) {
        return queryDao.findMaterielLeafByPageMap(params,initPage);
    }

    @Override
    public Page<Map<String, Object>> findMaterielOffLeafByPageMap(Map<String, Object> params, Pageable initPage) {
        return queryDao.findMaterielOffLeafByPageMap(params,initPage);
    }

    @Override
    public Page<Map<String, Object>> vipDerverList(Map<String, Object> params, Pageable initPage) {
        return queryDao.vipDerverList(params,initPage);
    }

    @Override
    public Page<Map<String, Object>> MonthInAndOutList(Map<String, Object> params, Pageable initPage) {
        return queryDao.MonthInAndOutList(params,initPage);
    }

    @Override
    public List<Map<String, Object>> monthInAndOutDetailList(Map<String, Object> params) {
        return queryDao.monthInAndOutDetailList(params);
    }

    @Override
    public Page<Map<String, Object>> findForPageList(Map<String, Object> params, Pageable initPage) {
        return queryDao.findForPageList(params,initPage);
    }

    @Override
    public void orderDetailClose(String[] ids, int i) {
        for (String str :ids){
            LibOrderDetails details = detailsService.getById(str);
            details.setIsClose(i);
            detailsService.save(details);
        }
    }
}
