package com.foreverwin.mesnac.common.service.impl;


import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foreverwin.mesnac.common.constant.Constants;
import com.foreverwin.mesnac.common.dto.LabelPrintDto;
import com.foreverwin.mesnac.common.model.PrintLog;
import com.foreverwin.mesnac.common.mapper.PrintLogMapper;
import com.foreverwin.mesnac.common.service.PrintLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.modular.core.exception.BusinessException;
import com.foreverwin.modular.core.util.CommonMethods;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Philip
 * @since 2021-07-16
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class PrintLogServiceImpl extends ServiceImpl<PrintLogMapper, PrintLog> implements PrintLogService {

    @Value("${print.server}")
    private String printServer;

    @Autowired
    private PrintLogMapper printLogMapper;

    @Autowired
    private PrintLogService printLogService;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void savePrintLog(String site, String user, PrintLog printLog) {
        LocalDateTime dateTime = LocalDateTime.now();

        printLog.setSite(site);
        printLog.setCreateUser(user);
        printLog.setCreatedDateTime(dateTime);
        printLog.setModifyUser(user);
        printLog.setModifiedDateTime(dateTime);
        this.save(printLog);
    }

    @Override
    public void labelPrint(String site, String user, List<PrintLog> printList) {
        // 获取printParam，并拼接为json格式字符串
        StringBuffer stringBuffer = new StringBuffer("[");
        for (PrintLog printLog : printList) {
            String printParam = printLog.getPrintParam();
            stringBuffer.append(printParam.replace("[","").replace("]","")).append(",");
        }
        StringBuffer append = stringBuffer.deleteCharAt(stringBuffer.length() - 1).append("]");
        List<LabelPrintDto> list= JSONArray.parseArray(append.toString(), LabelPrintDto.class);
        // 打印机、打印模板
        for (int i = 0; i < list.size(); i++) {
            list.get(i).setPrinter(printList.get(i).getPrintName());
            list.get(i).setPrintTemplate(printList.get(i).getPrintTemplate());
            list.get(i).setPrintNum(printList.get(i).getPrintNum());
        }

        // 访问打印服务
        printServer(list);

        // 更新打印记录：是否已打印、使用的打印机、打印次数
        List<PrintLog> printLogList = new ArrayList<>();
        for (PrintLog printLog : printList) {
            PrintLog printLogOne = new PrintLog();
            printLogOne.setHandle(printLog.getHandle());
            printLogOne.setIsPrint("true");
            Integer printNum = printLog.getPrintNum();
            String getOther1 = printLog.getOther1();
            if (getOther1 == null){
                printLogOne.setOther1("1");
            }else {
                printLogOne.setOther1(String.valueOf(Integer.valueOf(getOther1) + printNum));
            }
            if (!printLog.getCategory().equals(Constants.PRINT_TYPE_SFC)){
                printLogOne.setPrintName(printLog.getPrintName());
            }
            printLogList.add(printLogOne);
        }
        printLogService.updateBatchById(printLogList);

    }

    @Override
    public List<PrintLog> getPrintLogListByCondition(PrintLog printLog) {
        return printLogMapper.getPrintLogListByCondition(printLog);
    }

    @Override
    public LabelPrintDto findSfcPrintInfoBySfc(String sfc) {
        String site = CommonMethods.getSite();
        List<LabelPrintDto> sfcPrintInfoBySfc = printLogMapper.findSfcPrintInfoBySfc(sfc, site);
        if (sfcPrintInfoBySfc.size() < 1){
            throw BusinessException.build("未找到生产的库存数据！");
        }
        return sfcPrintInfoBySfc.get(0);
    }

    @Override
    public void sfcLabelPrint(Map<String,Object> map) {
        Integer qty = (Integer) map.get("qty");
        String itemBo = (String) map.get("itemBo");
        List<LabelPrintDto> labelPrintDtoList = (List<LabelPrintDto>) map.get("labelPrintDtoList");

        // 解决无法获取list中对象的问题
        String parse = JSON.toJSONString(labelPrintDtoList);
        List<LabelPrintDto> labelPrintDtos = JSONObject.parseArray(parse, LabelPrintDto.class);

        // 访问打印服务
        printServer(labelPrintDtos);

        // 打印张数
        Integer printNum = 0;
        for (LabelPrintDto labelP:labelPrintDtos) {
            printNum += labelP.getPrintNum();
        }
        LabelPrintDto labelPrintDto = labelPrintDtos.get(0);
        PrintLog printLog = new PrintLog();
        printLog.setCategory(Constants.PRINT_TYPE_SFC_SPE);
        printLog.setSfc(labelPrintDto.getSfc());
        printLog.setSite(CommonMethods.getSite());
        List<PrintLog> printLogListByCondition = printLogService.getPrintLogListByCondition(printLog);
        if (printLogListByCondition.size() == 1){
            PrintLog printLog1 = printLogListByCondition.get(0);
            printLog1.setPrintNum(printNum);
            printLog1.setModifiedDateTime(LocalDateTime.now());
            printLog1.setModifyUser(CommonMethods.getUser());
            printLogService.updateById(printLog1);
        }else{
            labelPrintDto.setQty(BigDecimal.valueOf(qty));
            printLog.setPrintParam(JSON.toJSONString(labelPrintDto));
            printLog.setItemBo(itemBo);
            printLog.setItem(labelPrintDto.getItem());
            printLog.setPrintName(labelPrintDto.getPrinter());
            printLog.setPrintTemplate(labelPrintDto.getPrintTemplate());
            printLog.setIsPrint("true");
            printLog.setPrintNum(printNum);
            printLog.setHandle(UUID.randomUUID().toString());
            printLog.setCreatedDateTime(LocalDateTime.now());
            printLog.setCreateUser(CommonMethods.getUser());
            printLogService.save(printLog);
        }
    }

    public void printServer(List<LabelPrintDto> list){
        // 超时时间180秒/3分钟
        String post = HttpUtil.post(printServer, JSON.toJSONString(list), 180000);
        /**
         * {"msg":"打印成功","code":0}
         * {"msg":"打印失败","code":500}
         * 根据返回值，更新打印机信息-printName及打印是否成功信息isPrint
         */
        JSONObject jsonObject = JSONObject.parseObject(post);
        Integer code = jsonObject.getInteger("code");
        String msg = jsonObject.getString("msg");
        if (code != 0){
            throw BusinessException.build(msg);
        }
    }

}