package com.ym.mec.education.controller;

import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.servlet.KaptchaServlet;
import com.ym.mec.biz.service.SmsCodeService;
import com.ym.mec.common.controller.BaseController;
import com.ym.mec.common.security.SecurityConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("code")
@Api(tags = "验证码服务")
public class SmsCodeController extends BaseController {

    @Autowired
    private SmsCodeService smsCodeService;
    @Autowired
    private Producer captchaProducer;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @ApiOperation(value = "发送登录短信验证码")
    @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String")
    @PostMapping(value = "/sendSms")
    public Object sendLoginVerifyCode(String mobile) throws Exception {
        smsCodeService.sendValidCode(mobile);
        return succeed();
    }

    @ApiOperation(value = "校验短信验证码")
    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String") })
    @PostMapping(value = "/verifySmsCode")
    public Object verifySmsCode(String phone,String code) {
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
        }
        if(smsCodeService.verifyValidCode(phone,code)){
            return succeed();
        }
        return failed("验证码校验失败");
    }

    @PostMapping(value = "/verifyLoginImage")
    @ApiOperation("校验登录图形验证码")
    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
    public Object verifyImageCode(String phone,String code){
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
        }
        String redisKey = Constants.KAPTCHA_SESSION_KEY + phone;
        if(redisTemplate.hasKey(redisKey)){
            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
                return succeed();
            }
        }
        return failed(SecurityConstants.VERIFY_FAILURE);
    }

    @GetMapping(value = "/getLoginImage")
    @ApiOperation("获取登录图片验证码")
    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
    public void getKaptchaImage(HttpServletResponse response,String phone) throws Exception {
        if(StringUtils.isEmpty(phone)){
            return;
        }
        response.setDateHeader("Expires", 0);

        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        // create the text for the image
        String capText = captchaProducer.createText();

        redisTemplate.opsForValue().set(Constants.KAPTCHA_SESSION_KEY + phone,capText,3, TimeUnit.MINUTES);
        // create the image with the text
        BufferedImage bi = captchaProducer.createImage(capText);
        KaptchaServlet kaptchaServlet = new KaptchaServlet();
        kaptchaServlet.init();
        ServletOutputStream out = response.getOutputStream();
        try {
            ImageIO.write(bi, "jpg", out);
            out.flush();
        } finally {
            out.close();
        }
    }
}
