package com.qxgmat.controller.api;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.nuliji.tools.PageMessage;
import com.nuliji.tools.Response;
import com.nuliji.tools.ResponseHelp;
import com.nuliji.tools.Transform;
import com.nuliji.tools.exception.ParameterException;
import com.qxgmat.data.constants.enums.ServiceKey;
import com.qxgmat.data.constants.enums.SettingKey;
import com.qxgmat.data.constants.enums.status.DirectionStatus;
import com.qxgmat.data.dao.entity.*;
import com.qxgmat.dto.extend.UserExtendDto;
import com.qxgmat.dto.response.CommentDto;
import com.qxgmat.dto.response.FaqDto;
import com.qxgmat.service.UsersService;
import com.qxgmat.service.inline.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/base")
@Api(tags = "基本接口", description = "全站基本数据接口", produces = MediaType.APPLICATION_JSON_VALUE)
public class BaseController {

    @Autowired
    private SettingService settingService;

    @Autowired
    private AdService adService;

    @Autowired
    private RankService rankService;

    @Autowired
    private ContractService contractService;

    @Autowired
    private ExerciseStructService exerciseStructService;

    @Autowired
    private ExaminationStructService examinationStructService;

    @Autowired
    private FaqService faqService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private ReadyReadService readyReadService;

    @Autowired
    private ReadyDataService readyDataService;

    @Autowired
    private ReadyRoomService readyRoomService;

    @Autowired
    private ReadyArticleCategoryService readyArticleCategoryService;

    @Autowired
    private ReadyRoomAreaService readyRoomAreaService;

    @Autowired
    private UsersService usersService;

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

    @RequestMapping(value = "/ad", method = RequestMethod.GET)
    @ApiOperation(value = "获取广告", notes = "获取广告列表", httpMethod = "GET")
    public Response<List<Ad>> ad(
            @RequestParam(required = true) String channel
    )  {
        List<Ad> adList = adService.all(channel);
        return ResponseHelp.success(adList);
    }

    @RequestMapping(value = "/tips", method = RequestMethod.GET)
    @ApiOperation(value = "获取提示信息", notes = "获取提示信息", httpMethod = "GET")
    public Response<Map<String, String>> tips(@RequestParam(required = true) String[] position)  {
        Setting entity = settingService.getByKey(SettingKey.TIPS);
        JSONObject value = entity.getValue();

        Map<String, String> map = new HashMap<>();
        for (String p: position) {
            map.put(p, value.getString(p));
        }
        return ResponseHelp.success(map);
    }

    @RequestMapping(value = "/sentence", method = RequestMethod.GET)
    @ApiOperation(value = "获取长难句信息", notes = "获取长难句信息", httpMethod = "GET")
    public Response<JSONObject> sentence()  {
        Setting entity = settingService.getByKey(SettingKey.SENTENCE_INFO);
        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/experience", method = RequestMethod.GET)
    @ApiOperation(value = "获取心经信息", notes = "获取心经信息", httpMethod = "GET")
    public Response<JSONObject> experience()  {
        Setting entity = settingService.getByKey(SettingKey.EXPERIENCE_INFO);
        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/wechat", method = RequestMethod.GET)
    @ApiOperation(value = "获取心经信息", notes = "获取心经信息", httpMethod = "GET")
    public Response<JSONObject> wechat()  {
        Setting entity = settingService.getByKey(SettingKey.WECHAT_INFO);
        return ResponseHelp.success(entity.getValue());
    }

    @RequestMapping(value = "/score", method = RequestMethod.GET)
    @ApiOperation(value = "考分计算", notes = "获取考分排行信息", httpMethod = "GET")
    public Response<Rank> score(
            @RequestParam(required = true) Number total,
            @RequestParam(required = true) Number quant
    )  {
        Rank rank = rankService.compute(total, quant);
        if (rank == null){
            throw new ParameterException("排名信息为空");
        }
        return ResponseHelp.success(rank);
    }

    @RequestMapping(value = "/exercise/main", method = RequestMethod.GET)
    @ApiOperation(value = "所有练习头2层", httpMethod = "GET")
    public Response<List<ExerciseStruct>> exerciseMain(HttpSession session) {
        List<ExerciseStruct> p = exerciseStructService.main();
        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/exercise/children", method = RequestMethod.GET)
    @ApiOperation(value = "所有练习层级", httpMethod = "GET")
    public Response<List<ExerciseStruct>> exerciseChildren(
            @RequestParam(required = true) Integer id,
            @RequestParam(required = false, defaultValue = "false") boolean children,
            HttpSession session) {
        List<ExerciseStruct> p = exerciseStructService.children(id, children? 1 : 0);
        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/exercise/parent", method = RequestMethod.GET)
    @ApiOperation(value = "练习层级父级", httpMethod = "GET")
    public Response<List<ExerciseStruct>> exerciseParent(
            @RequestParam(required = true) Integer id,
            HttpSession session) {
        List<ExerciseStruct> p = exerciseStructService.parent(id);
        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/exercise/range", method = RequestMethod.GET)
    @ApiOperation(value = "练习层级范围", httpMethod = "GET")
    public Response<List<ExerciseStruct>> exerciseRange(
            @RequestParam(required = true) Integer id,
            HttpSession session) {
        List<ExerciseStruct> p = exerciseStructService.all();

        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/examination/main", method = RequestMethod.GET)
    @ApiOperation(value = "所有模考头2层", httpMethod = "GET")
    public Response<List<ExaminationStruct>> examinationMain(HttpSession session) {
        List<ExaminationStruct> p = examinationStructService.main();
        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/examination/children", method = RequestMethod.GET)
    @ApiOperation(value = "所有模考层级", httpMethod = "GET")
    public Response<List<ExaminationStruct>> examinationChildren(
            @RequestParam(required = true) Integer id,
            @RequestParam(required = false, defaultValue = "false") boolean children,
            HttpSession session) {
        List<ExaminationStruct> p = examinationStructService.children(id, children ? 1 :0);
        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/examination/parent", method = RequestMethod.GET)
    @ApiOperation(value = "模考层级父级", httpMethod = "GET")
    public Response<List<ExaminationStruct>> examinationParent(
            @RequestParam(required = true) Integer id,
            HttpSession session) {
        List<ExaminationStruct> p = examinationStructService.parent(id);
        return ResponseHelp.success(p);
    }

    @RequestMapping(value = "/examination/number", method = RequestMethod.GET)
    @ApiOperation(value = "模考题目数", notes = "获取模考题目数", httpMethod = "GET")
    public Response<JSONObject> examinationNumber()  {
        Setting entity = settingService.getByKey(SettingKey.EXAMINATION_TIME);

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

    @RequestMapping(value = "/service", method = RequestMethod.GET)
    @ApiOperation(value = "获取服务信息", notes = "获取服务信息", httpMethod = "GET")
    public Response<JSONObject> service(@RequestParam(required = true) String service)  {
        SettingKey key;
        switch(ServiceKey.ValueOf(service)){
            case TEXTBOOK:
                key = SettingKey.SERVICE_TEXTBOOK;
                break;
            case VIP:
                key = SettingKey.SERVICE_VIP;
                break;
            case QX_CAT:
                key = SettingKey.SERVICE_QX_CAT;
                break;
            default:
                throw new ParameterException("服务信息错误");
        }
        Setting setting = settingService.getByKey(key);
        return ResponseHelp.success(setting.getValue());
    }

    @RequestMapping(value = "/contract", method = RequestMethod.GET)
    @ApiOperation(value = "获取合同信息", notes = "获取合同信息", httpMethod = "GET")
    public Response<Contract> contract(@RequestParam(required = true) String key)  {
        Contract contract = contractService.getContract(key);
        return ResponseHelp.success(contract);
    }

    @RequestMapping(value = "/faq/list", method = RequestMethod.GET)
    @ApiOperation(value = "faq列表", httpMethod = "GET")
    public Response<PageMessage<FaqDto>> listFaq(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = true) String channel,
            @RequestParam(required = false) String position,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {
        Page<Faq> p = faqService.list(page, size, channel, position);
        List<FaqDto> pr = Transform.convert(p, FaqDto.class);

        Collection userIds = Transform.getIds(p, Faq.class, "userId");
        List<User> userList = usersService.select(userIds);
        Transform.combine(pr, userList, FaqDto.class, "userId", "user", User.class, "id", UserExtendDto.class);

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

    @RequestMapping(value = "/comment/list", method = RequestMethod.GET)
    @ApiOperation(value = "评论列表", httpMethod = "GET")
    public Response<PageMessage<CommentDto>> listComment(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = true) String channel,
            @RequestParam(required = false) String position,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {
        Page<Comment> p = commentService.list(page, size, channel, position);

        Collection userIds = Transform.getIds(p, Comment.class, "userId");
        List<User> userList = usersService.select(userIds);
        commentService.replaceUser(p, userList);

        List<CommentDto> pr = Transform.convert(p, CommentDto.class);

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

    @RequestMapping(value = "/ready_info", method = RequestMethod.GET)
    @ApiOperation(value = "获取GetReady信息", notes = "获取GetReady信息", httpMethod = "GET")
    public Response<JSONObject> readyRead()  {
        Setting entity = settingService.getByKey(SettingKey.READY_READ);
        JSONObject info = entity.getValue();

        List<ReadyArticleCategory> articleCategoryList = readyArticleCategoryService.all();
        List<ReadyRoomArea> roomAreaList = readyRoomAreaService.all();

        JSONObject dto = new JSONObject();
        dto.put("read", info);
        dto.put("category", articleCategoryList);
        dto.put("area", roomAreaList);
        return ResponseHelp.success(dto);
    }

    @RequestMapping(value = "/read/list", method = RequestMethod.GET)
    @ApiOperation(value = "推荐阅读", httpMethod = "GET")
    public Response<PageMessage<ReadyRead>> listRead(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = true) String plate,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {
        Page<ReadyRead> p = readyReadService.list(page, size, plate, order, DirectionStatus.ValueOf(direction));
        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/room/list", method = RequestMethod.GET)
    @ApiOperation(value = "考场查询", httpMethod = "GET")
    public Response<PageMessage<ReadyRoom>> listRoom(
            @RequestParam(required = false, defaultValue = "1") int page,
            @RequestParam(required = false, defaultValue = "100") int size,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Integer areaId,
            @RequestParam(required = false, defaultValue = "id") String order,
            @RequestParam(required = false, defaultValue = "desc") String direction,
            HttpSession session) {
        Page<ReadyRoom> p = readyRoomService.list(page, size, keyword, areaId, order, DirectionStatus.ValueOf(direction));
        return ResponseHelp.success(p, page, size, p.getTotal());
    }

    @RequestMapping(value = "/data/all", method = RequestMethod.GET)
    @ApiOperation(value = "资料", httpMethod = "GET")
    public Response<List<ReadyData>> allData(
            @RequestParam(required = true) Boolean isOfficial,
            HttpSession session) {
        List<ReadyData> p = readyDataService.all(isOfficial);
        return ResponseHelp.success(p);
    }
}