package com.qmth.exam.reserve.controller.student;

import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.api.exception.DefaultExceptionEnum;
import com.qmth.boot.core.rateLimit.entity.RateLimitRule;
import com.qmth.boot.core.rateLimit.service.RateLimitService;
import com.qmth.exam.reserve.bean.Constants;
import com.qmth.exam.reserve.bean.RichTextBean;
import com.qmth.exam.reserve.bean.apply.ApplyTimePeriodResult;
import com.qmth.exam.reserve.bean.apply.ApplyVO;
import com.qmth.exam.reserve.bean.apply.TicketInfo;
import com.qmth.exam.reserve.controller.BaseController;
import com.qmth.exam.reserve.service.ExamReserveService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController("stuApplyController")
@Api(tags = "【考生端】考生预约相关接口")
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + "/student")
@Aac(strict = false, auth = true)
public class StudentApplyController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(StudentApplyController.class);

    @Autowired
    private ExamReserveService examReserveService;

    @Autowired
    private RateLimitService rateLimitService;

    @ApiOperation(value = "保存考生预约结果")
    @PostMapping(value = "/apply/save")
    public void save(@ApiParam("考点ID") @RequestParam Long examSiteId,
                     @ApiParam("预约时段ID") @RequestParam Long timePeriodId) {
        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
        if (!rateLimitService.getRateLimiter("apply_save", null, limitRule).acquire()) {
            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.REQUEST_API_BUSY);
        }

        examReserveService.saveStudentApply(curLoginStudent(), examSiteId, timePeriodId);
    }

    @ApiOperation(value = "取消考生预约结果")
    @PostMapping(value = "/apply/cancel")
    public void cancel(@ApiParam("考点ID") @RequestParam Long examSiteId,
                       @ApiParam("预约时段ID") @RequestParam Long timePeriodId) {
        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
        if (!rateLimitService.getRateLimiter("apply_cancel", null, limitRule).acquire()) {
            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.REQUEST_API_BUSY);
        }

        examReserveService.cancelStudentApply(curLoginStudent(), examSiteId, timePeriodId);
    }

    @ApiOperation(value = "获取考生预约结果列表（个人中心）")
    @PostMapping(value = "/apply/list")
    public List<ApplyVO> list(@ApiParam("是否已取消预约") @RequestParam(required = false) Boolean cancel) {
        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
        if (!rateLimitService.getRateLimiter("apply_list", null, limitRule).acquire()) {
            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.REQUEST_API_BUSY);
        }

        return examReserveService.getStudentApplyList(curLoginStudent(), cancel);
    }

    @ApiOperation(value = "获取考生当前进行中的预约列表（首页）")
    @PostMapping(value = "/apply/list/for/current")
    public List<ApplyVO> listForCurrent() {
        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
        if (!rateLimitService.getRateLimiter("apply_list", null, limitRule).acquire()) {
            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.REQUEST_API_BUSY);
        }

        return examReserveService.getStudentApplyListForCurrent(curLoginStudent());
    }

    @ApiOperation(value = "获取考生预约-电子准考证")
    @PostMapping(value = "/apply/ticket")
    public TicketInfo ticket(@ApiParam("考点ID") @RequestParam Long examSiteId,
                             @ApiParam("预约时段ID") @RequestParam Long timePeriodId) {
        return examReserveService.getApplyTicket(curLoginStudent().getId(), examSiteId, timePeriodId);
    }

    @ApiOperation(value = "获取考试须知")
    @PostMapping(value = "/exam/notice")
    public RichTextBean examNotice(@ApiParam("预约任务ID") @RequestParam Long applyTaskId) {
        return examReserveService.getExamNotice(applyTaskId);
    }

    @ApiOperation(value = "获取考场引导")
    @PostMapping(value = "/exam/site/guide")
    public RichTextBean examSiteGuide(@ApiParam("考点ID") @RequestParam Long examSiteId) {
        return examReserveService.getExamSiteGuide(examSiteId);
    }

    @ApiOperation(value = "获取可预约的“日期”列表", notes = "日期格式：yyyyMMdd")
    @PostMapping(value = "/apply/date/list")
    public List<String> dateList() {
        return examReserveService.getApplyDateList(curLoginStudent());
    }

    @ApiOperation(value = "获取可预约的“时段”列表")
    @PostMapping(value = "/apply/time/period/list")
    public ApplyTimePeriodResult timePeriodList(@ApiParam("考点ID") @RequestParam Long examSiteId,
                                                @ApiParam("预约日期：yyyyMMdd") @RequestParam String date) {
        RateLimitRule limitRule = RateLimitRule.parse(Constants.API_LIMIT_EXPRESSION);
        if (!rateLimitService.getRateLimiter("apply_time_list", null, limitRule).acquire()) {
            throw DefaultExceptionEnum.RATE_LIMITED.exception(Constants.REQUEST_API_BUSY);
        }

        return examReserveService.getApplyTimePeriodList(curLoginStudent(), examSiteId, date);
    }

}
