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

import cn.ysk.cashier.exception.BadRequestException;
import cn.ysk.cashier.pojo.product.TbProduct;
import cn.ysk.cashier.pojo.product.TbProductSku;
import cn.ysk.cashier.pojo.product.TbProductStockDetail;
import cn.ysk.cashier.pojo.shop.TbShopInfo;
import cn.ysk.cashier.pojo.shop.TbShopUnit;
import cn.ysk.cashier.repository.product.TbProductRepository;
import cn.ysk.cashier.repository.product.TbProductSkuRepository;
import cn.ysk.cashier.repository.product.TbProductStockDetailRepository;
import cn.ysk.cashier.repository.shop.TbShopInfoRepository;
import cn.ysk.cashier.repository.shop.TbShopUnitRepository;
import cn.ysk.cashier.service.LogService;
import cn.ysk.cashier.service.product.StockService;
import cn.ysk.cashier.utils.JSONUtil;
import cn.ysk.cashier.utils.SecurityUtils;
import cn.ysk.cashier.utils.StringUtils;
import cn.ysk.cashier.utils.WxMsgUtils;
import cn.ysk.cashier.vo.StockUpdateValueVO;
import cn.ysk.cashier.vo.StockUpdateWarnLineVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
@RequiredArgsConstructor
public class StockServiceImpl implements StockService {

    private final TbProductSkuRepository tbProductSkuRepository;

    private final TbShopInfoRepository tbShopInfoRepository;
    private final TbShopUnitRepository shopUnitRepository;
    private final TbProductStockDetailRepository tbProductStockDetailRepository;
    private final TbProductRepository tbProductRepository;
    private final WxMsgUtils wxMsgUtils;
    private final LogService logService;

    @PersistenceContext
    private EntityManager em;


    @Override
    @Transactional
    public void updateProductStatus(List<StockUpdateValueVO> updateValueVOs) {
        TbProduct product = new TbProduct();
        for (StockUpdateValueVO updateValueVO : updateValueVOs) {
            if (!updateValueVO.isSku()) {
                if (product.getId() == null) {
                    product = tbProductRepository.getById(Integer.valueOf(updateValueVO.getId()));
                }
                productUp(updateValueVO, product);
            } else {
                if (product.getId() == null) {
                    product = tbProductRepository.selectBySkuId(Integer.valueOf(updateValueVO.getId()));
                }
                productSkuUp(updateValueVO, product);
            }
        }
    }

    public void productUp(StockUpdateValueVO updateValueVO,TbProduct product){
        if(Objects.isNull(product)){
            throw new BadRequestException("该商品不存在");
        }
        StringBuilder sqlQuery = new StringBuilder("update tb_product ");
        StringBuilder description = new StringBuilder("商品" + product.getName());
        switch (updateValueVO.getKey()) {
            case "pauseSale"://商品 暂停销售
                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
                    throw new BadRequestException("无效值");
                }
                sqlQuery.append(" set is_pause_sale = ").append(updateValueVO.getValue());
                description.append(" 修改为" + ("0".equals(updateValueVO.getValue()) ? "非售罄" : "已售罄"));
                break;
            case "grounding"://上下架
                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
                    throw new BadRequestException("无效值");
                }
                tbProductSkuRepository.updateGroundingByProId(product.getId().toString(), Integer.valueOf(updateValueVO.getValue()));
                description.append("0".equals(updateValueVO.getValue()) ? "已下架" : "已上架");
                sqlQuery.append(" set is_grounding = ").append(updateValueVO.getValue());
                // 推送微信操作消息
                wxMsgUtils.aboardOperationMsg(("1".equals(updateValueVO.getValue()) ? "上架商品: " : "下架商品: ") + product.getName(), Integer.valueOf(product.getShopId()));
                break;
            case "stockNumber"://库存
                description.append(" 库存数量修改为:"+updateValueVO.getValue()+" 原库存:"+product.getStockNumber());
                sqlQuery.append(" set stock_number = ").append(updateValueVO.getValue());
                TbProductStockDetail detail=new TbProductStockDetail();
                detail.setProductId(product.getId().toString());
                detail.setProductName(product.getName());
                detail.setShopId(product.getShopId());
                detail.setOperator(SecurityUtils.getCurrentUsername());
                detail.setSourcePath("NORMAL");
                detail.setLeftNumber(product.getStockNumber());
                detail.setStockNumber(new Double(Integer.valueOf(updateValueVO.getValue())-product.getStockNumber()));
                TbShopUnit tbShopUnit = shopUnitRepository.findById(product.getUnitId()).orElse(null);
                if(tbShopUnit!=null){
                    detail.setUnitName(tbShopUnit.getName());
                }
                if (product.getStockNumber() > Integer.valueOf(updateValueVO.getValue())) {
                    detail.setSubType(-1);
                    detail.setType("盘点出库");
                } else {
                    detail.setSubType(1);
                    detail.setType("盘点入库");
                }
                detail.setCreatedAt(System.currentTimeMillis());
                detail.setUpdatedAt(System.currentTimeMillis());
                tbProductStockDetailRepository.save(detail);
                break;
            case "salePrice"://价格
                description.append("修改价格为" + updateValueVO.getValue());
                sqlQuery.append(" set low_price = ").append(updateValueVO.getValue());
                tbProductRepository.upLowPrice(product.getId(),new BigDecimal(updateValueVO.getValue()));
                tbProductSkuRepository.upSalePrice(product.getId().toString(),new BigDecimal(updateValueVO.getValue()));
                break;
            case "refundStock"://商品 暂停销售
                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
                    throw new BadRequestException("无效值");
                }
                sqlQuery.append(" set is_refund_stock = ").append(updateValueVO.getValue());
                description.append(" 修改为" + ("0".equals(updateValueVO.getValue()) ? "退款不退回库存":"退款退回库存"));
                break;
//            case "stock"://库存开关
//                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
//                    throw new BadRequestException("无效值");
//                }
//                description.append("库存开关" + ("0".equals(updateValueVO.getValue()) ? "已关闭" : "已开启"));
//                sqlQuery.append(" set is_stock = ").append(updateValueVO.getValue());
//                break;
//            case "distribute"://共享库存
//                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
//                    throw new BadRequestException("无效值");
//                }
//                description.append("库存共享 " + ("0".equals(updateValueVO.getValue()) ? "已关闭" : "已开启"));
//                sqlQuery.append(" set is_distribute = ").append(updateValueVO.getValue());
//                break;
            default:
                throw new BadRequestException("无效更新类型");
        }

        sqlQuery.append(" where ");
        if (StringUtils.isNotBlank(updateValueVO.getShopId())) {
            sqlQuery.append(" shop_id = ").append(updateValueVO.getShopId());
            sqlQuery.append(" and ");
        }
        sqlQuery.append(" id = ").append(updateValueVO.getId());
        sqlQuery.append(" ;");

        Query nativeQuery = em.createNativeQuery(String.valueOf(sqlQuery));
        nativeQuery.executeUpdate();
        if("pauseSale".equals(updateValueVO.getKey())){
            wxMsgUtils.aboardOperationMsg(("0".equals(updateValueVO.getValue()) ? "关闭售罄: " : "开启售罄: ") + product.getName(),
                    Integer.valueOf(updateValueVO.getShopId()));
        }
        logService.save(description.toString(),
                "cn.ysk.cashier.controller.product.StockController.updateProductStatus()",
                Integer.valueOf(product.getShopId()),
                JSONUtil.toJSONString(updateValueVO));
    }

    public void productSkuUp(StockUpdateValueVO updateValueVO, TbProduct product) {
        if (Objects.isNull(product)) {
            throw new BadRequestException("该商品不存在");
        }
        TbProductSku tbProductSku = tbProductSkuRepository.findById(Integer.valueOf(updateValueVO.getId())).orElse(null);
        if (Objects.isNull(tbProductSku)) {
            throw new BadRequestException("该商品规格不存在");
        }
        StringBuilder sqlQuery = new StringBuilder("update tb_product_sku ");
        StringBuilder description = new StringBuilder("商品" + product.getName()+" 规格:" + tbProductSku.getSpecSnap());
        switch (updateValueVO.getKey()) {
            case "pauseSale": //sku售罄
                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
                    throw new BadRequestException("无效值");
                }
                sqlQuery.append(" set is_pause_sale = ").append(updateValueVO.getValue());
                description.append(" 修改为").append("0".equals(updateValueVO.getValue()) ? "非售罄" : "已售罄");
                break;
            case "grounding": //sku上下架
                if (!"0".equals(updateValueVO.getValue()) && !"1".equals(updateValueVO.getValue())) {
                    throw new BadRequestException("无效值");
                }
                sqlQuery.append(" set is_grounding = ").append(updateValueVO.getValue());
                wxMsgUtils.aboardOperationMsg(("1".equals(updateValueVO.getValue()) ? "上架: " : "下架: ") + description, Integer.valueOf(product.getShopId()));
                description.append("0".equals(updateValueVO.getValue()) ? "已下架" : "已上架");
                break;
            case "salePrice"://价格
                description.append("修改价格为").append(updateValueVO.getValue());
                sqlQuery.append(" set sale_price = ").append(updateValueVO.getValue());
                if(("sku").equals(product.getTypeEnum())){
                    BigDecimal bigDecimal = tbProductSkuRepository.searchMinSalePrice(Integer.valueOf(tbProductSku.getProductId()),tbProductSku.getId());
                    if (bigDecimal.compareTo(new BigDecimal(updateValueVO.getValue())) < 0) {
                        tbProductRepository.upLowPrice(product.getId(),bigDecimal);
                    }else {
                        tbProductRepository.upLowPrice(product.getId(),new BigDecimal(updateValueVO.getValue()));
                    }
                }else {
                    tbProductRepository.upLowPrice(product.getId(),new BigDecimal(updateValueVO.getValue()));
                }
                break;
            default:
                throw new BadRequestException("无效更新类型");
        }
        sqlQuery.append(" where ");
        if (StringUtils.isNotBlank(updateValueVO.getShopId())) {
            sqlQuery.append(" shop_id = ").append(updateValueVO.getShopId());
            sqlQuery.append(" and ");
        }
        sqlQuery.append(" id = ").append(updateValueVO.getId());
        sqlQuery.append(" ;");

        Query nativeQuery = em.createNativeQuery(String.valueOf(sqlQuery));
        nativeQuery.executeUpdate();

        if("pauseSale".equals(updateValueVO.getKey())){
            // 推送微信操作消息
            wxMsgUtils.aboardOperationMsg(
                    ("0".equals(updateValueVO.getValue()) ? "关闭售罄: " : "开启售罄: ") + product.getName() + "/" + tbProductSku.getSpecSnap(),
                    Integer.valueOf(updateValueVO.getShopId()));
        }
        logService.save(description.toString(),
                "cn.ysk.cashier.controller.product.StockController.updateProductStatus()",
                Integer.valueOf(product.getShopId()),
                JSONUtil.toJSONString(updateValueVO));
    }


    @Override
    public void updateProductWarnLine(StockUpdateWarnLineVO stockUpdateWarnLineVO) {
        TbShopInfo shopInfo = tbShopInfoRepository.findById(Integer.valueOf(stockUpdateWarnLineVO.getShopId())).orElse(null);
        if (shopInfo == null) {
            throw new BadRequestException("店铺不存在");
        }
        tbProductRepository.updateWarnLineByShopId(stockUpdateWarnLineVO.getWarnLine(), stockUpdateWarnLineVO.getShopId());
    }
}
