package cn.wisenergy.web.admin.controller.app;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.wisenergy.common.utils.*;
import cn.wisenergy.model.app.User;
import cn.wisenergy.model.app.UsersDto;
import cn.wisenergy.service.app.UserService;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
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 javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * Created by m1991 on 2021/3/2 13:35
 */
@Api(tags = "登录/注册")
@Slf4j
@RequestMapping("api/user")
@RestController
public class LoginController {
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UserService usersService;

//        @Autowired
//        private Result result;

    /**
     * 手机登录接口
     * @param userId
     * @param sms
     * @return
     * @throws Exception
     */

    @ApiOperation(value = "登录", notes = "登录", httpMethod = "POST", produces = "application/json;charset=UTF-8")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sms", value = "验证码", dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "用户手机号", required = true, dataType = "String")})
    @RequestMapping("/login")
    public Map loginBySms(@RequestParam String userId, @RequestParam String sms)throws Exception{
        User users=null;
        Map map=new HashMap();
        String key= StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX,Constants.RedisKey.SMS_PRIFIX,userId,Constants.Sms.CodeType.LOGIN_OR_REGISTER+"");
        String redisCode=redisUtils.getValue(key);
        if(StringUtil.isBlank(redisCode) || !sms.equals(redisCode)){

            map.put("code","1003");
            map.put("msg","验证码错误");
//            throw new BaseException(ResultEnum.FAIL_VERIFY);
            return map;
        }
        redisUtils.delete(key);
        //根据手机号判断用户是否存在
        //不存在则保存用户信息--修改为提示用户注册
        users=usersService.queryUsersByPhone(userId);
        if(null==users){
            //throw new BaseException(ResultEnum.FAIL_ACCOUNT_NOT_EXIST);
            map.put("code","1005");
            map.put("msg","账号不存在,请注册");
            return map;
        }
        String token= null;

            token = createToken(users);

        if(!StringUtil.isBlank(token)){
            String wyz=users.getInviteCode();
            Map<String, Object> map1=StringUtil.createSimpleMap("token",token);
            map1.put("wyz",wyz);
            map1.put("code",0);
            map1.put("msg","成功！");
            return map1;
        }
        return (Map) ResultUtils.returnFail();
    }

    public String createToken(User users)throws Exception{
        String token=StringUtil.createToken();
        //保存token
        String tokenKey=StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX,Constants.RedisKey.TOKEN_PRIFIX,token);
        UsersDto usersDto=new UsersDto();
        BeanUtils.copyProperties(users,usersDto);
        redisUtils.set(tokenKey, JSONObject.toJSONString(usersDto),Constants.Duration.HALF_HOUR_INT);
        return token;
    }
    @ApiOperation(value = "获取用户登录token信息", notes = "获取用户登录token信息", httpMethod = "POST", produces = "application/json; charset=UTF-8")
    @RequestMapping("/info")
    public Map info(HttpServletRequest request)throws Exception{
        String token=request.getHeader("token");
        String tokenKey=StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX,Constants.RedisKey.TOKEN_PRIFIX,token);
        String userDtoJson=redisUtils.getValue(tokenKey);
        if(StringUtil.isBlank(userDtoJson)){
            Map map=new HashMap();
            map.put("code","2001");
            map.put("msg","未登录");
            return map;
            ///throw new BaseException(ResultEnum.FILE_NOT_LOGIN);
        }
        UsersDto usersDto=JSONObject.parseObject(userDtoJson,UsersDto.class);
        usersDto.setPassword(null);

        return (Map) ResultUtils.returnDataSuccess(userDtoJson);
    }

    @ApiOperation(value = "二维码邀请注册", notes = "二维码邀请注册", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户手机号", required = true, dataType = "String")
    })
    @PostMapping(value = "/registerByQrCode")
    public ResponseEntity<byte[]> registerByQrCode(@RequestParam("userId") String userId, HttpServletRequest request) throws IOException {
        User user = this.usersService.getByUserId(userId);
        if (user != null) {
            String regFullUrl = request.getScheme() + "://" + request.getServerName() + ":"+request.getServerPort()
                    + "/regist?beInvitedCode=" + user.getInviteCode();
            final InputStream is = new ClassPathResource("templates/background.jpg").getInputStream();
            BufferedImage srcImage = ImageIO.read(is);

            QrConfig config = new QrConfig(130, 130);
            config.setCharset(StandardCharsets.UTF_8);
            config.setMargin(0);
            BufferedImage waterImage = QrCodeUtil.generate(regFullUrl,config);
            byte[] bytes = ImageUtil.watermarkImageSimple1(srcImage, waterImage);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG);
            headers.setContentLength(bytes.length);
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        }
        return null;
    }

    @ApiOperation(value = "用户注册", notes = "用户注册", httpMethod = "POST", produces = "application/json; charset=UTF-8")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "beInvitedCode", value = "推荐人邀请码", required = false, dataType = "String"),
            @ApiImplicitParam(name = "sms", value = "验证码",required = true, dataType = "String")
    })
    @RequestMapping("/register")
    public Map register(@RequestParam String userId,@RequestParam  String beInvitedCode, @RequestParam String sms)throws Exception {
        User users=null;
        String key= StringUtil.formatKeyWithPrefix(Constants.RedisKey.PROJECT_PRIFIX,Constants.RedisKey.SMS_PRIFIX,userId,Constants.Sms.CodeType.LOGIN_OR_REGISTER+"");
        String redisCode=redisUtils.getValue(key);
        if(StringUtil.isBlank(redisCode) || !sms.equals(redisCode)){
//            try {
//                throw new BaseException(ResultEnum.FAIL_VERIFY);
//
//            } catch (BaseException e) {
                Map map=new HashMap();
                map.put("code","1003");
                map.put("msg","验证码错误");
//            throw new BaseException(ResultEnum.FAIL_VERIFY);
                return map;
//            }

        }
        redisUtils.delete(key);
        //判断phone是否符合输入类型
        if(!userId.matches(Constants.RegConstant.PHONE_REGSTR)){
//            try {
//                throw new BaseException(ResultEnum.PHONE_ERROR);
//            } catch (BaseException e) {
//                e.printStackTrace();
                Map map=new HashMap();
                map.put("code","1008");
                map.put("msg","手机号码格式不正确");
//            throw new BaseException(ResultEnum.FAIL_VERIFY);
                return map;
//            }
        }

        return usersService.userByZx(userId,beInvitedCode);
    }

}
