package com.prolog.cs.biz.outbound.utils;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import com.prolog.cs.biz.outbound.core.SpringUtils;
import com.prolog.cs.biz.outbound.dao.WaveBillMapper;
import com.prolog.cs.biz.outbound.model.BILL_STATUS;
import com.prolog.cs.biz.outbound.model.entity.WaveBillDO;
import com.prolog.framework.utils.MapUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.Objects;

/**
 * 算法工具类
 * Created by chenjun on 2021-03-25.
 */
public class BillUtils {
    private static Logger logger = LoggerFactory.getLogger(BillUtils.class);

    // 流水号格式
    private final static String FORMAT_CODE = "00000";

    public static boolean updateStatus(String billId, BILL_STATUS status) {
        Map<String, Object> statusMap = MapUtils.put("status", status.getCode()).getMap();
        WaveBillMapper billMapper = SpringUtils.getBeansByType(WaveBillMapper.class);
        long result = billMapper.updateMapById(billId, statusMap, WaveBillDO.class);
        if (result == 1) {
            logger.info("更新订单状态成功billId={} ", billId);
            return false;
        }
        logger.info("更新订单状态失败,billId={} ", billId);
        return true;
    }

    public static boolean updateStatus(String billId, BILL_STATUS status,String errorMsg) {
        String value = errorMsg.replaceAll("\r|\n", "");
        value=value.length()>100?value.substring(0,100):value;
        Map<String, Object> statusMap = MapUtils.put("status", status.getCode()).
                put("errorMsg", value).
                getMap();
        WaveBillMapper billMapper = SpringUtils.getBeansByType(WaveBillMapper.class);
        long result = billMapper.updateMapById(billId, statusMap, WaveBillDO.class);
        if (result == 1) {
            logger.info("更新订单状态成功billId={} ", billId);
            return false;
        }
        logger.info("更新订单状态失败,billId={} ", billId);
        return true;
    }

    /**
     * 生成标签码
     * @param firstPreFix 条码第一位区分出库与补货：1 出库，2补货
     * @param secondPreFix 条码第二位区分整件、零货：0 整件，1零货
     * @param serialNum 序号
     * @param slidwayNo 条码第三位、第四位为配送方向/上架库区
     * @return
     */
    public static String getBarcode(String firstPreFix, String secondPreFix, Integer serialNum, String slidwayNo, String suffix){
        Date date = DateUtil.date();
        //2022 - 2000 = 22
        int year = DateUtil.year(date) - 2000;
        int month = DateUtil.month(date) + 1;
        String monthStr = month < 10 ? "0" + month : "" + month;
        int day = DateUtil.dayOfMonth(date);
        String dayStr = day < 10 ? "0" + day : "" + day;
        String serialNumStr = String.valueOf(serialNum);
        for (int i = 0; i < 4; i ++){
            if (serialNumStr.length() >= 4){
                break;
            }
            serialNumStr = "0" + serialNumStr;
        }
        return firstPreFix + secondPreFix + slidwayNo + year + monthStr + dayStr + serialNumStr +suffix;
    }

    /**
     * 拼箱号生成 日期加四位流水号
     */
    public static String getBarcode(RedisTemplate redisTemplate){
        String redisKey = "wms:pick:serial:" + DateUtil.format(DateUtil.date(), DatePattern.NORM_DATE_FORMAT);
        RedisAtomicInteger counter = new RedisAtomicInteger(redisKey, redisTemplate.getConnectionFactory());
        counter.expireAt(DateUtil.endOfDay(DateUtil.date()));
        Integer serialNo = counter.incrementAndGet();

        // 使用日期格式化工具类将日期格式化成想要的格式   LocalDateTime是1.8新增的   他是线程安全的
        LocalDateTime now = LocalDateTime.now(ZoneId.of("+8"));
        // 格式在这里定义
        String pattern = "yyyyMMdd";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        String date = formatter.format(now);

        //使用数字格式化工具类将ID转换成想要的数据格式     DecimalFormat:数字格式化工具类
        DecimalFormat dft = new DecimalFormat(FORMAT_CODE);
        String code = dft.format(serialNo); // 格式化为四位流水号 code: 0001
        return date + code;
    }
}