package com.qxgmat.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.nuliji.tools.*;
import com.nuliji.tools.exception.ParameterException;
import com.qxgmat.data.constants.enums.MessageCategory;
import com.qxgmat.data.constants.enums.MessageMethod;
import com.qxgmat.data.constants.enums.SettingKey;
import com.qxgmat.data.constants.enums.status.AnswerStatus;
import com.qxgmat.data.constants.enums.status.DirectionStatus;
import com.qxgmat.data.constants.enums.user.MoneyRange;
import com.qxgmat.data.dao.entity.*;
import com.qxgmat.dto.admin.extend.InfoExtendDto;
import com.qxgmat.dto.admin.extend.UserExtendDto;
import com.qxgmat.dto.admin.request.*;
import com.qxgmat.dto.admin.response.CommentInfoDto;
import com.qxgmat.dto.admin.response.FaqInfoDto;
import com.qxgmat.help.ShiroHelp;
import com.qxgmat.service.UsersService;
import com.qxgmat.service.extend.MessageExtendService;
import com.qxgmat.service.extend.OrderFlowService;
import com.qxgmat.service.inline.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@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 ShiroHelp shiroHelp;

    @Autowired
    private ManagerLogService managerLogService;

    @Autowired
    private AdService adService;

    @Autowired
    private SettingService settingService;

    @Autowired
    private RankService rankService;

    @Autowired
    private ContractService contractService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private FaqService faqService;

    @Autowired
    private MessageTemplateService messageTemplateService;

    @Autowired
    private MessageExtendService messageExtendService;

    @Autowired
    private UsersService usersService;

    @Autowired
    private CourseService courseService;

    @Autowired
    private CourseDataService courseDataService;

    @Autowired
    private OrderFlowService orderFlowService;

    @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 = "/base", method = RequestMethod.PUT)
    @ApiOperation(value = "修改基础配置", httpMethod = "PUT")
    private Response<Boolean> editBase(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.BASE);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/base", method = RequestMethod.GET)
    @ApiOperation(value = "获取基础配置", httpMethod = "GET")
    private Response<JSONObject> getBase(){
        Setting entity = settingService.getByKey(SettingKey.BASE);
        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 = "/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 = "/exercise_paper_auto", method = RequestMethod.PUT)
    @ApiOperation(value = "修改自动组卷时间设置", httpMethod = "PUT")
    private Response<Boolean> editExercisePaperAuto(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.EXERCISE_PAPER_AUTO);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/exercise_paper_auto", method = RequestMethod.GET)
    @ApiOperation(value = "获取自动组卷时间配置", httpMethod = "GET")
    private Response<JSONObject> getExercisePaperAuto(){
        Setting entity = settingService.getByKey(SettingKey.EXERCISE_PAPER_AUTO);

        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 = "/textbook_config", method = RequestMethod.PUT)
    @ApiOperation(value = "修改机经设置", httpMethod = "PUT")
    private Response<Boolean> editTextbookConfig(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.TEXTBOOK_CONFIG);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

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

        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.SERVICE_QX_CAT);
        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.SERVICE_QX_CAT);

        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 = "/promote", method = RequestMethod.PUT)
    @ApiOperation(value = "修改促销", httpMethod = "PUT")
    private Response<Boolean> editPromote(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.PROMOTE);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/promote", method = RequestMethod.GET)
    @ApiOperation(value = "获取课程促销", httpMethod = "GET")
    private Response<JSONObject> getPromote(){
        Setting entity = settingService.getByKey(SettingKey.PROMOTE);

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

    @RequestMapping(value = "/prepare_info", method = RequestMethod.PUT)
    @ApiOperation(value = "修改备考信息", httpMethod = "PUT")
    private Response<Boolean> editPrepareInfo(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.PREPARE_INFO);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/prepare_info", method = RequestMethod.GET)
    @ApiOperation(value = "获取备考信息", httpMethod = "GET")
    private Response<JSONObject> getPrepareInfo(){
        Setting entity = settingService.getByKey(SettingKey.PREPARE_INFO);

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

    @RequestMapping(value = "/experience_info", method = RequestMethod.PUT)
    @ApiOperation(value = "修改心经信息", httpMethod = "PUT")
    private Response<Boolean> editExperienceInfo(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.EXPERIENCE_INFO);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/experience_info", method = RequestMethod.GET)
    @ApiOperation(value = "获取心经信息", httpMethod = "GET")
    private Response<JSONObject> getExperienceInfo(){
        Setting entity = settingService.getByKey(SettingKey.EXPERIENCE_INFO);

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

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

    @RequestMapping(value = "/sentence_info", method = RequestMethod.GET)
    @ApiOperation(value = "获取长难句信息", httpMethod = "GET")
    private Response<JSONObject> getSentenceInfo(){
        Setting entity = settingService.getByKey(SettingKey.SENTENCE_INFO);

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

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

    @RequestMapping(value = "/wechat_info", method = RequestMethod.GET)
    @ApiOperation(value = "获取长难句信息", httpMethod = "GET")
    private Response<JSONObject> getWechatInfo(){
        Setting entity = settingService.getByKey(SettingKey.WECHAT_INFO);

        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 = "/ready_read", method = RequestMethod.PUT)
    @ApiOperation(value = "修改推荐阅读设置", httpMethod = "PUT")
    private Response<Boolean> editReadyRead(@RequestBody @Validated JSONObject dto){
        Setting entity = settingService.getByKey(SettingKey.READY_READ);
        entity.setValue(dto);
        settingService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/ready_read", method = RequestMethod.GET)
    @ApiOperation(value = "获取推荐阅读配置", httpMethod = "GET")
    private Response<JSONObject> getReadyRead(){
        Setting entity = settingService.getByKey(SettingKey.READY_READ);

        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);
        entity.setIsSystem(1);
        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/order", method = RequestMethod.PUT)
    @ApiOperation(value = "修改评价排序", httpMethod = "PUT")
    private Response<Boolean> orderComment(@RequestBody @Validated CommentOrderDto dto){
        commentService.updateOrder(dto.getIds());
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/comment/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取评价列表", httpMethod = "GET")
    private Response<PageMessage<CommentInfoDto>> listComment(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) Boolean user,
            @RequestParam(required = false) String channel,
            @RequestParam(required = false) String position,
            @RequestParam(required = false) Integer userId,
            @RequestParam(required = false) Boolean isSpecial,
            @RequestParam(required = false) Boolean isShow,
            @RequestParam(required = false) Integer moneyRang,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction
    ){
        Page<Comment> p = commentService.listAdmin(page, size, user, channel, position, userId, isSpecial, isShow, MoneyRange.ValueOf(moneyRang), order, DirectionStatus.ValueOf(direction));
        List<CommentInfoDto> pr = Transform.convert(p, CommentInfoDto.class);

        // 绑定用户
        Collection userIds = Transform.getIds(p, Comment.class, "userId");
        List<User> userList = usersService.select(userIds);
        Transform.combine(pr, userList, CommentInfoDto.class, "userId", "user", User.class, "id", UserExtendDto.class);

        // 绑定课程
        List<CommentInfoDto> prCourse = pr.stream().filter((row)-> row.getChannel().equals("course-video")).collect(Collectors.toList());
        Collection courseIds = Transform.getIds(prCourse, CommentInfoDto.class, "position");
        List<Course> courseList = courseService.select(courseIds);
        Transform.combine(prCourse, courseList, CommentInfoDto.class, "position", "positionDetail", Course.class, "id", InfoExtendDto.class);

        // 绑定资料
        List<CommentInfoDto> prData = pr.stream().filter((row)-> row.getChannel().equals("course_data")).collect(Collectors.toList());
        Collection dataIds = Transform.getIds(prData, CommentInfoDto.class, "position");
        List<CourseData> dataList = courseDataService.select(dataIds);
        Transform.combine(prData, dataList, CommentInfoDto.class, "position", "positionDetail", CourseData.class, "id", InfoExtendDto.class);

        return ResponseHelp.success(pr, 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);
        entity.setIsSystem(1);
        if(!entity.getAnswer().isEmpty()){
            entity.setAnswerTime(new Date());
            entity.setAnswerStatus(AnswerStatus.ANSWER.index);
            Manager manager = shiroHelp.getLoginManager();
            entity.setManagerId(manager.getId());
        }
        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);
        Faq in = faqService.get(entity.getId());

        // 回复
        if(in.getAnswerStatus() == 0){
            entity.setAnswerTime(new Date());
            Manager manager = shiroHelp.getLoginManager();
            entity.setManagerId(manager.getId());
            entity.setAnswerStatus(dto.getStatus());

            in.setAnswerStatus(entity.getAnswerStatus());
            in.setAnswer(entity.getAnswer());
            if(in.getIsSystem() == 0){
                in.setAnswerStatus(dto.getStatus());
                User user = usersService.get(in.getUserId());
                UserOrderRecord record = null;
                messageExtendService.sendFaqCallback(user, in);
            }
        }
        faqService.edit(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/faq/order", method = RequestMethod.PUT)
    @ApiOperation(value = "修改faq排序", httpMethod = "PUT")
    private Response<Boolean> orderFaq(@RequestBody @Validated FaqOrderDto dto){
        faqService.updateOrder(dto.getIds());
        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<FaqInfoDto>> listFaq(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) Boolean user,
            @RequestParam(required = false) String channel,
            @RequestParam(required = false) String position,
            @RequestParam(required = false) Integer userId,
            @RequestParam(required = false) Integer answerStatus,
            @RequestParam(required = false) Boolean isShow,
            @RequestParam(required = false) Boolean isSpecial,
            @RequestParam(required = false) Integer moneyRang,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction
    ){
        Page<Faq> p = faqService.listAdmin(page, size, user, channel, position, userId, answerStatus, isSpecial, isShow, MoneyRange.ValueOf(moneyRang), order, DirectionStatus.ValueOf(direction));
        List<FaqInfoDto> pr = Transform.convert(p, FaqInfoDto.class);

        // 绑定用户
        Collection userIds = Transform.getIds(p, Faq.class, "userId");
        List<User> userList = usersService.select(userIds);
        Transform.combine(pr, userList, FaqInfoDto.class, "userId", "user", User.class, "id", UserExtendDto.class);

        // 绑定position
        // 绑定课程
        List<FaqInfoDto> prCourse = pr.stream().filter((row)-> row.getChannel().equals("course-video")).collect(Collectors.toList());
        Collection courseIds = Transform.getIds(prCourse, FaqInfoDto.class, "position");
        List<Course> courseList = courseService.select(courseIds);
        Transform.combine(prCourse, courseList, FaqInfoDto.class, "position", "positionDetail", Course.class, "id", InfoExtendDto.class);

        // 绑定资料
        List<FaqInfoDto> prData = pr.stream().filter((row)-> row.getChannel().equals("course_data")).collect(Collectors.toList());
        Collection dataIds = Transform.getIds(prData, FaqInfoDto.class, "position");
        List<CourseData> dataList = courseDataService.select(dataIds);
        Transform.combine(prData, dataList, FaqInfoDto.class, "position", "positionDetail", CourseData.class, "id", InfoExtendDto.class);

        return ResponseHelp.success(pr, page, size, p.getTotal());
    }

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

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

    @RequestMapping(value = "/message/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除消息", httpMethod = "DELETE")
    private Response<Boolean> deleteMessage(@RequestParam int id){
        MessageTemplate in = messageTemplateService.get(id);
        if(!in.getMessageCategory().equals(MessageCategory.CUSTOM.key)){
            throw new ParameterException("不允许删除非自定义消息模版");
        }
        messageTemplateService.delete(id);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/message/detail", method = RequestMethod.GET)
    @ApiOperation(value = "获取消息", httpMethod = "GET")
    public Response<MessageTemplate> detailMessage(@RequestParam int id, HttpSession session) {
        MessageTemplate entity = messageTemplateService.get(id);
        return ResponseHelp.success(entity);
    }

    @RequestMapping(value = "/message/list", method = RequestMethod.GET)
    @ApiOperation(value = "获取消息列表", httpMethod = "GET")
    private Response<PageMessage<MessageTemplate>> listMessage(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) String messageCategory,
            @RequestParam(required = false) String messageMethod,
            @RequestParam(required = false) Boolean needCustom,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction
    ){
        Page<MessageTemplate> p = messageTemplateService.listAdmin(page, size, MessageCategory.ValueOf(messageCategory), MessageMethod.ValueOf(messageMethod), needCustom,order, DirectionStatus.ValueOf(direction));
        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/ad/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加广告", httpMethod = "POST")
    public Response<Ad> addAd(@RequestBody @Validated AdDto dto, HttpServletRequest request) {
        Ad entity = Transform.dtoToEntity(dto);
        entity = adService.addAd(entity);
        managerLogService.log(request);
        return ResponseHelp.success(entity);
    }

    @RequestMapping(value = "/ad/edit", method = RequestMethod.PUT)
    @ApiOperation(value = "修改广告", httpMethod = "PUT")
    public Response<Boolean> editAd(@RequestBody @Validated AdDto dto, HttpServletRequest request) {
        Ad entity = Transform.dtoToEntity(dto);
        entity = adService.editAd(entity);
        managerLogService.log(request);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/ad/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "删除广告", httpMethod = "DELETE")
    public Response<Boolean> deleteAd(@RequestParam int id, HttpServletRequest request) {
        adService.delete(id);
        managerLogService.log(request);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/ad/detail", method = RequestMethod.GET)
    @ApiOperation(value = "获取广告", httpMethod = "GET")
    public Response<Ad> detailAd(@RequestParam int id, HttpSession session) {
        Ad entity = adService.get(id);
        return ResponseHelp.success(entity);
    }

    @RequestMapping(value = "/ad/list", method = RequestMethod.GET)
    @ApiOperation(value = "广告列表", httpMethod = "GET")
    public Response<PageMessage<Ad>> listAd(
            @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, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {
        Page<Ad> p = adService.listAdmin(page, size, channel, position, order, DirectionStatus.ValueOf(direction));

        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/contract/edit", method = RequestMethod.PUT)
    @ApiOperation(value = "修改合同", httpMethod = "PUT")
    private Response<Boolean> editContract(@RequestBody @Validated ContractDto dto){
        Contract entity = Transform.dtoToEntity(dto);
        contractService.editContract(entity);
        return ResponseHelp.success(true);
    }

    @RequestMapping(value = "/contract/detail", method = RequestMethod.GET)
    @ApiOperation(value = "修改排行", httpMethod = "GET")
    private Response<Contract> getContract(String key){
        Contract in = contractService.getContract(key);
        return ResponseHelp.success(in);
    }

    @RequestMapping(value = "/contract/all", method = RequestMethod.GET)
    @ApiOperation(value = "获取排行设置", httpMethod = "GET")
    private Response<List<Contract>> allContract(){
        List<Contract> contractList = contractService.all();
        return ResponseHelp.success(contractList);
    }

    @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", method = RequestMethod.POST)
    @ApiOperation(value = "导入排行数据", httpMethod = "POST")
    private Response<Integer> importRank(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        // 删除所有排行数据, 并导入excel数据
        // 读取文件
//        InputStream is = new FileInputStream();
        // 将文件流解析成 POI 文档
        Workbook wb =null;
        Row row = null;
        Cell cell = null;

        if (multipartFile.getOriginalFilename().contains(".xlsx")){
            // 再将 POI 文档解析成 Excel 工作簿
            wb = new XSSFWorkbook(multipartFile.getInputStream());
        }else{
            // 再将 POI 文档解析成 Excel 工作簿
            wb = new HSSFWorkbook(multipartFile.getInputStream());
        }
        // 得到第 1 个工作簿
        Sheet sheet = wb.getSheetAt(0);
        int totalColumns = 8; // total_score, total_rank, quant_score, quant_rank, verbal_score, verbal_rank
        // 得到最后一行的坐标
        Integer lastRowNum = sheet.getLastRowNum();
        System.out.println("lastRowNum => " + lastRowNum);


        List<Rank> rankList = new ArrayList<>();
        Rank rank = 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){
                    switch(j){
                        case 0:
                            rank.setTotalScore((int) cell.getNumericCellValue());
                            break;
                        case 1:
                            rank.setTotalRank((int) cell.getNumericCellValue());
                            break;
                        case 2:
                            rank.setQuantScore((int) cell.getNumericCellValue());
                            break;
                        case 3:
                            rank.setQuantRank((int) cell.getNumericCellValue());
                            break;
                        case 4:
                            rank.setVerbalScore((int) cell.getNumericCellValue());
                            break;
                        case 5:
                            rank.setVerbalRank((int) cell.getNumericCellValue());
                            break;
                        case 6:
                            rank.setIrScore((int) cell.getNumericCellValue());
                            break;
                        case 7:
                            rank.setIrRank((int) cell.getNumericCellValue());
                            break;
                    }
                }else{
                    throw new ParameterException(String.format("%d行%d列数据为空", i, j));
                }
            }
            rankList.add(rank);
        }
        rankService.replaceAll(rankList);
        return ResponseHelp.success(rankList.size());
    }
}