package com.xhkjedu.sapi.service.cloud;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.sapi.config.ConfigKey;
import com.xhkjedu.sapi.mapper.cloud.CloudSyncDetailMapper;
import com.xhkjedu.sapi.mapper.cloud.CloudSyncMapper;
import com.xhkjedu.sapi.model.cloud.TCloudSync;
import com.xhkjedu.sapi.model.cloud.TCloudSyncDetail;
import com.xhkjedu.sapi.utils.ApiUtil;
import com.xhkjedu.sapi.utils.CopyURL;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.vo.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author ywx
 * @classname CloudSyncService
 * @description 
 * @date 2021/5/6 15:48
 **/
@Service
@Slf4j
public class CloudSyncService {
    @Resource
    private CloudSyncMapper cloudSyncMapper;
    @Resource
    private CloudSyncDetailMapper cloudSyncDetailMapper;

    //列表
    public List<Map> findAll(TCloudSync sync) {
        return cloudSyncMapper.findAll(sync);
    }

    //添加
    public void save(TCloudSync model) {
        model.setCreatetime(N_Utils.getSecondTimestamp());
        cloudSyncMapper.insertSelective(model);
    }

    //同步基础信息、试题、资源
    public synchronized ResultVo sync(TCloudSync sync) {
        TCloudSync lastSync = cloudSyncMapper.getLastSync();
        Integer csid;
        List<TCloudSyncDetail> details = null;
        if (lastSync == null || lastSync.getSyncstate() == 1 || lastSync.getSynctask() == 0) {
            String cloudcode = sync.getCloudcode();
            Integer begintime = lastSync==null?null:lastSync.getEndtime();
            Map map = new HashMap();
            map.put("cloudcode", cloudcode);
            map.put("begintime", begintime);
            //同步所有基本信息
            //map.put("modules", sync.getModules());
            String param = JSON.toJSONString(map);
            //同步任务
            ResultVo vo = getResultVo("csync/g",param);
            if (vo.getCode() != 0) return vo;
            TCloudSync cloudSync = JSON.parseObject(JSON.toJSONString(vo.getObj()),TCloudSync.class);
            csid = cloudSync.getCsid();
            cloudSync.setCreateid(sync.getCreateid());
            if (cloudSync.getSynctask() == 1) {
                cloudSync.setStarttime(N_Utils.getSecondTimestamp());
            }
            cloudSyncMapper.save(cloudSync);

            //同步任务详情
            details = cloudSync.getSyncdetails();
            if (N_Utils.isListNotEmpty(details)) {
                cloudSyncDetailMapper.batchSave(details,csid,sync.getCreateid());
            }
        } else {
            csid = lastSync.getCsid();
            if (lastSync.getSynctask() == 1) {
                details = cloudSyncDetailMapper.listByCsId(csid);
            }
        }

        ResultVo vo = syncDetail(details, csid, sync.getSyncnum());
        if (vo != null) return vo;

        return new ResultVo(0,"同步成功");
    }

    //调用云平台接口
    private ResultVo getResultVo(String url, String param) {
        String result = N_Utils.sendJsonPost(ConfigKey.cloudapi + url, param);
        ResultVo vo = JSON.parseObject(result, ResultVo.class);
        return vo;
    }

    //同步任务详情
    private ResultVo syncDetail(List<TCloudSyncDetail> details, Integer csid, Integer syncnum) {
        if (N_Utils.isListEmpty(details)) return null;
        for (TCloudSyncDetail detail : details) {
            detail.setSyncnum(syncnum);
            Integer realnum = detail.getRealnum();
            ResultVo vo = getResultVo("csync/s",JSON.toJSONString(detail));//获取同步数据
            if (vo.getCode() != 0) return vo;
            String endid = detail.getEndid();
            List<Map> list = (List<Map>) vo.getObj();
            realnum += list.size();
            String synctable = detail.getSynctable();
            if (synctable.equals("t_director")) {
                Integer fkExisted = cloudSyncMapper.getFkExisted("fk_directorpid", ConfigKey.dbname);
                if (!N_Utils.isEmptyInteger(fkExisted)) {
                    cloudSyncMapper.delDirectorFk();//删除章节外键
                }
            } else if (synctable.equals("t_point")) {
                Integer fkExisted = cloudSyncMapper.getFkExisted("fk_pointpid", ConfigKey.dbname);
                if (!N_Utils.isEmptyInteger(fkExisted)) {
                    cloudSyncMapper.delPointFk();//删除知识点外键
                }
            }
            String handleid = syncList(detail, list);
            while (handleid != null && !endid.equals(handleid)) {
                detail.setHandleid(handleid);
                detail.setRealnum(realnum);
                vo = getResultVo("csync/s",JSON.toJSONString(detail));//获取同步数据
                if (vo.getCode() != 0) return vo;
                list = (List<Map>) vo.getObj();
                realnum += list.size();
                handleid = syncList(detail,list);
            }
            if (synctable.equals("t_director")) {
                cloudSyncMapper.addDirectorFk();//添加章节外键
            } else if (synctable.equals("t_point")) {
                cloudSyncMapper.addPointFk();//添加知识点外键
            }
        }

        Integer num = cloudSyncDetailMapper.countNoEndByCsId(csid);//获取未执行完成的任务详情数量
        if (num == 0) cloudSyncMapper.updateState(csid, 1, N_Utils.getSecondTimestamp());
        return null;
    }

    //同步任务详情数据
    private String syncList(TCloudSyncDetail detail, List<Map> list) {
        String synctable = detail.getSynctable();
        String handleid = null;
        int syncnum = list.size();
        List<String> files = new ArrayList<>();
        try {
            if (synctable.equals("t_subject")) {//同步科目
                handleid = (String) list.get(list.size()-1).get("subjectid");
                cloudSyncMapper.syncSubject(list, N_Utils.getSecondTimestamp());
            } else if (synctable.equals("t_version")) {//同步版本
                handleid = (String) list.get(list.size()-1).get("versionid");
                cloudSyncMapper.syncVersion(list, N_Utils.getSecondTimestamp());
            } else if (synctable.equals("t_subject_book")) {//同步教材
                handleid = (String) list.get(list.size()-1).get("lsbid");
                for (Map sb : list) {
                    String coverpath = (String) sb.get("coverpath");
                    files.add(coverpath);//教材封面图
                }
                cloudSyncMapper.syncSubjectBook(list, N_Utils.getSecondTimestamp());
            } else if (synctable.equals("t_subject_questiontype")) {//同步题型
                handleid = (String) list.get(list.size()-1).get("qtypeid");
                cloudSyncMapper.syncSubjectQuestionType(list, N_Utils.getSecondTimestamp());
            } else if (synctable.equals("t_director")) {//同步章节
                handleid = (String) list.get(list.size()-1).get("directorid");
                cloudSyncMapper.syncDirector(list, N_Utils.getSecondTimestamp());
            } else if (synctable.equals("t_point")) {//同步知识点
                handleid = (String) list.get(list.size()-1).get("pointid");
                cloudSyncMapper.syncPoint(list, N_Utils.getSecondTimestamp());
            } /*else if (synctable.equals("t_question")) {//同步试题
                handleid = (String) list.get(list.size()-1).get("questionid");
                for (Map question : list) {
                    Integer ctype = (Integer) question.get("ctype");
                    String qstem = (String) question.get("qstem");
                    String questionid = (String) question.get("questionid");
                    question.put("qstate",1);
                    try {
                        files.addAll(CopyURL.getImgSrc2(qstem));//题干图片
                        question.put("qstem",qstem.replaceAll(ConfigKey.oldshowurl,ConfigKey.showurl));
                        if (ctype == 1 || ctype == 2) {//单选题、多选题
                            String qoption = (String) question.get("qoption");
                            files.addAll(CopyURL.getImgSrc2(qoption));//选项图片
                            question.put("qoption",qoption.replaceAll(ConfigKey.oldshowurl,ConfigKey.showurl));
                        }
                        if (ctype == 3) {//主观题
                            String qanswer = (String) question.get("qanswer");
                            files.addAll(CopyURL.getImgSrc2(qanswer));//答案图片
                            question.put("qanswer",qanswer.replaceAll(ConfigKey.oldshowurl,ConfigKey.showurl));
                        }
                        String qanalyze = (String) question.get("qanalyze");
                        files.addAll(CopyURL.getImgSrc2(qanalyze));//解析图片
                        question.put("qanalyze",qanalyze.replaceAll(ConfigKey.oldshowurl,ConfigKey.showurl));
                        cloudSyncMapper.syncQuestion(question, N_Utils.getSecondTimestamp());
                        try {
                            List<Map> points = (List<Map>) question.get("pointlist");
                            if (N_Utils.isListNotEmpty(points)) cloudSyncMapper.syncQuestionPoint(points, N_Utils.getSecondTimestamp());
                        } catch (Exception e) {
                            log.error("同步【t_question_point "+questionid+"】失败",e.getMessage());
                        }
                        try {
                            List<Map> directors = (List<Map>) question.get("dirlist");
                            if (N_Utils.isListNotEmpty(directors)) cloudSyncMapper.syncQuestionDirector(directors, N_Utils.getSecondTimestamp());
                        } catch (Exception e) {
                            log.error("同步【t_question_director "+questionid+"】失败",e.getMessage());
                        }
                    } catch (Exception e) {
                        syncnum--;
                        log.error("同步【"+synctable+" "+questionid+"】失败",e.getMessage());
                    }
                }
            } else if (synctable.equals("t_resource")) {//同步资源
                handleid = (String) list.get(list.size()-1).get("resourceid");
                for (Map resource : list) {
                    String resourceid = (String) resource.get("resourceid");
                    String resourceurl = (String) resource.get("resourceurl");
                    String pdfurl = (String) resource.get("pdfurl");
                    String resourcecover = (String) resource.get("resourcecover");
                    resource.put("resourcestate",1);
                    try {
                        if (N_Utils.isNotEmpty(resourceurl)) {//资源文件
                            files.add(resourceurl);
                        }
                        if (N_Utils.isNotEmpty(pdfurl)) {//pdf文件
                            files.add(pdfurl);
                        }
                        if (N_Utils.isNotEmpty(resourcecover)) {//视频封面图
                            files.add(resourcecover);
                        }
                        cloudSyncMapper.syncResource(resource, N_Utils.getSecondTimestamp());
                        try {
                            List<Map> directors = (List<Map>) resource.get("dirlist");
                            if (N_Utils.isListNotEmpty(directors)) cloudSyncMapper.syncResourceDirector(directors, N_Utils.getSecondTimestamp());
                        } catch (Exception e) {
                            log.error("同步【t_resource_director "+resourceid+"】失败",e.getMessage());
                        }
                    } catch (Exception e) {
                        syncnum--;
                        log.error("同步【"+synctable+" "+resourceid+"】失败",e.getMessage());
                    }
                }
            }*/

        } catch (Exception e) {
            syncnum--;
            log.error("同步【"+synctable+"】失败",e.getMessage());
        }

        if (N_Utils.isListNotEmpty(files)) {//复制文件
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("filepaths",JSON.toJSONString(files));
            String apiUrl = ConfigKey.fileapi + "dn/down_files";
            ApiUtil.sendFormData(apiUrl,map);
        }

        //更新已同步数量
        if (N_Utils.isEmpty(detail.getHandleid())) {
            detail.setStarttime(N_Utils.getSecondTimestamp());
        }
        if (detail.getEndid().equals(handleid)) {
            detail.setStoptime(N_Utils.getSecondTimestamp());
        }
        detail.setRealnum(syncnum);
        detail.setHandleid(handleid);
        cloudSyncDetailMapper.updateRealNum(detail);
        return handleid;
    }

    public TCloudSync getCloudInfo() {
        return cloudSyncMapper.getCloudInfo();
    }

    /**
     * @Description 获取同步类型
     * @Date 2023/10/13 15:15
     * @Author YWX
     * @Param []
     * @Return com.xhkjedu.vo.ResultVo
     **/
    public ResultVo listModule() {
        return new ResultVo(0, "获取同步类型成功！", cloudSyncMapper.listModule());
    }
}
