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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.ysk.cashier.cons.domain.TbConsInfo;
import cn.ysk.cashier.cons.domain.TbProskuCon;
import cn.ysk.cashier.cons.repository.TbConsInfoRepository;
import cn.ysk.cashier.cons.service.dto.ProskuInfo;
import cn.ysk.cashier.cons.service.dto.TbProskuConDtoV2;
import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductSku;
import cn.ysk.cashier.repository.product.TbProductRepository;
import cn.ysk.cashier.repository.product.TbProductSkuRepository;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.cons.repository.TbProskuConRepository;
import cn.ysk.cashier.cons.service.TbProskuConService;
import cn.ysk.cashier.cons.service.dto.TbProskuConDto;
import cn.ysk.cashier.cons.service.dto.TbProskuConQueryCriteria;
import cn.ysk.cashier.cons.service.mapstruct.TbProskuConMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.util.CollectionUtils;

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

@Service
@RequiredArgsConstructor
@Slf4j
public class TbProskuConServiceImpl implements TbProskuConService {

    private final TbProskuConRepository tbProskuConRepository;
    private final TbProskuConMapper tbProskuConMapper;

    private final TbProductRepository tbProductRepository;

    private final TbProductSkuRepository tbProductSkuRepository;

    private final TbConsInfoRepository tbConsInfoRepository;

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

    @Override
    public List<TbProskuConDto> queryAll(TbProskuConQueryCriteria criteria){
        return tbProskuConMapper.toDto(tbProskuConRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public TbProskuConDto findById(Integer id) {
        TbProskuCon tbProskuCon = tbProskuConRepository.findById(id).orElseGet(TbProskuCon::new);
        ValidationUtil.isNull(tbProskuCon.getId(),"TbProskuCon","id",id);
        return tbProskuConMapper.toDto(tbProskuCon);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TbProskuConDto create(List<ProskuInfo> resources) throws Exception {

        log.info("List<ProskuInfo> resources:{}",JSONUtil.toJSONString(resources));
        for (ProskuInfo resource : resources) {
            TbProduct product= tbProductRepository.getById(resource.getProductId());
            if(Objects.isNull(product)){
                throw new BadRequestException("对应的商品信息不存在");
            }
            List<TbProskuCon> list=new ArrayList<>();
//            if(product.getIsDistribute().intValue()==1){

                TbConsInfo tbConsInfo= tbConsInfoRepository.findById(resource.getConsInfoId()).orElseGet(TbConsInfo::new);

                if(ObjectUtil.isNull(tbConsInfo)||ObjectUtil.isNull(tbConsInfo.getId())){
                    throw new BadRequestException("对应的耗材信息不存在");
                }

                //查询商品对应的所有规格
                List<TbProductSku> skuList= tbProductSkuRepository.searchSku(product.getId().toString());
                if(Objects.nonNull(skuList)&&skuList.size()>0){
                    for (TbProductSku tbProductSku : skuList) {
                        int count=tbProskuConRepository.countByConInfoIdAndProductSkuIdAndShopId(resource.getConsInfoId(), tbProductSku.getId(), Integer.valueOf(tbProductSku.getShopId()), Integer.valueOf(tbProductSku.getProductId()));
                        if(count<=0){
                            TbProskuCon tbProskuCon=new TbProskuCon();

                            tbProskuCon.setShopId(Integer.valueOf(tbProductSku.getShopId()));
                            tbProskuCon.setConInfoId(tbConsInfo.getId());
                            tbProskuCon.setProductId(Integer.valueOf(tbProductSku.getProductId()));
                            tbProskuCon.setProductSkuId(tbProductSku.getId());
                            tbProskuCon.setSurplusStock(resource.getSurplusStock());
                            tbProskuCon.setStatus("1");
                            tbProskuCon.setCreateTime(new Timestamp(System.currentTimeMillis()));
                            list.add(tbProskuCon);
                        }else {
                            throw new BadRequestException(product.getName().concat("对应的耗材信息已存在"));
                        }
                    }
                }

//            }else {
//                for (ProskuInfo.SkuInfo skuInfo : resource.getSkuInfos()) {
//
//
//                    TbConsInfo tbConsInfo= tbConsInfoRepository.findById(skuInfo.getConInfoId()).orElseGet(TbConsInfo::new);
//
//                    log.info("skuInfo:{}", JSONUtil.toJSONString(tbConsInfo));
//
//                    if(ObjectUtil.isNull(tbConsInfo)||ObjectUtil.isNull(tbConsInfo.getId())){
//                        throw new BadRequestException("对应的耗材信息不存在");
//                    }
//
//                    TbProductSku tbProductSku= tbProductSkuRepository.findById(skuInfo.getSkuId()).orElseGet(TbProductSku::new);
//                    if(ObjectUtil.isNull(tbProductSku)||ObjectUtil.isNull(tbProductSku.getId())){
//                        throw new BadRequestException("规格信息不存在");
//                    }
//
//                    int count=tbProskuConRepository.countByConInfoIdAndProductSkuIdAndShopId(resource.getConsInfoId(), skuInfo.getSkuId(), skuInfo.getShopId(), resource.getProductId());
//                    if(count<=0){
//                        TbProskuCon tbProskuCon=new TbProskuCon();
//                        tbProskuCon.setShopId(Integer.valueOf(skuInfo.getShopId()));
//                        tbProskuCon.setConInfoId(tbConsInfo.getId());
//                        tbProskuCon.setProductId(resource.getProductId());
//                        tbProskuCon.setProductSkuId(skuInfo.getSkuId());
//                        tbProskuCon.setSurplusStock(skuInfo.getSurplusStock());
//                        tbProskuCon.setStatus("1");
//                        tbProskuCon.setCreateTime(new Timestamp(System.currentTimeMillis()));
//                        list.add(tbProskuCon);
//                    }else {
//                        TbProductSku sku=  tbProductSkuRepository.getById(skuInfo.getSkuId());
//                        throw new BadRequestException(product.getName().concat("商品对应的").concat(Objects.nonNull(sku.getSpecSnap())?sku.getSpecSnap():"").concat("规格已存在"));
//                    }
//                }
//
//            }
            if(Objects.nonNull(list)&&list.size()>0){
                tbProskuConRepository.saveAll(list);
            }
        }


        return new TbProskuConDto();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upV2(TbProskuConDtoV2 resources) {
        if (CollectionUtils.isEmpty(resources.getCons())) {
            tbProskuConRepository.deleteAllByProductId(resources.getProductId());
            return;
        }
        List<TbProskuConDto> cons = resources.getCons();
        if(hasIdentical(cons)){
            throw new BadRequestException("添加失败，对应耗材存在多条关系");
        }
        List<TbProskuCon> newCons = new ArrayList<>();
        TbProduct product = tbProductRepository.getById(resources.getProductId());
        if (Objects.isNull(product)) {
            throw new BadRequestException("对应的商品信息不存在");
        }

        List<Integer> collect = resources.getCons().stream().map(TbProskuConDto::getId).collect(Collectors.toList());
        //现有的
        List<TbProskuCon> tbProskuCons = tbProskuConRepository.searchAllByProductId(resources.getProductId());
        List<Integer> delIds = new ArrayList<>();
        for (TbProskuCon tbProskuCon : tbProskuCons) {
            if (!collect.contains(tbProskuCon.getId())) {
                delIds.add(tbProskuCon.getId());
            }
        }
        if (!CollectionUtils.isEmpty(delIds)) {
            tbProskuConRepository.deleteAllById(delIds);
        }

        //判断
        for (TbProskuConDto resource : resources.getCons()) {
            if (resource.getConInfoId() == null) {
                continue;
            }
            TbConsInfo tbConsInfo = tbConsInfoRepository.findById(resource.getConInfoId()).orElseGet(TbConsInfo::new);
            if (ObjectUtil.isNull(tbConsInfo) || ObjectUtil.isNull(tbConsInfo.getId())) {
                throw new BadRequestException("对应的耗材信息不存在");
            }
            if (resource.getSurplusStock().compareTo(BigDecimal.ZERO) <= 0) {
                throw new BadRequestException("耗材"+ tbConsInfo.getConName() +"使用数量不可小于等于 0");
            }
            TbProductSku sku = null;
            if (resource.getProductSkuId() != 0) {
                sku = tbProductSkuRepository.findById(resource.getProductSkuId()).orElseGet(TbProductSku::new);
                if (ObjectUtil.isNull(sku) || ObjectUtil.isNull(sku.getId())) {
                    throw new BadRequestException("规格信息不存在");
                }
            }
            TbProskuCon tbConsInfo1 = new TbProskuCon();

//            int count = tbProskuConRepository.countByConInfoIdAndProductSkuIdAndShopId(resource.getConInfoId(), resource.getProductSkuId(), resource.getShopId(), resource.getProductId());
//            if (count <= 0) {
//                BeanUtil.copyProperties(resource, tbConsInfo1, CopyOptions.create().setIgnoreNullValue(true));
//                newCons.add(tbConsInfo1);
//            } else {
//                StringBuilder strResult = new StringBuilder(product.getName());
//                if (sku != null) {
//                    strResult.append(" 规格" + sku.getSpecSnap());
//                }
//                strResult.append("与耗材 " + tbConsInfo.getConName() + " 的对应关系已存在");
//                throw new BadRequestException(strResult.toString());
//            }
            BeanUtil.copyProperties(resource, tbConsInfo1, CopyOptions.create().setIgnoreNullValue(true));
            newCons.add(tbConsInfo1);

        }
        if (!CollectionUtils.isEmpty(newCons)) {
            tbProskuConRepository.saveAll(newCons);
        }
    }


    public static boolean hasIdentical(List<TbProskuConDto> cons) {
        List<List<TbProskuConDto>> groupedByAllFields = cons.stream()
                .collect(Collectors.groupingBy(item -> item.getProductSkuId() + "-" + item.getConInfoId() + "-" + item.getShopId() + "-" + item.getProductId()))
                .values().stream()
                .filter(group -> group.size() > 1)
                .collect(Collectors.toList());
        return!groupedByAllFields.isEmpty();
    }

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

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

    @Override
    public void download(List<TbProskuConDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbProskuConDto tbProskuCon : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("商品规格id", tbProskuCon.getProductSkuId());
            map.put("耗材id", tbProskuCon.getConInfoId());
            map.put("状态 1 启用 0 禁用", tbProskuCon.getStatus());
            map.put("创建时间", tbProskuCon.getCreateTime());
            map.put("店铺id", tbProskuCon.getShopId());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}