package co.dc.aptiv.service;

import co.dc.aptiv.AptivApp;
import co.dc.commons.basedao.CommonBaseDao;
import co.dc.commons.utils.DateTimeUtil;
import co.dc.aptiv.ScanFrame;
import co.dc.aptiv.pojo.BillDetailPojo;
import co.dc.aptiv.pojo.MaterielPojo;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * @describe: 二维码生成
 * @author: liuxinglong
 * @version: 2018/4/18 19:50
 */
@Service("qrCodesService")
public class QrCodeService {
    private ScanFrame scanFrame;
    @Resource(name = "commonBaseDao")
    private CommonBaseDao baseDao;
    private static final Log log = LogFactory.getLog(QrCodeService.class);
    protected String createDateTime = null;
    boolean isReCode = false;

    /**
     * 根据物料Id生成二维码
     *
     * @param materielId 物料Id
     * @return QR Code
     */
    public String generateQRCode(Long materielId) {
        createDateTime = DateTimeUtil.getDateTimeString();
        //当前日期
        String nowDate = createDateTime.substring(0, 10);
        //物料最后生产日期
        String lastDate = AptivApp.billDetailService.getLastDate(materielId);
        MaterielPojo materielPojo = AptivApp.materielService.findById(materielId);
        if (materielPojo == null) {
            log.info("物料不存在，无法生成码");
            return null;
        }
        /*lastDate == null || (nowDate - lastDate > 0)  = 重置计数*/
        if (lastDate == null || (DateTimeUtil.compareDay(nowDate, lastDate) > 0)) {
            //重置计数
            materielPojo.setMaxNum(1);
            AptivApp.materielService.updateMaterielpojo(materielPojo);
        }
        //每天计数不能超过9999
        /*if (materielPojo.getMaxNum() > 9999) {
            return null;
        }*/
        String maxNum = materielPojo.getMaxNum() + "";
        //最大序号不足4位进行补位
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4 - maxNum.length(); i++) {
            sb.append("0");
        }
        maxNum = sb.toString() + maxNum;
        //更新物料序号
        AptivApp.materielService.updateMaterielpojoMaxNum(materielId);
        //物料编号+生产日期+(补位+最大序号）
        String code = materielPojo.getCpn() + " " + nowDate.replace("-", "").substring(2, 8) + maxNum;
        log.info("生成码 =" + code);
        return code;
    }


    /**
     * 将码发送到激光机
     */
    public int sendQrCode() {
//        if (AptivApp.flag && AptivApp.printStatus) {
        if (AptivApp.flag) {
//            AptivApp.printStatus = false;
            String code = generateQRCode(AptivApp.nowMaterielPojo.getId()).trim();
            if (code == null) {
                return 2;
            }
            AptivApp.qrCode = code;
            BillDetailPojo billDetailPojo = baseDao.findByParam(BillDetailPojo.class, "qrCode", AptivApp.qrCode);
            //不是重码才发往激光机打印，是重码提示管理员
            if (billDetailPojo == null) {
                getScanFrame().loadCode();
                //获取码并发送到激光机
                int status = AptivApp.printMina.sendByte(AptivApp.ccu.String2ASCII(AptivApp.nowMaterielPojo.getCpn() + AptivApp.nowMaterielPojo.getType() + AptivApp.qrCode));
                if (status > 0) {
                    return status;
                }
            } else {
                log.error("生产出重码 =" + AptivApp.qrCode);
                getScanFrame().alertMsg(1, "生产出重码，请停止打印并联系管理员");
            }
        }
        return -1;
    }


    /**
     * 从采集器接收码并保存
     *
     * @param str
     */
    public void receiveQrCode(String str) {
        //设置扫描状态为不可扫描
//        AptivApp.scanStatus = false;
        //采集器未采到码
        if ("ERROR".equals(str)) {
            log.info("生产模式：采集器未采集到码");
        }
        //检查重码
        BillDetailPojo billDetailPojo = baseDao.findByParam(BillDetailPojo.class, "qrCode", str);
        boolean reCodeORFailed = billDetailPojo != null || (AptivApp.qrCode != null && !AptivApp.qrCode.equals(str));
        //重码或不合格返给采集器错误信号
        if (reCodeORFailed) {
            sendErrorCommand(billDetailPojo != null ? "生产模式：检测到重码！" : "生产模式：采集器采集到不合格的码");
        }
        //保存详情
        BillDetailPojo bdp = AptivApp.billDetailService.addBillDetail(AptivApp.billPojo.getId(), AptivApp.nowMaterielPojo.getId(), AptivApp.qrCode, str);
        getScanFrame().loadjtable1(bdp);
        //更新单据统计数据
        AptivApp.billService.updateBillStatistics(AptivApp.billPojo.getId(), bdp);
        log.info("成功保存码" + str);
        //设置打印状态为可打印
//        AptivApp.printStatus = true;

        //打印状态且非联机模式，重新发码
        if (AptivApp.flag && !getScanFrame().onLine) {
            int codeFlag = sendQrCode();
            if (codeFlag != 1) {
                log.info("发送码给激光机异常");
                getScanFrame().alertMsg(1, "生产码异常，请停止打印并联系管理员！");
            }
        }

    }

    /**
     * 统计当前日期打印总数
     *
     * @return
     */
    public Map<String, Object> countDayData() {
        String date = DateTimeUtil.getDateString();
        Map<String, Object> map = new HashMap<String, Object>(3);
        try {
            String sql = "SELECT SUM(number),sum(qualifiedNum),sum(UnqualifiedNum) FROM bill WHERE createTime BETWEEN '" + date + " 00:00:00' AND '" + date + " 23:59:59';";
            map = baseDao.query(sql, new MapHandler());
            log.info("统计当前日期打印总数" + map.toString());
        } catch (SQLException e) {
            log.error("统计当前日期打印总数异常：" + e);
        }
        return map;
    }


    public ScanFrame getScanFrame() {
        return scanFrame;
    }

    public void setScanFrame(ScanFrame scanFrame) {
        this.scanFrame = scanFrame;
    }

    /**
     * 检查重码
     * 判断是不是我们产的码
     * 不是我们产的码返给采集器错误信号
     * 是我们生产的那肯定是重码
     *
     * @return
     */
    public void checkReCode(String str) {
        //采到的码去找当前订单详情
        BillDetailPojo billDetailPojo = baseDao.findByParam(BillDetailPojo.class, "qrCode", str);
        sendErrorCommand(billDetailPojo == null ? "点检模式：检测到不是程序生产的码！" : "点检模式：检测到重码！");
        isReCode = billDetailPojo == null;
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                getScanFrame().alertMsg(1, isReCode ? "检测到不是程序生产的码！" : "检测到重码！");
            }
        });
    }


    /**
     * 重置激光机的数据，以实现打印完就清空的效果
     * 目前不理想，二空格仍然会被识别成二维码，需要优化方案
     */
    public void resetLaserMachine() {
        //此处的33个空格是用来清空激光机上打过的最后一条数据
        AptivApp.printMina.sendByte(AptivApp.ccu.String2ASCII("                                 "));
        log.info("清空激光机保留的最后一条数据");
    }

    /**
     * 重码时返给采集器错误信号
     */
    public void sendErrorCommand(String errorMsg) {
        AptivApp.collectorMina.send("R");
        log.info(errorMsg);
    }

}
