package com.ruoyi.biemo.business.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.corpus.document.sentence.Sentence;
import com.hankcs.hanlp.corpus.document.sentence.word.IWord;
import com.hankcs.hanlp.corpus.document.sentence.word.Word;
import com.hankcs.hanlp.dictionary.CustomDictionary;
import com.hankcs.hanlp.seg.Segment;
import com.hankcs.hanlp.seg.common.Term;
import com.ruoyi.biemo.business.domain.Category;
import com.ruoyi.biemo.business.domain.DocInfo;
import com.ruoyi.biemo.business.domain.EmotionResult;
import com.ruoyi.biemo.business.domain.WordCloudItem;
import com.ruoyi.biemo.business.service.CategoryService;
import com.ruoyi.biemo.business.service.DocInfoService;
import com.ruoyi.biemo.core.page.Page;
import com.ruoyi.biemo.core.page.PageFactory;
import com.ruoyi.biemo.nlp.DependencyParserUtils;
import com.ruoyi.biemo.nlp.TextClassificationUtils;
import com.ruoyi.biemo.utils.MyObjects;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author makesoft
 * @version 1.0
 * @date 2021/1/14 11:19
 */
@RestController
@RequestMapping(value = "/makesoft/docInfo")
public class DocInfoController extends BaseController {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private DocInfoService docInfoService;
    @Autowired
    private CategoryService categoryService;

    /**
     * 查询文章管理列表
     */
    //@PreAuthorize("@ss.hasPermi('biemo:docInfo:list')")
    @GetMapping("/list")
    public Page<DocInfo> list(DocInfo docInfo)
    {
        Page<DocInfo> page =  docInfoService.selectDocInfoPage(docInfo,PageFactory.defaultPage());
        page.getRows().forEach(doc->{
            Category category = new Category();
            category = categoryService.selectCategoryById(doc.getCateId());
            if(category!=null&&category.getName()!=null){
                doc.setCateName(category.getName());
            }
        });
        return page;
    }

    @GetMapping("/getWordCloudByCateId/{categoryId}")
    public AjaxResult getWordCloudByCateId(@PathVariable String categoryId){
        List<WordCloudItem> wordCloudItems = docInfoService.getWordCloudByCateId(categoryId);

        return AjaxResult.success(wordCloudItems);
    }

    @GetMapping("/getEmotionAnalysisByCateId/{categoryId}")
        public AjaxResult getEmotionAnalysis(@PathVariable String categoryId) throws IOException {
        EmotionResult emotionResult = docInfoService.getEmotionAnalysis(categoryId);
        return AjaxResult.success(emotionResult);
    }
    /**
     * 导出文章管理列表
     */
    //@PreAuthorize("@ss.hasPermi('biemo:docInfo:export')")
    @Log(title = "文章管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DocInfo docInfo)
    {
        List<DocInfo> list = docInfoService.selectDocInfoList(docInfo);
        ExcelUtil<DocInfo> util = new ExcelUtil<DocInfo>(DocInfo.class);
        util.exportExcel(response, list, "文章管理数据");
    }

    /**
     * 获取文章管理详细信息
     */
    //@PreAuthorize("@ss.hasPermi('biemo:docInfo:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id)
    {
        return AjaxResult.success(docInfoService.selectDocInfoById(id));
    }

    /**
     * 批量标注
     */
    @PostMapping(value = "/uploadPosTagIds")
    public AjaxResult uploadPosTag(@RequestBody List<String> idList) throws IOException {
        for (int i = 0; i < idList.size(); i++) {
            getInfoDelHtml(idList.get(i));
        }
        return AjaxResult.success();
    }

    /**
     * 获取文章管理详细信息 去掉内容标签
     */
    //@PreAuthorize("@ss.hasPermi('biemo:docInfo:query')")
    @GetMapping(value = "/getInfoDelHtml/{id}")
    public AjaxResult getInfoDelHtml(@PathVariable("id") String docInfoId) throws IOException {
        DocInfo docInfo = docInfoService.selectDocInfoById(docInfoId);
        JSONObject result = new JSONObject();
        if (docInfo == null) {
            return AjaxResult.error("未查询到文本");
        }
        String content = docInfo.getContent();
        content = MyObjects.delHTMLTag(content);
        content = MyObjects.delSpace(content);
        JSONArray labels = new JSONArray();
        result.put("docInfoId",docInfoId);
        result.put("content", content);
        result.put("connections", new JSONArray());
        result.put("connectionCategories", MyObjects.connectionCategories);
        result.put("labelCategories", MyObjects.labelCategories);
        Sentence sentence = DependencyParserUtils.nerAnalysis(content);
        List<IWord> wordList = sentence.wordList;
        int noun=0;
        int personalName=0;
        int placeName=0;
        int InstitutionalGroup=0;
        int verb=0;
        int adjective=0;
        int adverb=0;
        if(wordList!=null&&wordList.size()>0){
            int offset = 0;
            int id = 0;
            for(int i=0;i<wordList.size();i++){
                String value = wordList.get(i).getValue();
                String label = wordList.get(i).getLabel();
                if(MyObjects.wordsMapping.get(label)!=null){
                    Integer startIndex = offset;
                    Integer endIndex = offset+value.length();
                    Integer categoryId = MyObjects.wordsMapping.get(label);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id",id);
                    if(categoryId==0){
                        noun++;
                    }else if(categoryId==1){
                        personalName++;
                    }else if(categoryId==2){
                        placeName++;
                    }else if(categoryId==3){
                        InstitutionalGroup++;
                    }else if(categoryId==4){
                        verb++;
                    }else if(categoryId==5){
                        adjective++;
                    }else if(categoryId==6){
                        adverb++;
                    }
                    jsonObject.put("categoryId",categoryId);
                    jsonObject.put("startIndex",startIndex);
                    jsonObject.put("endIndex",endIndex);
                    labels.add(jsonObject);
                }
                offset += value.length();
                id++;
            }
            result.put("labels",labels);
        }

        Map map=new HashMap();
        map.put("noun",noun);
        map.put("personalName",personalName);
        map.put("placeName",placeName);
        map.put("institutionalGroup",InstitutionalGroup);
        map.put("verb",verb);
        map.put("adjective",adjective);
        map.put("adverb",adverb);
        result.put("partData",map);

        //点击词性标注后直接上传 并修改状态
        Query query = new Query(Criteria.where("_id").is(docInfoId));
        Update update = new Update();
        update.set("posTagStatus", "已标注");
        mongoTemplate.upsert(query, update, DocInfo.class);
        return AjaxResult.success("查询成功",result);
    }

    @PostMapping("/getInfoDelHtmlByContent")
    public AjaxResult getInfoDelHtmlByContent(@RequestBody String content) throws IOException {
        JSONObject result = new JSONObject();
        content = MyObjects.delHTMLTag(content);
        content = MyObjects.delSpace(content);
        JSONArray labels = new JSONArray();
        result.put("content",content);
        result.put("connections",new JSONArray());
        result.put("connectionCategories",MyObjects.connectionCategories);
        result.put("labelCategories",MyObjects.labelCategories);
        Sentence sentence = DependencyParserUtils.nerAnalysis(content);
        List<IWord> wordList = sentence.wordList;
        if(wordList!=null&&wordList.size()>0){
            int offset = 0;
            int id = 0;
            for(int i=0;i<wordList.size();i++){
                String value = wordList.get(i).getValue();
                String label = wordList.get(i).getLabel();
                if(MyObjects.wordsMapping.get(label)!=null){
                    Integer startIndex = offset;
                    Integer endIndex = offset+value.length();
                    Integer categoryId = MyObjects.wordsMapping.get(label);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id",id);
                    jsonObject.put("categoryId",categoryId);
                    jsonObject.put("startIndex",startIndex);
                    jsonObject.put("endIndex",endIndex);
                    labels.add(jsonObject);
                }
                offset += value.length();
                id++;
            }
            result.put("labels",labels);
        }
        return AjaxResult.success("查询成功",result);
    }

    @PostMapping("/uploadPosTag")
    public AjaxResult uploadPosTag(@RequestBody JSONObject jsonObject) throws IOException {
        String content = jsonObject.getString("content");
        JSONArray labels = jsonObject.getJSONArray("labels");
        String docInfoId = jsonObject.getString("docInfoId");
        List<IWord> wordList = new ArrayList<>();
        if(labels!=null&&labels.size()>0){
            for(int i=0;i<labels.size();i++){
                Word word = new Word(null,null);
                JSONObject labelJSONObject = labels.getJSONObject(i);
                Integer startIndex = labelJSONObject.getInteger("startIndex");
                Integer endIndex = labelJSONObject.getInteger("endIndex");
                Integer categoryId = labelJSONObject.getInteger("categoryId");
                String value = content.substring(startIndex,endIndex);
                String label = MyObjects.wordsMappingIndex.get(categoryId);
                word.setLabel(label);
                word.setValue(value);
                wordList.add(word);
            }
            Sentence sentence = new Sentence(wordList);
            DependencyParserUtils.learn(sentence);
        }
        Query query = new Query(Criteria.where("_id").is(docInfoId));
        Update update = new Update();
        update.set("posTagStatus", "已标注");
        mongoTemplate.upsert(query, update, DocInfo.class);
        return AjaxResult.success("标注上传成功");
    }

    /**
     * 新增文章管理或修改文章
     */
    //@PreAuthorize("@ss.hasPermi('biemo:docInfo:add')")
    @Log(title = "文章新增", businessType = BusinessType.INSERT)
    @RequestMapping
    public AjaxResult add(@RequestBody DocInfo docInfo)
    {
        docInfoService.insertOrUpdateDocInfo(docInfo);
        return AjaxResult.success();
    }

    /**
     * 删除文章管理
     */
    //@PreAuthorize("@ss.hasPermi('biemo:docInfo:remove')")
    @Log(title = "文章删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids)
    {
        docInfoService.deleteDocInfoByIds(ids);
        return AjaxResult.success();
    }

    @GetMapping("/analysis/{id}")
    public AjaxResult analysis(@PathVariable String id){
        return AjaxResult.success(docInfoService.analysis(id,false));
    }


    //    @GetMapping("/socialAnalysis")
//    public AjaxResult socialAnalysis(@RequestParam String content) {
//        return AjaxResult.success(docInfoService.socialAnalysis(content));
//    }
    //社会网络分析--用户输入
    @PostMapping("/socialAnalysis")
    public AjaxResult socialAnalysis(@RequestBody String content) {
        return AjaxResult.success(docInfoService.socialAnalysis(content));
    }

    //文章管理--批量分析
    @GetMapping("/batchAnalysis/{ids}")
    public AjaxResult batchAnalysis(@PathVariable String[] ids){
        return AjaxResult.success(docInfoService.batchAnalysis(ids));
    }

    //社会网络分析
    @PostMapping("/socialNetworkAnalysis")
    public AjaxResult batchAnalysisByIds(@RequestBody String [] ids) {
        return AjaxResult.success(docInfoService.socialNetworkAnalysis(ids));
    }

    @GetMapping("/summary/{id}")
    public AjaxResult summary(@PathVariable String id){
        return AjaxResult.success(docInfoService.summary(id));
    }

    @GetMapping("/handleClassification/{id}")
    public AjaxResult handleClassification(@PathVariable String id){
        DocInfo docInfo = docInfoService.selectDocInfoById(id);
        JSONObject result = new JSONObject();
        String content = docInfo.getContent();
        content = MyObjects.delHTMLTag(content);
        content = MyObjects.delSpace(content);
        return AjaxResult.success("查询成功",TextClassificationUtils.getClassification(content));
    }

//    @PostMapping("/createEsIndex")
//    public void createEsIndex(){
//        DocInfo docInfo=new DocInfo();
//        docInfoService.insertEs(docInfo);
//    }

    @PostMapping("/splitWordIds")
    public AjaxResult splitWordIds(@RequestBody List<DocInfo> docInfoList){
        for (int i = 0; i < docInfoList.size(); i++) {
            splitWordDocInfo(docInfoList.get(i));
        }
        return AjaxResult.success("批量分词成功");
    }

    @PostMapping ("/splitWordStr")
    public AjaxResult splitWordStr(@RequestBody String str){
        Segment segment= HanLP.newSegment();
        List<Term> termList = segment.seg(str);
        List<String> wordList=new ArrayList<>();
        for (Term term : termList) {
            String word = term.toString().substring(0, term.length());
            wordList.add(word);
        }
        return AjaxResult.success("分词成功",wordList);
    }

    @PostMapping ("/splitWordDocInfo")
    public AjaxResult splitWordDocInfo(@RequestBody DocInfo docInfo){
        String title = docInfo.getContent();
        Segment segment= HanLP.newSegment();
        List<Term> termList = segment.seg(title);
        List<String> wordList=new ArrayList<>();
        //遍历分词结果
        for (Term term : termList) {
            String word = term.toString().substring(0, term.length());
            wordList.add(word);
        }
        docInfo.setAnalyzeTitle(wordList);
        List<String> analyzeTitleList = docInfo.getAnalyzeTitle();
        for (int i = 0; i < analyzeTitleList.size(); i++) {
            if(StringUtils.isNotBlank(analyzeTitleList.get(i))){
                CustomDictionary.add(analyzeTitleList.get(i));
            }
        }
        Query query = new Query(Criteria.where("_id").is(docInfo.getId()));
        Update update = new Update();
        update.set("splitWordStatus", "已分词");
        mongoTemplate.upsert(query, update, DocInfo.class);
        return AjaxResult.success("分词成功",docInfo);
    }

    /**
     * 分词结果上传
     *
     * @param splitResult
     * @return
     */
    @PostMapping("/uploadSplitWordStr")
    public AjaxResult uploadSplitWordStr(@RequestBody String splitResult) {
        try {
            String[] split = splitResult.split("/");
            for (int i = 0; i < split.length; i++) {
                if (StringUtils.isNotBlank(split[i])) {
                    CustomDictionary.add(split[i]);
                }
            }
            return AjaxResult.success("分词上传成功");
        }catch (Exception e){
            return AjaxResult.error("格式不正确");
        }
    }

    @PostMapping("/uploadSplitWordDocInfo")
    public AjaxResult uploadSplitWordDocInfo(@RequestBody DocInfo docInfo) {
        try {
            List<String> analyzeTitleList = docInfo.getAnalyzeTitle();
            for (int i = 0; i < analyzeTitleList.size(); i++) {
                if(StringUtils.isNotBlank(analyzeTitleList.get(i))){
                    CustomDictionary.add(analyzeTitleList.get(i));
                }
            }
            Query query = new Query(Criteria.where("_id").is(docInfo.getId()));
            Update update = new Update();
            update.set("splitWordStatus", "已分词");
            mongoTemplate.upsert(query, update, DocInfo.class);
            return AjaxResult.success("分词上传成功");
        }catch (Exception e){
            return AjaxResult.error("格式不正确");
        }
    }
//    /**
//     * 分词结果上传
//     *
//     * @param docInfo
//     * @return
//     */
//    @PostMapping("/uploadSplitWord")
//    public AjaxResult uploadsplitWord(@RequestBody DocInfo docInfo) {
//        Query query = new Query(Criteria.where("_id").is(docInfo.getId()));
//        Update update = new Update();
//        update.set("splitWordResult", docInfo.getSplitWordResult());
//        mongoTemplate.upsert(query, update, DocInfo.class);
//        return AjaxResult.success("上传成功");
//    }
//
//    /**
//     * 分词词训练结果上传
//     *
//     * @param splitWordDrill
//     * @return
//     */
//    @PostMapping("/uploadSplitWordDrill")
//    public AjaxResult uploadSplitWordDrill(@RequestBody SplitWordDrill splitWordDrill) {
//        for (String data : splitWordDrill.getSplitResult()) {
//            mongoTemplate.updateFirst(
//                    Query.query(Criteria.where("_id").is(splitWordDrill.getId())),  // 查询条件
//                    new Update()
//                            .push("splitResult").each(data)
//                            .currentDate("updateTime"),
////                            .currentTimestamp("updateTime"),
//                    "splitWordDrill");
//        }
//        return AjaxResult.success("上传成功");
//    }

}
