/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package cn.ysk.cashier.service.impl.order;

import cn.ysk.cashier.dto.product.TbProductDto;
import cn.ysk.cashier.pojo.order.TbCashierCart;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.repository.product.TbProductRepository;
import cn.ysk.cashier.repository.product.TbProductSkuRepository;
import cn.ysk.cashier.service.product.TbProductService;
import cn.ysk.cashier.utils.*;
import lombok.RequiredArgsConstructor;
import cn.ysk.cashier.repository.order.TbCashierCartRepository;
import cn.ysk.cashier.service.order.TbCashierCartService;
import cn.ysk.cashier.dto.order.TbCashierCartDto;
import cn.ysk.cashier.dto.order.TbCashierCartQueryCriteria;
import cn.ysk.cashier.mapper.order.TbCashierCartMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.jpa.domain.Specification;
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.util.List;
import java.util.Map;
import java.io.IOException;
import javax.persistence.criteria.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
* @website https://eladmin.vip
* @description 服务实现
* @author lyf
* @date 2024-03-02
**/
@Service
@RequiredArgsConstructor
public class TbCashierCartServiceImpl implements TbCashierCartService {

    private static final Logger log = LoggerFactory.getLogger(TbCashierCartServiceImpl.class);
    private final TbCashierCartRepository tbCashierCartRepository;
    private final TbCashierCartMapper tbCashierCartMapper;
    private final TbProductService tbproductService;
    private final TbProductSkuRepository skuRepository;
    private final RedisUtils redisUtils;
    private final TbProductRepository tbProductRepository;


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

    @Override
    public List<TbCashierCartDto> queryAll(TbCashierCartQueryCriteria criteria){
        return tbCashierCartMapper.toDto(tbCashierCartRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public TbCashierCartDto findById(Integer id) {
        TbCashierCart tbCashierCart = tbCashierCartRepository.findById(id).orElseGet(TbCashierCart::new);
        ValidationUtil.isNull(tbCashierCart.getId(),"TbCashierCart","id",id);
        return tbCashierCartMapper.toDto(tbCashierCart);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TbCashierCartDto create(TbCashierCart resources) {
        return tbCashierCartMapper.toDto(tbCashierCartRepository.save(resources));
    }

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

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

    @Override
    public void download(List<TbCashierCartDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (TbCashierCartDto tbCashierCart : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("主单Id", tbCashierCart.getMasterId());
            map.put("本次下单Id", tbCashierCart.getOrderId());
            map.put("退单Id", tbCashierCart.getRefOrderId());
            map.put("购物车总额", tbCashierCart.getTotalAmount());
            map.put("商品Id", tbCashierCart.getProductId());
            map.put("商品图片", tbCashierCart.getCoverImg());
            map.put("是否sku", tbCashierCart.getIsSku());
            map.put("skuId", tbCashierCart.getSkuId());
            map.put("商品名", tbCashierCart.getName());
            map.put("单价", tbCashierCart.getSalePrice());
            map.put("结余数量", tbCashierCart.getNumber());
            map.put("总下单数量", tbCashierCart.getTotalNumber());
            map.put("退单数量", tbCashierCart.getRefundNumber());
            map.put("分类Id", tbCashierCart.getCategoryId());
            map.put("'购物车关闭 closed',' 购物车挂起 refund',' 购物车列表生效create',' 购物车完成final'", tbCashierCart.getStatus());
            map.put("是否为组合商品 0-单商品 1为组合商品", tbCashierCart.getType());
            map.put("商户Id", tbCashierCart.getMerchantId());
            map.put("店铺Id", tbCashierCart.getShopId());
            map.put(" createdAt",  tbCashierCart.getCreatedAt());
            map.put(" updatedAt",  tbCashierCart.getUpdatedAt());
            map.put("用户的openId", tbCashierCart.getUserId());
            map.put("台桌id", tbCashierCart.getTableId());
            map.put("打包费", tbCashierCart.getPackFee());
            map.put(" tradeDay",  tbCashierCart.getTradeDay());
            map.put(" isPack",  tbCashierCart.getIsPack());
            map.put(" isGift",  tbCashierCart.getIsGift());
            map.put(" pendingAt",  tbCashierCart.getPendingAt());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public void clearExpireOrder(TbCashierCart cart) {
        String key = CacheKey.PRODUCT + cart.getShopId() + ":product" + cart.getProductId();
        TbProduct tbProduct = tbProductRepository.findById(Integer.valueOf(cart.getProductId())).orElse(null);
        if (tbProduct == null) {
            log.warn("清空购物车查询订单失败，product id： {}", cart.getProductId());
            return;
        }
        if (tbProduct.getIsDistribute() == 1) {
            tbproductService.incrStockNumber(cart.getProductId(), cart.getNumber());
        } else {
            key = CacheKey.PRODUCT + cart.getShopId() + ":" + cart.getId();
            skuRepository.updateStockNumber(Integer.valueOf(cart.getSkuId()),cart.getNumber().doubleValue());
        }

        // 减去销量
        if (cart.getNumber() > 0) {
            redisUtils.decrBy(key, cart.getNumber());
        }
    }
}