package cn.ysk.cashier.cons.service.impl;

import cn.ysk.cashier.cons.domain.TbConCheck;
import cn.ysk.cashier.cons.domain.TbConsInfo;
import cn.ysk.cashier.cons.domain.TbConsInfoFlow;
import cn.ysk.cashier.cons.repository.TbConsInfoFlowRepository;
import cn.ysk.cashier.cons.repository.TbConsInfoRepository;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.utils.FileUtil;
import cn.ysk.cashier.utils.PageUtil;
import cn.ysk.cashier.utils.QueryHelp;
import cn.ysk.cashier.utils.ValidationUtil;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.cons.repository.TbConCheckRepository;
import cn.ysk.cashier.cons.service.TbConCheckService;
import cn.ysk.cashier.cons.service.dto.TbConCheckDto;
import cn.ysk.cashier.cons.service.dto.TbConCheckQueryCriteria;
import cn.ysk.cashier.cons.service.mapstruct.TbConCheckMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author admin
* @date 2024-07-06
**/
@Service
@RequiredArgsConstructor
public class TbConCheckServiceImpl implements TbConCheckService {

    private final TbConCheckRepository tbConCheckRepository;
    private final TbConCheckMapper tbConCheckMapper;

    private final TbConsInfoRepository tbConsInfoRepository;

    public final TbConsInfoFlowRepository tbConsInfoFlowRepository;

    @Override
    public Map<String,Object> queryAll(TbConCheckQueryCriteria criteria, Pageable pageable){
        Page<TbConCheck> page = tbConCheckRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(tbConCheckMapper::toDto));
    }

    @Override
    public List<TbConCheckDto> queryAll(TbConCheckQueryCriteria criteria){
        return tbConCheckMapper.toDto(tbConCheckRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public TbConCheckDto findById(Integer id) {
        TbConCheck tbConCheck = tbConCheckRepository.findById(id).orElseGet(TbConCheck::new);
        ValidationUtil.isNull(tbConCheck.getId(),"TbConCheck","id",id);
        return tbConCheckMapper.toDto(tbConCheck);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TbConCheckDto create(TbConCheck resources) throws Exception {

        if(BigDecimal.ZERO.compareTo(resources.getStockNumber())>0||resources.getStockNumber().compareTo(new BigDecimal("99999999999999"))>0){
            throw new BadRequestException("请输入正确的数值");
        }


        TbConsInfo consInfo= tbConsInfoRepository.getById(resources.getConInfoId());
        if(Objects.isNull(consInfo)){
            throw new Exception("耗材信息不存在");
        }
        TbConsInfoFlow flow=new TbConsInfoFlow();

        if(consInfo.getStockNumber().compareTo(resources.getStockNumber())>=0){
            flow.setBizCode("checkStockOut");
            flow.setBizName("盘点出库");
            flow.setBizType("-");
        }else {
            flow.setBizCode("checkStockIn");
            flow.setBizName("盘点入库");
            flow.setBizType("+");
        }


        consInfo.setStockConsume(BigDecimal.ZERO);
        consInfo.setStockNumber(resources.getStockNumber());
        consInfo.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        tbConsInfoRepository.save(consInfo);





        flow.setConsId(consInfo.getId());
        flow.setShopId(consInfo.getShopId());
        flow.setConName(consInfo.getConName());
        flow.setAmount(consInfo.getStockNumber());
        flow.setBalance(consInfo.getStockNumber());

        flow.setCreateTime(new Timestamp(System.currentTimeMillis()));
        tbConsInfoFlowRepository.save(flow);



        TbConCheck conCheck=new TbConCheck();

        conCheck.setConInfoId(consInfo.getId());
        conCheck.setConName(consInfo.getConName());
        conCheck.setPrice(consInfo.getPrice());
        conCheck.setAcStockNumber(resources.getStockNumber());
        conCheck.setStockNumber(resources.getStockNumber());
        conCheck.setLpNum(resources.getLpNum());
        conCheck.setLpAmount(consInfo.getPrice().multiply(resources.getLpNum()));
        conCheck.setCreateTime(new Timestamp(System.currentTimeMillis()));
        conCheck.setRemark(resources.getRemark());
        return tbConCheckMapper.toDto(tbConCheckRepository.save(conCheck));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TbConCheck resources) {
        TbConCheck tbConCheck = tbConCheckRepository.findById(resources.getId()).orElseGet(TbConCheck::new);
        ValidationUtil.isNull( tbConCheck.getId(),"TbConCheck","id",resources.getId());
        tbConCheck.copy(resources);
        tbConCheckRepository.save(tbConCheck);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            tbConCheckRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<TbConCheckDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbConCheckDto tbConCheck : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put(" conInfoId",  tbConCheck.getConInfoId());
            map.put(" conName",  tbConCheck.getConName());
            map.put(" price",  tbConCheck.getPrice());
            map.put(" stockNumber",  tbConCheck.getStockNumber());
            map.put(" lpNum",  tbConCheck.getLpNum());
            map.put(" lpAmount",  tbConCheck.getLpAmount());
            map.put(" acStockNumber",  tbConCheck.getAcStockNumber());
            map.put(" createTime",  tbConCheck.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}