package com.bonus.material.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bonus.common.biz.config.AppOcrConfig;
import com.bonus.common.biz.enums.HttpCodeEnum;
import com.bonus.common.biz.utils.HttpHelper;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.app.domain.MachineOcrBean;
import com.bonus.material.app.mapper.AppOcrMapper;
import com.bonus.material.app.service.AppOcrService;
import com.bonus.material.ma.domain.Machine;
import com.bonus.material.ma.domain.vo.MachineVo;
import com.bonus.material.ma.mapper.MachineMapper;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.internal.util.StringHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName AppOcrServiceImpl
 * @Author ma_sh
 * @create 2025/1/2 13:50
 */
@Service
@Slf4j
public class AppOcrServiceImpl implements AppOcrService {

    @Resource
    private AppOcrMapper appOcrMapper;

    @Resource
    private MachineMapper machineMapper;

    /**
     * 提交机具出库
     * @param bean
     * @return
     */
    @Override
    public AjaxResult submitOcrOut(MachineOcrBean bean) {
        int res = 0;
        try {
            String taskId = bean.getTaskId();
            // ---------↓-----bpm_example修改状态发料进行中---↓---------
            //res = updateTaskStatus(bean,taskId);
            String maId = bean.getMaId();
            MachineVo ma = machineMapper.selectMachineByMaId(Long.parseLong(maId));
            if (ma != null) {
                // ---------↓-----bpm_pick_form修改数据---↓-----------------
                //res = updateFormData(bean,taskId,pickId);

                // ---------↓-----ma_machine修改状态---↓----bpm_pick_form_details插入数据--↓-------------
                ma.setMaStatus("2");
                res = updateMaStatus(bean, ma, taskId);

                if (res > 0) {
                    // ---------↓-----ma_machine_type修改库存，在用---↓---------
                    res = updateStorageData(bean, taskId);
                    if (res > 0) {
                        log.info("maId:" + maId + "出库成功！");
                    } else {
                        throw new RuntimeException("修改ma_machine_type信息失败!");
                    }
                } else {
                    throw new RuntimeException("修改ma_machine信息失败!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (res > 0) {
            return AjaxResult.success("出库成功");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 修改库存数据
     * @param bean
     * @param taskId
     * @return
     */
    private int updateStorageData(MachineOcrBean bean, String taskId) {
        bean.setOutNum("1");
        return appOcrMapper.updateStorageData(bean);
    }

    /**
     * 修改机具状态
     * @param bean
     * @param ma
     * @param taskId
     * @return
     */
    private int updateMaStatus(MachineOcrBean bean, MachineVo ma, String taskId) {
        Machine machine = new Machine();
        machine.setMaId(Long.parseLong(bean.getMaId()));
        machine.setUpdateTime(DateUtils.getNowDate());
        machine.setMaStatus(ma.getMaStatus());
        return machineMapper.updateMachine(machine);
    }

    /**
     * 查询机具出库列表
     * @param bean
     * @return
     */
    @Override
    public List<MachineOcrBean> findByPage(MachineOcrBean bean) {
        return appOcrMapper.findByPage(bean);
    }

    /**
     * 根据code查询机具出库列表
     * @param bean
     * @return
     */
    @Override
    public List<MachineVo> findOutListByDeviceCode(MachineOcrBean bean) {
        List<MachineVo> codeList = appOcrMapper.findListByDeviceCode(bean);
        if (CollectionUtils.isNotEmpty(codeList)) {
            MachineOcrBean o= new MachineOcrBean();
            o.setModel("出库");
            o.setCode(bean.getMaCode());
            o.setResult("1");
            o.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            appOcrMapper.addOcrRecord(o);
            return codeList;
        } else {
            MachineOcrBean o= new MachineOcrBean();
            o.setModel("出库");
            o.setCode(bean.getMaCode());
            o.setResult("0");
            o.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            appOcrMapper.addOcrRecord(o);
            List<MachineVo> rsList = new ArrayList<>();
            String ocrCode = o.getMaCode();
            List<MachineVo> stList = appOcrMapper.findCodeList(o);
            for(MachineVo m : stList){
                String code =  m.getMaCode();
                float rsNum = AppOcrConfig.getSimilarityRatio(ocrCode, code, true);
                if(rsNum > 91){
                    rsList.add(m);
                }
            }
            if (CollectionUtils.isNotEmpty(rsList)) {
                return rsList;
            }
        }
        return null;
    }

    /**
     * 根据code查询机具退料列表
     * @param bean
     * @return
     */
    @Override
    public List<MachineVo> findBackListByDeviceCode(MachineOcrBean bean) {
        List<MachineVo> codeList = appOcrMapper.findListByDeviceCode(bean);
        if (CollectionUtils.isNotEmpty(codeList)) {
            MachineOcrBean o= new MachineOcrBean();
            o.setModel("退料");
            o.setCode(bean.getMaCode());
            o.setResult("1");
            o.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            appOcrMapper.addOcrRecord(o);
            return codeList;
        } else {
            MachineOcrBean o= new MachineOcrBean();
            o.setModel("退料");
            o.setCode(bean.getMaCode());
            o.setResult("0");
            o.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            appOcrMapper.addOcrRecord(o);
            List<MachineVo> rsList = new ArrayList<>();
            String ocrCode = o.getMaCode();
            List<MachineVo> stList = appOcrMapper.findCodeList(o);
            for(MachineVo m : stList){
                String code =  m.getMaCode();
                float rsNum = AppOcrConfig.getSimilarityRatio(ocrCode, code, true);
                if(rsNum > 91){
                    rsList.add(m);
                }
            }
            if (CollectionUtils.isNotEmpty(rsList)) {
                return rsList;
            }
        }
        return null;
    }

    /**
     * 提交机具退料
     * @param bean
     * @return
     */
    @Override
    public AjaxResult submitOcrBack(MachineOcrBean bean) {
        int res = 0;
        try {
            String taskId = bean.getTaskId();
            // ---------↓-----bpm_example修改状态发料进行中---↓---------
            //res = updateTaskStatus(bean,taskId);
            String maId = bean.getMaId();
            MachineVo ma = machineMapper.selectMachineByMaId(Long.parseLong(maId));
            if (ma != null) {
                // ---------↓-----bpm_pick_form修改数据---↓-----------------
                //res = updateFormData(bean,taskId,pickId);

                // ---------↓-----ma_machine修改状态---↓----bpm_pick_form_details插入数据--↓-------------
                ma.setMaStatus("1");
                res = updateMaStatus(bean, ma, taskId);

                if (res > 0) {
                    // ---------↓-----ma_machine_type修改库存，在库---↓---------
                    res = updateStorageDataBack(bean, taskId);
                    if (res > 0) {
                        log.info("maId:" + maId + "出库成功！");
                    } else {
                        throw new RuntimeException("修改ma_machine_type信息失败!");
                    }
                } else {
                    throw new RuntimeException("修改ma_machine信息失败!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (res > 0) {
            return AjaxResult.success("退料成功");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 获取ocr编码
     * @param bean
     * @return
     */
    @Override
    public AjaxResult getOcrCode(MachineOcrBean bean) {
        String url = "http://10.138.55.102:10000/api/jdx_scq";
        JSONObject js = null;
        try {
            System.out.println("ocr-base64数据:" + bean.getImage());
            String jsonStr = JSONObject.toJSONString(bean);
            String data = HttpHelper.sendHttpPostForToken(url, jsonStr);
            System.out.println("ocr返回数据:" + data);
            js = JSONObject.parseObject(data);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取OCR编码失败:" + e.getMessage());
        }
        return AjaxResult.success(js);
    }

    @Override
    public AjaxResult getOcrCodeTwo(MachineOcrBean bean) {
        String url = "http://10.138.55.102:10000/api_gqj/pre";
        JSONObject js = null;
        try {
            System.out.println("ocr-base64数据:" + bean.getImage());
            String jsonStr = JSONObject.toJSONString(bean);
            String data = HttpHelper.sendHttpPostForToken(url, jsonStr);
            System.out.println("ocr返回数据:" + data);
            js = JSONObject.parseObject(data);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取OCR编码失败:" + e.getMessage());
        }
        return AjaxResult.success(js);
    }

    /**
     * 推送设备至第三方入库
     * @param bean
     * @return
     */
    @Override
    public AjaxResult addDeviceNumber(MachineOcrBean bean) {
        if (bean == null) {
            return AjaxResult.error(HttpCodeEnum.TO_PARAM_NULL.getCode(), HttpCodeEnum.TO_PARAM_NULL.getMsg());
        }
        String deviceNumber = bean.getDeviceNumber();
        if (deviceNumber != null) {
            String url = "http://10.138.55.102:10000/api_ruku_1/bianma_add";
            JSONObject obj = ofObject(deviceNumber);
            try {
                String objJSONString = JSONObject.toJSONString(obj);
                String result = HttpHelper.sendHttpPostForToken(url, objJSONString);
                if (result != null) {
                    obj = JSONObject.parseObject(result);
                    if (obj.getInteger("code") == 0) {
                        // Java8 CompletableFuture异步工具类 ---- 推送nginx
                        CompletableFuture.runAsync(() -> {
                            // 输出异步执行的线程名称
                            System.out.println("Executing task in thread: " + Thread.currentThread().getName());
                            // 执行异步任务
                            pushNginxByDeviceNumber(deviceNumber);
                            // 异步任务执行结束
                            System.out.println("Task completed.");
                        });
                        return AjaxResult.success("设备编号添加成功");
                    } else {
                        return AjaxResult.error("设备编号添加失败,外部接口调用返回内容:" + obj.getString("msg"));
                    }
                } else {
                    return AjaxResult.error("设备编号添加失败,外部接口调用返回内容为null");
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            return AjaxResult.error("设备编号不能为空");
        }
    }

    /**
     * 循环10次请求nginx
     * @param deviceNumber
     * @return
     */
    private static boolean pushNginxByDeviceNumber(String deviceNumber) {
        boolean isSuccess = true;
        String url = "http://10.138.55.102:10000/api_ruku_1/bianma_reload";
        JSONObject obj = ofObject(deviceNumber);
        String objJsonString = JSONObject.toJSONString(obj);
        for (int i = 0; i < 10; i++) {
            try {
                String result = HttpHelper.sendHttpPostForToken(url, objJsonString);
                if (result != null) {
                    obj = JSONObject.parseObject(result);
                    if (obj.getInteger("code") != 0) {isSuccess = false;}
                } else {
                    isSuccess = false;
                }
                // 暂停3秒
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("线程被中断: " + e.getMessage());
            } catch (Exception e){
                throw new RuntimeException(e);
            }
        }
        System.out.println("nginx推送结果:" + isSuccess);
        return isSuccess;
    }

    /**
     * 方法抽取
     * @param deviceNumber
     * @return
     */
    private static JSONObject ofObject(String deviceNumber) {
        JSONObject obj = new JSONObject();
        obj.put("table_name", "bianmaku_1");
        obj.put("name", "1");
        obj.put("type", "2");
        obj.put("number", deviceNumber);
        return obj;
    }

    /**
     * 修改ma_machine_type库存，在库
     * @param bean
     * @param taskId
     * @return
     */
    private int updateStorageDataBack(MachineOcrBean bean, String taskId) {
        bean.setBackNum("1");
        return appOcrMapper.updateStorageDataBack(bean);
    }
}
