package com.icomsys.main_vm.biz.rcp.conversation.controller;

import com.google.gson.Gson;
import com.icomsys.main_vm.biz.advice.excep.CustomRuntimeException;
import com.icomsys.main_vm.biz.common.common.service.ExcelService;
import com.icomsys.main_vm.biz.rcp.conversation.service.SynonymManageService;
import com.icomsys.main_vm.biz.rcp.conversation.vo.synonym.ExcelSynonymListVo;
import com.icomsys.main_vm.biz.rcp.conversation.vo.synonym.SelectSynonymList2Vo;
import com.icomsys.main_vm.common.code.enumresource.ActionResource;
import com.icomsys.main_vm.common.code.enumresource.MenuResource;
import com.icomsys.main_vm.db.jpa.entity.conversation.TbSynonymMaster;
import com.icomsys.main_vm.db.jpa.entity.system.TbIcsCustInfo;
import com.icomsys.main_vm.db.jpa.repo.system.TbSynonymMasterRepo;
import com.icomsys.main_vm.db.mybatis.alias.LoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;
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;
import java.util.stream.Collectors;

@Controller
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/admin/rcp/conversation")
public class ConversationSynonymController {

    private final HttpServletRequest request;
    private final SynonymManageService synonymManageService;
    private final MappingJackson2JsonView ajaxMainView;
    @Autowired
    private TbSynonymMasterRepo tbSynonymMasterRepo;
    private final ExcelService excelService;

    @GetMapping("/synonym/manage.do")
    public String SynonymView() {
        return "/adm/rcp/conversation/synonym";
    }

    @RequestMapping("/synonym/synonymList.do")
    public ModelAndView synonymList(@RequestParam Map<String, String> dataMap){
        return synonymManageService.synonymList(dataMap);
    }

    @Transactional
    @RequestMapping("/synonym/deleteSynonym.do")
    public ModelAndView deleteSynonym(@RequestParam int seq, String serviceGroup, String custCode) {
		ModelAndView mv = new ModelAndView(ajaxMainView);
		LoginVO resultVO = (LoginVO) request.getSession().getAttribute("LoginVO");

        String oprMngCode = custCode + "_RCP_" + serviceGroup;

        HashMap eMap = new HashMap();
		eMap.put("seq", seq);
        eMap.put("oprMngCode", oprMngCode);
		eMap.put("userId", resultVO.getUserId());
        eMap.put("serviceGroup", serviceGroup);

		boolean result = true;
		try {
			synonymManageService.deleteSynonym(eMap);
		} catch (Exception e) {
			result = false;
		}

		mv.addObject("result", result);

		return mv;
//        return synonymManageService.deleteSynonym(eMap);
    }

    @RequestMapping("/synonym/dupCheck.do")
    public ModelAndView dupCheck(HttpServletRequest request, @RequestParam Map<String, String> dataMap) {
        String oprMngCode = dataMap.get("custCode") + "_RCP_" + dataMap.get("serviceGroup") == null ? null : dataMap.get("custCode") + "_RCP_" + dataMap.get("serviceGroup");

        ModelAndView mv = new ModelAndView(ajaxMainView);

        LoginVO resultVO = (LoginVO) request.getSession().getAttribute("LoginVO");

        HashMap eMap = new HashMap();
        eMap.putAll(dataMap);
        eMap.put("userId", resultVO.getUserId());
        eMap.put("serviceCode", oprMngCode);

        boolean result = true;
        String msg = "";
        int returnSeq = -1;

        try {
            String data = dataMap.get("synonymWords").toString();
            JSONParser parser = new JSONParser();
            Object obj = parser.parse(data);
            eMap.put("list", obj);

            returnSeq = synonymManageService.dupCheck(eMap);
        } catch (DuplicateKeyException e) {
            result = false;
            msg = e.getMessage();
        } catch (Exception e) {
            result = false;
            msg = "처리도중 오류가 발생하였습니다.";
        }

        mv.addObject("result", result);
        mv.addObject("msg", msg);
        mv.addObject("seq", returnSeq);

        return mv;
    }

    @ResponseBody
    @Transactional
    @RequestMapping("/synonym/saveSynonymList.do")
    public ModelAndView saveSynonymList(HttpServletRequest request, @RequestParam Map<String, Object> paramMap) {

        boolean result = true;
        ModelAndView mv = new ModelAndView(ajaxMainView);
        LoginVO resultVO = (LoginVO) request.getSession().getAttribute("LoginVO");
        String oprMngCode = paramMap.get("custCode") + "_RCP_" + paramMap.get("serviceGroup");

        HashMap eMap = new HashMap();
        eMap.put("userId", resultVO.getUserId());
        eMap.put("serviceCode", oprMngCode);
        eMap.putAll(paramMap);

        String data = paramMap.get("synonymWords").toString();
        JSONParser parser = new JSONParser();
        try {
            Object obj = parser.parse(data);
            eMap.put("list", obj);
            synonymManageService.saveSynonymList(eMap);

            if (synonymManageService.countSynonymWord(eMap) < 1) {
                synonymManageService.deleteSynonym(eMap);
            }

            //synonymManageService.saveSynonymList(eMap);
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (Exception e) {
            result = false;
        }

        mv.addObject("result", result);

        return mv;
//        return synonymManageService.saveSynonymList(request, paramMap);
    }

    @ResponseBody
    @RequestMapping("/synonym/download.do")
    public void downloadExcel(@RequestParam Map<String, String> dataMap) throws IOException {
        synonymManageService.downloadExcel(dataMap);
    }

    @RequestMapping("/synonym/uploadSynonym.do")
    public String uploadSynonym(HttpServletRequest request, @RequestParam("csvFile") MultipartFile[] csvFile,
                                @RequestParam Map<String, Object> dataMap, RedirectAttributes redirectAttr) throws CustomRuntimeException {
        boolean result = true;
        String message = "저장되었습니다.";
        String oprMngCode = dataMap.get("custCode") + "_RCP_" + dataMap.get("serviceGroup");

        log.info("dataMap -> {}", dataMap);

        HashMap eMap = new HashMap();
        LoginVO resultVO = (LoginVO) request.getSession().getAttribute("LoginVO");
        eMap.put("userId", resultVO.getUserId());
        eMap.put("serviceCode", oprMngCode);
        eMap.putAll(dataMap);

        List<HashMap> synonymList = new ArrayList<>();

        for (MultipartFile m : csvFile) {

            try {
                HSSFWorkbook wb = new HSSFWorkbook(m.getInputStream());
                HSSFSheet sheet = wb.getSheetAt(0);

                String sheetName = sheet.getSheetName();
                if (!(sheetName.equals("data"))) {
                    throw new CustomRuntimeException("엑셀 양식이 잘못되었습니다.");
                }

                for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {
                    HashMap fMap = new HashMap();

                    HSSFRow row = sheet.getRow(i);
                    if (row == null) continue;
                    int cells = row.getPhysicalNumberOfCells();

                    // 숫자인 경우, Numeric으로 들어와서 String형으로 받을 때 에러 발생
                    row.getCell(0).setCellType(CellType.STRING);
                    row.getCell(1).setCellType(CellType.STRING);
                    row.getCell(2).setCellType(CellType.STRING);

                    HSSFCell cell1 = row.getCell(0);
                    HSSFCell cell2 = row.getCell(1);
                    HSSFCell cell3 = row.getCell(2);

                    String idivWord = cell1.getStringCellValue();
                    String repWord = cell2.getStringCellValue();
                    String synonymWords = cell3.getStringCellValue();

                    if (cell1 == null || cell1.getStringCellValue().equals("")) {
                        continue;
                    }

                    fMap.putAll(eMap);
                    fMap.put("idivWord", idivWord);
                    fMap.put("repWord", repWord);
                    fMap.put("synonymWords", synonymWords.replaceAll("\"", ""));

                    String[] list = synonymWords.replaceAll(", ", ",").split(",");

                    if (list.length > 200) {
                        throw new CustomRuntimeException("동의어 제한을 초과했습니다.");
                    }
                    fMap.put("list", list);

                    synonymList.add(fMap);
                }

                if (synonymList.size() > 50) {
                    throw new CustomRuntimeException("개체어 제한을 초과했습니다.");
                }

                for (HashMap hMap : synonymList) {
                    try {
                        synonymManageService.uploadDupCheck(hMap);
                    } catch (DuplicateKeyException e) {
                        result = false;
                        message = e.getMessage();
                    }
                }

                synonymManageService.workLogSave(MenuResource.rcpconversationsynonymmanage, ActionResource.upload, eMap.get("serviceGroup").toString(), "엑셀 업로드");

            } catch (CustomRuntimeException e) {
                result = false;
                message = e.getMessage();
            } catch (IOException e) {
                result = false;
                message = "IO 오류가 발생하였습니다.";
            } catch (Exception e) {
                result = false;
                message = "처리도중 오류가 발생했습니다.";
            }
        }

        redirectAttr.addFlashAttribute("result", result);
        redirectAttr.addFlashAttribute("message", message);
        return "redirect:/admin/rcp/conversation/synonym/manage.do";
    }


}

