package com.ssj.service.sys.picturepredeal.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ssj.bean.kmt.kmt.domain.KmtExerciseBook;
import com.ssj.bean.kmt.kmt.domain.QuestionRecommendRecord;
import com.ssj.bean.sys.homework.domain.HomeworkPicture;
import com.ssj.bean.sys.picturepredeal.domain.PicturePreDeal;
import com.ssj.bean.weixin.libmy.domain.LibVip;
import com.ssj.bean.weixin.libmy.domain.TbLibManager;
import com.ssj.conch.push.util.PushConstants;
import com.ssj.conch.util.AIServiceUtils;
import com.ssj.dao.sys.picturepredeal.dao.PicturePreDealDao;
import com.ssj.enums.XinGePushBusinessTypeEnum;
import com.ssj.enums.XinGePushMessageTypeEnum;
import com.ssj.framework.basic.utils.StringUtils;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.rabbitmq.TopicRabbitConfig;
import com.ssj.framework.core.rabbitmq.producer.BaseRabbitSend;
import com.ssj.framework.core.util.OSSUtils;
import com.ssj.framework.core.util.PropertiesUtil;
import com.ssj.framework.core.util.ResponseEntity;
import com.ssj.framework.core.util.StringUtil;
import com.ssj.framework.weixin.util.DateUtil;
import com.ssj.service.ai.model.HomeworkPicturePreDeal;
import com.ssj.service.conch.teacher.service.TeacherService;
import com.ssj.service.kmt.request.AnswerSearchV2Request;
import com.ssj.service.kmt.request.SubmitQueryViaOssResultRequest;
import com.ssj.service.kmt.service.KmtExerciseBookService;
import com.ssj.service.kmt.service.KmtExerciseQuestionService;
import com.ssj.service.kmt.service.QuestionRecommendRecordService;
import com.ssj.service.mapper.KmtExerciseMapper;
import com.ssj.service.sys.homework.service.HomeworkPictureService;
import com.ssj.service.sys.picturepredeal.request.RecognitionResultReq;
import com.ssj.service.sys.picturepredeal.service.PicturePreDealService;
import com.ssj.service.sys.push.service.SconXingeService;
import com.ssj.service.weixin.library.service.IBookManagerService;
import com.ssj.service.weixin.library.service.ILibVipService;
import com.ssj.service.weixin.sales.service.LibVipServiceService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

@Service(version = "1.0")
@Transactional
public class PicturePreDealServiceImpl extends BaseServiceImpl<PicturePreDeal, String> implements PicturePreDealService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private PicturePreDealDao picturePreDealDao;
    @Autowired
    private ILibVipService vipService;


    @Autowired
    private LibVipServiceService libVipServiceService;

    @Autowired
    private SconXingeService sconXingeService;

    @Autowired
    private IBookManagerService managerService;

    @Autowired
    private HomeworkPictureService homeworkPictureService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private KmtExerciseQuestionService kmtExerciseQuestionService;
    @Autowired
    private QuestionRecommendRecordService questionRecommendRecordService;

    @Autowired
    private KmtExerciseMapper kmtExerciseMapper;

    @Autowired
    private KmtExerciseBookService kmtExerciseBookService;

    //private ExecutorService executor = Executors.newFixedThreadPool(10);

    @Override
    public PagingAndSortingRepository<PicturePreDeal, String> getDao() {
        return picturePreDealDao;
    }

    @Override
    public void postRequest2AI(HomeworkPicturePreDeal homeworkPicturePreDeal) {
        try {
            Thread.sleep(500);
        } catch (Exception e){
        }
        HomeworkPicture homeworkPicture = homeworkPicturePreDeal.getHomeworkPicture();
        if(!OSSUtils.doesObjectExist(homeworkPicture.getFileKey())){
            logger.error("{}图片不存在", homeworkPicture.getId());
        }
        if (!this.getRource(PropertiesUtil.getValue("OSS_INTERNAL_PATH") + homeworkPicture.getFileKey())){
            try {
                Thread.sleep(2000);
            } catch (Exception e){
                logger.error("睡眠异常", e);
            }
        }

        PicturePreDeal preDeal = homeworkPicturePreDeal.getPicturePreDeal();
        String result = null;
        LibVip vip = vipService.getById(homeworkPicture.getVipId());
        Map<String,String> querys=new HashMap<String, String>();
        String filePathPrefix = PropertiesUtil.getValue("file_save_path");
        if ("2".equals(PropertiesUtil.getValue("SYS_ENV"))){
            filePathPrefix = PropertiesUtil.getValue("AI_TEST_SAVE_PATH");
        }
        querys.put("path", filePathPrefix + homeworkPicture.getFileKey());
        querys.put("ossPath", PropertiesUtil.getValue("OSS_INTERNAL_PATH") + homeworkPicture.getFileKey());
        querys.put("subject", homeworkPicture.getSubject());
        int semester = Integer.parseInt(PropertiesUtil.getValue("semester"));
        querys.put("grade", vip.getGrade() + (semester == 1 ? "上册"  : "下册"));
        querys.put("version", "");
        querys.put("mode", "question");
        try {
            if (preDeal == null){
                preDeal = new PicturePreDeal();
                preDeal.setHomeworkPictureId(homeworkPicture.getId());
                preDeal.setCreateTime(new Date());
            }
            preDeal.setTaskStatus(0);
            preDeal.setDealFlag(0);
            preDeal.setBookId(null);
            preDeal.setUnitId(null);
            preDeal.setBookPageNo(null);
            preDeal.setPath(null);
            preDeal.setRequestType(1);
            logger.info("{}开始请求接口,入参{}", homeworkPicture.getId(),querys);
            result = AIServiceUtils.recognitionExerciseBookV1(querys);
            preDeal.setResponse(result);
            logger.info("{}AI返回的结果{}", homeworkPicture.getId(), result);
            if(result != null) {
                this.recordPostRequestData(preDeal, result);
            }
            //this.saveHomeworkPicturePreDealResult(homeworkPicture, preDeal);
        } catch (Exception e){
            logger.error("请求ai识别图片异常", e);
            preDeal.setTaskStatus(2);
            preDeal.setResponse(e.getMessage());
        }
        this.save(preDeal);

    }

    /**
     * 判断作业图片是否存在
     * @param source
     * @return
     */
    private boolean getRource(String source) {
        try {
            URL url = new URL(source);
            URLConnection uc = url.openConnection();
            InputStream in = uc.getInputStream();
            if (source.equalsIgnoreCase(uc.getURL().toString()))
                in.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 记录发送ai的请求信息
     */
    private void recordPostRequestData (PicturePreDeal preDeal, String responseStr) {

        JSONObject jsonObject = JSON.parseObject(responseStr);
        if ("success".equals(jsonObject.getString("status"))){
            int flag = jsonObject.getInteger("flag");
            JSONObject data = jsonObject.getJSONObject("data");
            preDeal.setDealFlag(flag);
            preDeal.setTaskStatus(1);
            preDeal.setUpdateTime(new Date());
            if (flag == 1) {
                String path = data.getString("path");
                if (StringUtils.isNotBlank(path)){
                    String filePathPrefix = PropertiesUtil.getValue("file_save_path");
                    if ("2".equals(PropertiesUtil.getValue("SYS_ENV"))){
                        filePathPrefix = PropertiesUtil.getValue("AI_TEST_SAVE_PATH");
                    }
                    //上传oss
                    String ps = OSSUtils.uploadFile(path.replaceFirst(filePathPrefix, PropertiesUtil.getValue("file_save_path")),
                            path.replaceFirst(filePathPrefix + "/",""));
                    logger.info("{}阿里oss返回的路径={}", preDeal.getHomeworkPictureId(), ps);
                    preDeal.setPath(path.replaceFirst(filePathPrefix, ""));
                }
            }
            preDeal.setBookId(data.getString("book_id"));
            preDeal.setUnitId(data.getString("module_id"));
            preDeal.setModuleId(data.getString("unit_id"));
            preDeal.setQuestionIds(data.getString("question_ids"));
            if (data.getJSONArray("page_no") != null){
                preDeal.setBookPageNo(data.getJSONArray("page_no").toString());
            }

            //有book_id，更新识别次数
            if (StringUtil.isNotBlank(preDeal.getBookId())){
                //查询book_id的所有book记录
                List<KmtExerciseBook> exerciseBooks  = kmtExerciseMapper.findExerciseBooksByBookId(preDeal.getBookId());
                if (CollectionUtils.isNotEmpty(exerciseBooks)){
                    for (KmtExerciseBook book : exerciseBooks){
                        //修改识别次数
                        book.setIdentifiedNums(book.getIdentifiedNums() + 1);
                    }
                    kmtExerciseBookService.save(exerciseBooks);
                }
            }
        } else {
            preDeal.setTaskStatus(2);
            preDeal.setDealFlag(0);
            logger.warn("ai请求返回失败{}, 失败数据{}", preDeal.getHomeworkPictureId(), responseStr);
        }
    }

    private void saveHomeworkPicturePreDealResult(HomeworkPicture homeworkPicture, PicturePreDeal preDeal){
        if (preDeal.getTaskStatus() == 1 && preDeal.getDealFlag() != 0){
            AnswerSearchV2Request request = new AnswerSearchV2Request();
            request.setBookId(preDeal.getBookId());
            request.setUnitId(preDeal.getUnitId());
            request.setPeriodId(preDeal.getModuleId());
            if (StringUtil.isNotBlank(preDeal.getBookPageNo())){
                JSONArray pageNoArray = JSON.parseArray(preDeal.getBookPageNo());
                request.setPageIndexs(pageNoArray.toJavaList(Integer.class));
            }
            boolean isNotPublish = kmtExerciseQuestionService.findIsNotPublish(request);
            if (!isNotPublish){
                homeworkPicture.setIsNeedingKnow(0);
                homeworkPictureService.save(homeworkPicture);
            }
        }

    }

    public  void afterAiSetTeacherId(HomeworkPicture homeworkPicture,int correctType){
        //如果没有作业吧服务则不分配老师
        Date finishDate = new Date();
        int count = libVipServiceService.checkIsZybServiceByVipId(homeworkPicture.getVipId());
        if (count > 0) {
            homeworkPicture.setAllotTime(finishDate);
            String homeworkTeacherId = teacherService.getHomeworkTeacherId(homeworkPicture.getVipId(), homeworkPicture.getSubject());
            homeworkPicture.setTeacherId(homeworkTeacherId);
            homeworkPictureService.save(homeworkPicture);
            if (org.apache.commons.lang3.StringUtils.isNotBlank(homeworkTeacherId)) {
                //更新选定批改老师的实时权重和批改图片总数
                managerService.updateCorrectHomeworkNum(homeworkPicture.getVipId(), homeworkTeacherId, 1);
            }
        }
        HomeworkPicture  lastHomeworkPicture=null;
        List<HomeworkPicture> list = homeworkPictureService.findLastTowByHomeworkId(homeworkPicture.getHomeworkId());
        //判断是否需要推送提醒，只在第一次上传图片或间隔超过10分钟才会推送提醒给批改老师
        boolean needSendNotice = false;
        if (list.size()==1) {
            //第一张图片，需要推送提醒
            needSendNotice = true;
        } else {
            lastHomeworkPicture = list.get(1);
            long lastPictureCreateTime = lastHomeworkPicture.getCreateTime().getTime();
            long newPictureCreateTime = homeworkPicture.getCreateTime().getTime();
            if (newPictureCreateTime - lastPictureCreateTime > 10 * 60 * 1000) {
                //距离上一次上传大于10分钟，需要推送提醒
                needSendNotice = true;
            }
        }

        //给线上批改的老师推送消息
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(homeworkPicture.getVipId()) && org.apache.commons.lang3.StringUtils.isNotEmpty(homeworkPicture.getTeacherId())){
            homeworkPictureService.sendMsg4SubmitWork(homeworkPicture.getVipId(), homeworkPicture.getTeacherId());
        }

        //推送提醒给在线批改老师
        if (needSendNotice) {
            logger.info("给批改老师推送提醒，推送开始");
            LibVip student = vipService.getById(homeworkPicture.getVipId());
            if (student != null){
                homeworkPictureService.sendTempMsg2OnlineTeacher(homeworkPicture.getTeacherId(), student.getChildName(), finishDate,homeworkPicture.getSubject());

                List<TbLibManager> libManagerList = managerService.findByUserIdAndTypeIn(homeworkPicture.getTeacherId(), new int[]{8, 11});
                if (CollectionUtils.isNotEmpty(libManagerList)) {
                    TbLibManager correctTeacher = libManagerList.get(0);
                    String content = "尊敬的" + correctTeacher.getName() + "老师，您负责的" + student.getChildName() + "学生，已经于" + DateUtil.dateTimeToString(finishDate) + "时间完成" + homeworkPicture.getSubject() + "作业，请您尽快完成作业批改！";
                    this.sconXingeService.asynPushThreadTask(homeworkPicture.getTeacherId(), 4, XinGePushMessageTypeEnum.Message.getCode(), XinGePushBusinessTypeEnum.HomeworkCorrectNotice.getCode(), "作业批改提醒", content, "APP_TEACHER", PushConstants.PUSH_OTHER);
                }
            } else {
                logger.error("找不到学生记录，没有推送， vipId={}", homeworkPicture.getVipId());
            }
            logger.info("给批改老师推送提醒，推送结束");
        }
    }
    @Override
    public void asyncPostRequest2AI(HomeworkPicture homeworkPicture){
        PicturePreDeal preDeal = this.findPreDealByHomeworkPictureId(homeworkPicture.getId());
        if (preDeal == null){
            preDeal = new PicturePreDeal();
            preDeal.setHomeworkPictureId(homeworkPicture.getId());
            preDeal.setCreateTime(new Date());
        }
        preDeal.setTaskStatus(0);
        preDeal.setDealFlag(0);
        preDeal.setBookId(null);
        preDeal.setUnitId(null);
        preDeal.setBookPageNo(null);
        preDeal.setPath(null);
        preDeal.setRequestType(1);
        preDeal = this.save(preDeal);
        HomeworkPicturePreDeal homeworkPicturePreDeal = new HomeworkPicturePreDeal();
        homeworkPicturePreDeal.setHomeworkPicture(homeworkPicture);
        homeworkPicturePreDeal.setPicturePreDeal(preDeal);
        String uuid=BaseRabbitSend.convertAndTopicSend(
				TopicRabbitConfig.exchange_aijia,
				TopicRabbitConfig.topic_homework_discern,
                homeworkPicturePreDeal);
		logger.error("作业图片识别已加入推送信息队列数据uuid："+uuid+" data:"+JSONObject.toJSONString(homeworkPicturePreDeal));
    }

    @Override
    public PicturePreDeal findPreDealByHomeworkPictureId(String homeworkPictureId) {
        return picturePreDealDao.findByHomeworkPictureId(homeworkPictureId);
    }

    @Override
    public ResponseEntity findRecognitionResult(RecognitionResultReq req) {
        ResponseEntity responseEntity = new ResponseEntity();
        Map<String, Object> resultMap = new HashMap<>();
        int discernType = 2;
        String bookId = "";
        String unitId = "";
        String periodId = "";
        Object [] questionIds = new Object[]{};
        Object [] pageIndexs = new Object[]{};

        PicturePreDeal picturePreDeal = this.findPreDealByHomeworkPictureId(req.getHomeworkPictureId());
        if (picturePreDeal != null) {
            //查询到识别记录
            if (Objects.equals(1, picturePreDeal.getTaskStatus())) {
                //ai已返回识别结果
                if (picturePreDeal.getDealFlag() > 0) {
                    //匹配到练习册
                    discernType = 1;
                    bookId = picturePreDeal.getBookId();
                    unitId = picturePreDeal.getUnitId();
                    periodId = picturePreDeal.getModuleId();
                    if (org.apache.commons.lang3.StringUtils.isNotBlank(picturePreDeal.getBookPageNo())) {
                        pageIndexs = JSON.parseArray(picturePreDeal.getBookPageNo()).toArray();
                    }
                    if (StringUtil.isNotBlank(picturePreDeal.getQuestionIds())){
                        questionIds = JSON.parseArray(picturePreDeal.getQuestionIds()).toArray();
                    }
                } else {
                    //未匹配到练习册
                    discernType = 3;
                }
            } else {
                //识别中或识别失败
                discernType = picturePreDeal.getTaskStatus();
            }
        }

        if (discernType != 1) {
            //未从ai识别中获取到答案信息，校验是否学期回顾题目图片，如果是则尝试从题目推荐记录获取答案信息
            HomeworkPicture homeworkPicture = homeworkPictureService.getById(req.getHomeworkPictureId());
            if (homeworkPicture != null && StringUtils.isNotBlank(homeworkPicture.getQuestionRecommendRecordId())) {
                QuestionRecommendRecord questionRecommendRecord =
                        questionRecommendRecordService.getById(homeworkPicture.getQuestionRecommendRecordId());
                if (questionRecommendRecord != null) {
                    discernType = 1;
                    String questionIdListJson = Optional.ofNullable(questionRecommendRecord.getQuestionIdListJson())
                            .orElse("[]");
                    questionIds = JSON.parseArray(questionIdListJson).toArray();
                    bookId = "semester_review";
                    pageIndexs = new Object[]{1};
                }
            }
        }

        resultMap.put("discernType", discernType);
        resultMap.put("bookId", bookId);
        resultMap.put("unitId", unitId);
        resultMap.put("periodId", periodId);
        resultMap.put("pageIndexs", pageIndexs);
        resultMap.put("questionIds", questionIds);

        return responseEntity.success(resultMap, "查询成功");
    }


    @Override
    public void postRequest2AIV1 (HomeworkPicturePreDeal homeworkPicturePreDeal) {
        try {
            Thread.sleep(500);
        } catch (Exception e){
        }
        HomeworkPicture homeworkPicture = homeworkPicturePreDeal.getHomeworkPicture();
        if (!this.getRource(PropertiesUtil.getValue("OSS_INTERNAL_PATH") + homeworkPicture.getFileKey())){
            try {
                Thread.sleep(2000);
            } catch (Exception e){
                logger.error("睡眠异常", e);
            }
        }

        PicturePreDeal preDeal = homeworkPicturePreDeal.getPicturePreDeal();
        String result = null;
        LibVip vip = vipService.getById(homeworkPicture.getVipId());
        Map<String,String> querys=new HashMap<String, String>();
        String filePathPrefix = PropertiesUtil.getValue("file_save_path");
        querys.put("requestMethod", "https://api.sharingschool.com/sz/api/kmt/exercise/submitQueryViaOssResult");

        if ("2".equals(PropertiesUtil.getValue("SYS_ENV"))){
            filePathPrefix = PropertiesUtil.getValue("AI_TEST_SAVE_PATH");
            querys.put("requestMethod", "https://xt.sharingschool.com/sz/api/kmt/exercise/submitQueryViaOssResult");
        }
        querys.put("taskId", preDeal.getId());
        querys.put("path", filePathPrefix + homeworkPicture.getFileKey());
        querys.put("ossPath", PropertiesUtil.getValue("OSS_INTERNAL_PATH") + homeworkPicture.getFileKey());
        querys.put("subject", homeworkPicture.getSubject());
        int semester = Integer.parseInt(PropertiesUtil.getValue("semester"));
        querys.put("grade", vip.getGrade() + (semester == 1 ? "上册"  : "下册"));
        querys.put("version", "");
        querys.put("mode", "question");
        try {
            logger.info("{}开始请求接口,入参{}", homeworkPicture.getId(),querys);
            result = AIServiceUtils.recognitionExerciseBookV2(querys);
            preDeal.setResponse(result);
            logger.info("{}AI请求发送的结果{}", homeworkPicture.getId(), result);
        } catch (Exception e){
            logger.error("AI请求异常", e);
        }
    }

    @Override
    public ResponseEntity submitQueryViaOssResult(SubmitQueryViaOssResultRequest request) {
        ResponseEntity responseEntity = new ResponseEntity();
        String requestJSON = JSONObject.toJSONString(request);
        logger.error("作业识别结果={}", requestJSON);
        PicturePreDeal preDeal = picturePreDealDao.findOne(request.getTaskId());
        if (preDeal != null){
            preDeal.setTaskStatus(1);
            preDeal.setDealFlag(request.getFlag());
            preDeal.setUpdateTime(new Date());
            preDeal.setResponse(requestJSON);
            if (request.getFlag() == 1){
                String path = request.getPath();
                if (StringUtils.isNotBlank(path)){
                    String filePathPrefix = PropertiesUtil.getValue("file_save_path");
                    if ("2".equals(PropertiesUtil.getValue("SYS_ENV"))){
                        filePathPrefix = PropertiesUtil.getValue("AI_TEST_SAVE_PATH");
                    }
                    //上传oss
                    String ps = OSSUtils.uploadFile(path.replaceFirst(filePathPrefix, PropertiesUtil.getValue("file_save_path")),
                            path.replaceFirst(filePathPrefix + "/",""));
                    logger.info("{}阿里oss返回的路径={}", preDeal.getHomeworkPictureId(), ps);
                    preDeal.setPath(path.replaceFirst(filePathPrefix, ""));
                }
            }
            preDeal.setBookId(request.getBookId());
            preDeal.setExerciseBookId(JSON.toJSONString(request.getExerciseBookId()));
            preDeal.setUnitId(request.getModuleId());
            preDeal.setModuleId(request.getUnitId());
            if (CollectionUtils.isNotEmpty(request.getQuestionIds())){
                preDeal.setQuestionIds(JSONObject.toJSONString(request.getQuestionIds()));
            }
            if (CollectionUtils.isNotEmpty(request.getPageNo())){
                preDeal.setBookPageNo(JSONObject.toJSONString(request.getPageNo()));
            }

            //有book_id，更新识别次数
            if (StringUtil.isNotBlank(preDeal.getExerciseBookId())){
                //查询book_id的所有book记录
                KmtExerciseBook exerciseBook  = kmtExerciseBookService.getById(preDeal.getExerciseBookId());
                if (exerciseBook != null){
                    exerciseBook.setIdentifiedNums(exerciseBook.getIdentifiedNums() + 1);
                    kmtExerciseBookService.save(exerciseBook);
                }
            }
            this.save(preDeal);
        } else {
            logger.error("ai识别结果异常，找不到记录");
        }
        return responseEntity.success("成功");
    }
}
