package com.qxgmat.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.nuliji.tools.*;
import com.qxgmat.data.constants.enums.SettingKey;
import com.qxgmat.data.constants.enums.module.ChannelModule;
import com.qxgmat.data.dao.entity.*;
import com.qxgmat.dto.admin.request.CommentDto;
import com.qxgmat.dto.admin.request.FaqDto;
import com.qxgmat.dto.admin.request.RankDto;
import com.qxgmat.service.inline.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.poifs.filesystem.POIFSFileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


@RestController("AdminSettingController")
@RequestMapping("/admin/setting")
@Api(tags = "配置信息接口", description = "全局独立配置设置", produces = MediaType.APPLICATION_JSON_VALUE)
public class SettingController {
    private static final Logger logger = LoggerFactory.getLogger(SettingController.class);

    @Autowired
    private SettingService settingService;

    @Autowired
    private RankService rankService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private FaqService faqService;

    @Autowired
    private MessageService messageService;

    @RequestMapping(value = "/index", method = RequestMethod.PUT)
    @ApiOperation(value = "修改首页配置", httpMethod = "PUT")
    private Response<Boolean> editIndex(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.INDEX);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/index", method = RequestMethod.GET)
    @ApiOperation(value = "获取首页配置", httpMethod = "GET")
    private Response<JSONObject> getIndex(){
        Setting entity = settingService.getByKey(SettingKey.INDEX);
        logger.debug("{}", entity);
        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/place", method = RequestMethod.PUT)
    @ApiOperation(value = "修改考点设置", httpMethod = "PUT")
    private Response<Boolean> editPlace(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.PLACE);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/place", method = RequestMethod.GET)
    @ApiOperation(value = "获取考点配置", httpMethod = "GET")
    private Response<JSONObject> getPlace(){
        Setting entity = settingService.getByKey(SettingKey.PLACE);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/message_template", method = RequestMethod.PUT)
    @ApiOperation(value = "修改消息模版", httpMethod = "PUT")
    private Response<Boolean> editMessageTemplate(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.MESSAGE_TEMPLATE);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/message_template", method = RequestMethod.GET)
    @ApiOperation(value = "获取消息模版", httpMethod = "GET")
    private Response<JSONObject> getMessageTemplate(){
        Setting entity = settingService.getByKey(SettingKey.MESSAGE_TEMPLATE);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/sentence", method = RequestMethod.PUT)
    @ApiOperation(value = "修改长难句设置", httpMethod = "PUT")
    private Response<Boolean> editSentence(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.SENTENCE);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/sentence", method = RequestMethod.GET)
    @ApiOperation(value = "获取长难句配置", httpMethod = "GET")
    private Response<JSONObject> getSentence(){
        Setting entity = settingService.getByKey(SettingKey.SENTENCE);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/exercise_time", method = RequestMethod.PUT)
    @ApiOperation(value = "修改做题时间设置", httpMethod = "PUT")
    private Response<Boolean> editExerciseTime(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.EXERCISE_TIME);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/exercise_time", method = RequestMethod.GET)
    @ApiOperation(value = "获取做题时间配置", httpMethod = "GET")
    private Response<JSONObject> getExerciseTime(){
        Setting entity = settingService.getByKey(SettingKey.EXERCISE_TIME);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/examination_time", method = RequestMethod.PUT)
    @ApiOperation(value = "修改做题时间设置", httpMethod = "PUT")
    private Response<Boolean> editExaminationTime(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.EXAMINATION_TIME);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/examination_time", method = RequestMethod.GET)
    @ApiOperation(value = "获取做题时间配置", httpMethod = "GET")
    private Response<JSONObject> getExaminationTime(){
        Setting entity = settingService.getByKey(SettingKey.EXAMINATION_TIME);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/filter_time", method = RequestMethod.PUT)
    @ApiOperation(value = "修改剔除时间设置", httpMethod = "PUT")
    private Response<Boolean> editFilterTime(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.FILTER_TIME);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/filter_time", method = RequestMethod.GET)
    @ApiOperation(value = "获取剔除时间配置", httpMethod = "GET")
    private Response<JSONObject> getFilterTime(){
        Setting entity = settingService.getByKey(SettingKey.FILTER_TIME);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/sentence_time", method = RequestMethod.PUT)
    @ApiOperation(value = "修改长难句时间设置", httpMethod = "PUT")
    private Response<Boolean> editSentenceTime(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.SENTENCE_TIME);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/sentence_time", method = RequestMethod.GET)
    @ApiOperation(value = "获取长难句时间配置", httpMethod = "GET")
    private Response<JSONObject> getSentenceTime(){
        Setting entity = settingService.getByKey(SettingKey.SENTENCE_TIME);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/textbook_time", method = RequestMethod.PUT)
    @ApiOperation(value = "修改机经时间设置", httpMethod = "PUT")
    private Response<Boolean> editTextbookTime(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.TEXTBOOK_TIME);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/textbook_time", method = RequestMethod.GET)
    @ApiOperation(value = "获取机经时间配置", httpMethod = "GET")
    private Response<JSONObject> getTextbookTime(){
        Setting entity = settingService.getByKey(SettingKey.TEXTBOOK_TIME);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/score_switch", method = RequestMethod.PUT)
    @ApiOperation(value = "修改分数开关", httpMethod = "PUT")
    private Response<Boolean> editScoreSwitch(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.SCORE_SWITCH);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/score_switch", method = RequestMethod.GET)
    @ApiOperation(value = "获取分数开关", httpMethod = "GET")
    private Response<JSONObject> getScoreSwitch(){
        Setting entity = settingService.getByKey(SettingKey.SCORE_SWITCH);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/service_vip", method = RequestMethod.PUT)
    @ApiOperation(value = "修改Vip服务", httpMethod = "PUT")
    private Response<Boolean> editServiceVip(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.SERVICE_VIP);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/service_vip", method = RequestMethod.GET)
    @ApiOperation(value = "获取Vip服务", httpMethod = "GET")
    private Response<JSONObject> getServiceVip(){
        Setting entity = settingService.getByKey(SettingKey.SERVICE_VIP);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/service_textbook", method = RequestMethod.PUT)
    @ApiOperation(value = "修改千行CAT服务", httpMethod = "PUT")
    private Response<Boolean> editServiceTextbook(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.SERVICE_TEXTBOOK);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/service_textbook", method = RequestMethod.GET)
    @ApiOperation(value = "获取千行CAT服务", httpMethod = "GET")
    private Response<JSONObject> getServiceTextbook(){
        Setting entity = settingService.getByKey(SettingKey.SERVICE_TEXTBOOK);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/service_qx_cat", method = RequestMethod.PUT)
    @ApiOperation(value = "修改千行CAT服务", httpMethod = "PUT")
    private Response<Boolean> editServiceQXCat(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.SCORE_SWITCH);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/service_qx_cat", method = RequestMethod.GET)
    @ApiOperation(value = "获取千行CAT服务", httpMethod = "GET")
    private Response<JSONObject> getServiceQXCat(){
        Setting entity = settingService.getByKey(SettingKey.SCORE_SWITCH);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/course_index", method = RequestMethod.PUT)
    @ApiOperation(value = "修改课程首页", httpMethod = "PUT")
    private Response<Boolean> editCourseIndex(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.COURSE_INDEX);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/course_index", method = RequestMethod.GET)
    @ApiOperation(value = "获取课程首页", httpMethod = "GET")
    private Response<JSONObject> getCourseIndex(){
        Setting entity = settingService.getByKey(SettingKey.COURSE_INDEX);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/tips", method = RequestMethod.PUT)
    @ApiOperation(value = "修改结构说明", httpMethod = "PUT")
    private Response<Boolean> editTips(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.TIPS);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/tips", method = RequestMethod.GET)
    @ApiOperation(value = "获取结构说明", httpMethod = "GET")
    private Response<JSONObject> getTips(){
        Setting entity = settingService.getByKey(SettingKey.TIPS);

        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/comment/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加评价", httpMethod = "POST")
    private Response<Boolean> addComment(@RequestBody @Validated CommentDto dto){
        Comment entity = Transform.dtoToEntity(dto);
        commentService.add(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/comment/edit", method = RequestMethod.PUT)
    @ApiOperation(value = "修改评价", httpMethod = "PUT")
    private Response<Boolean> editComment(@RequestBody @Validated CommentDto dto){
        Comment entity = Transform.dtoToEntity(dto);
        commentService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/comment/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除评价", httpMethod = "DELETE")
    private Response<Boolean> deleteComment(@RequestParam int id){
        commentService.delete(id);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/comment/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取评价列表", httpMethod = "GET")
    private Response<PageMessage<Comment>> listComment(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) String channel,
            @RequestParam(required = false) String position,
            @RequestParam(required = false) Integer userId,
            @RequestParam(required = false) Boolean isSpecial
    ){
        Page<Comment> p = commentService.listAdmin(page, size, ChannelModule.ValueOf(channel), position, userId, isSpecial);
        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/faq/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加faq", httpMethod = "POST")
    private Response<Boolean> addFaq(@RequestBody @Validated FaqDto dto){
        Faq entity = Transform.dtoToEntity(dto);
        faqService.add(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/faq/edit", method = RequestMethod.PUT)
    @ApiOperation(value = "修改faq", httpMethod = "PUT")
    private Response<Boolean> editFaq(@RequestBody @Validated FaqDto dto){
        Faq entity = Transform.dtoToEntity(dto);
        faqService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/faq/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除评价", httpMethod = "DELETE")
    private Response<Boolean> deleteFaq(@RequestParam int id){
        faqService.delete(id);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/faq/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取faq列表", httpMethod = "GET")
    private Response<PageMessage<Faq>> listFaq(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) String channel,
            @RequestParam(required = false) String position,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) Boolean isSpecial
    ){
        Page<Faq> p = faqService.listAdmin(page, size, ChannelModule.ValueOf(channel), position, status, isSpecial);
        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/message/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加消息", httpMethod = "POST")
    private Response<Boolean> addMessage(@RequestBody @Validated FaqDto dto){
        Faq entity = Transform.dtoToEntity(dto);
        faqService.add(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/message/edit", method = RequestMethod.PUT)
    @ApiOperation(value = "修改消息", httpMethod = "PUT")
    private Response<Boolean> editMessage(@RequestBody @Validated FaqDto dto){
        Faq entity = Transform.dtoToEntity(dto);
        faqService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/message/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除消息", httpMethod = "DELETE")
    private Response<Boolean> deleteMessage(@RequestParam int id){
        faqService.delete(id);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/message/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取消息列表", httpMethod = "GET")
    private Response<PageMessage<Message>> listMessage(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size
    ){
        Page<Message> p = messageService.select(page, size);
        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/rank/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加排行", httpMethod = "POST")
    private Response<Boolean> addRank(@RequestBody @Validated RankDto dto){
        Rank entity = Transform.dtoToEntity(dto);
        rankService.add(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/rank/edit", method = RequestMethod.PUT)
    @ApiOperation(value = "修改排行", httpMethod = "PUT")
    private Response<Boolean> editRank(@RequestBody @Validated RankDto dto){
        Rank entity = Transform.dtoToEntity(dto);
        rankService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/rank/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除排行", httpMethod = "DELETE")
    private Response<Boolean> deleteRank(@RequestParam int id){
        rankService.delete(id);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/rank/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取排行设置", httpMethod = "GET")
    private Response<List<Rank>> getRank(){
        List<Rank> rankList = rankService.all();
        return ResponseHelp.success(rankList);
    }

    @RequestMapping(value = "/rank/import", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE, method = RequestMethod.POST)
    @ApiOperation(value = "导入排行数据", httpMethod = "POST")
    private Response<Boolean> importRank(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        // 删除所有排行数据, 并导入excel数据
        // 读取文件
        InputStream is = new FileInputStream("002.xls");
        // 将文件流解析成 POI 文档
        POIFSFileSystem fs = new POIFSFileSystem(is);
        // 再将 POI 文档解析成 Excel 工作簿
        HSSFWorkbook wb = new HSSFWorkbook(fs);
        HSSFRow row = null;
        HSSFCell cell = null;
        // 得到第 1 个工作簿
        HSSFSheet sheet = wb.getSheetAt(0);
        // 得到这一行一共有多少列
        int totalColumns = sheet.getRow(0).getPhysicalNumberOfCells();
        // 得到最后一行的坐标
        Integer lastRowNum = sheet.getLastRowNum();
        System.out.println("lastRowNum => " + lastRowNum);

        List<Rank> rankList = new ArrayList<>();
        Rank rank = null;
        String cellValue = null;

        // 从第 2 行开始读
        for(int i=1;i<=lastRowNum;i++){
            row = sheet.getRow(i);
            rank = new Rank();
            for(int j=0;j<totalColumns;j++){
                cell = row.getCell(j);
                if(cell!=null){
                    cellValue = cell.getStringCellValue();
                }else {
                    cellValue = "【没有数据】";
                }
            }
            rankList.add(rank);
        }
        rankService.replaceAll(rankList);
        return ResponseHelp.success(true);
    }
}