/**
 * Copyright (c) 2020 fumeiai All rights reserved.
 * <p>
 * <p>
 * <p>
 * 版权所有，侵权必究！
 */

package com.lz.modules.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lz.common.utils.*;
import com.lz.modules.app.dto.SmsResult;
import com.lz.modules.app.entity.CodeRecordEntity;
import com.lz.modules.app.entity.SmsTemplateEntity;
import com.lz.modules.app.entity.StaffEntity;
import com.lz.modules.app.enums.SmsTypeEnum;
import com.lz.modules.app.service.CodeRecordService;
import com.lz.modules.app.service.SmsTemplateService;
import com.lz.modules.app.service.StaffService;
import com.lz.modules.flow.entity.StaffRole;
import com.lz.modules.flow.service.StaffRoleService;
import com.lz.modules.sys.entity.SysConfigEntity;
import com.lz.modules.sys.entity.SysUserEntity;
import com.lz.modules.sys.form.SysLoginForm;
import com.lz.modules.sys.service.SysCaptchaService;
import com.lz.modules.sys.service.SysConfigService;
import com.lz.modules.sys.service.SysUserService;
import com.lz.modules.sys.service.SysUserTokenService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.*;

/**
 * 登录相关
 *
 * @author fumeiai
 */
@RestController
public class SysLoginController extends AbstractController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserTokenService sysUserTokenService;
    @Autowired
    private SysCaptchaService sysCaptchaService;
    @Resource
    private SmsTemplateService smsTemplateService;
    @Autowired
    private CodeRecordService codeRecordService;
    @Resource
    private SysConfigService sysConfigService;

    @Autowired
    private StaffRoleService staffRoleService;
    @Resource
    private DhgjSmsUtil dhgjSmsUtil;

    @Value(value = "${spring.console.env}")
    private String environment;

    @Autowired
    private StaffService staffService;
    @Value(value = "${sms.code}")
    private boolean sendSMSCode;

    /**
     * 验证码
     */
    @GetMapping("captcha.jpg")
    public void captcha(HttpServletResponse response, String uuid) throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //获取图片验证码
        BufferedImage image = sysCaptchaService.getCaptcha(uuid);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

    /**
     * 发送短信验证码
     */
    @PostMapping("/sys/sendSMS")
    public R sendSMS(SysLoginForm form) {

        String username = form.getUserName();
        if (StringUtils.isBlank(username)) {
            return R.error("请输入用户名");
        }
        //用户信息
        SysUserEntity user = sysUserService.queryByUserName(form.getUserName());
        if (user == null) {
            if (user == null) {
                user = staffService.getUser(form.getUserName());
                if (user == null) {
                    return R.error("账号不存在!");
                }
            }
        }

        //账号不存在、密码错误
        if (!user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
            return R.error("密码不正确!");
        }
        String mobile = user.getMobile();
        if (StringUtils.isBlank(mobile)) {
            return R.error("该用户无手机号码");
        }
        //账号锁定
        if (user.getStatus() == 0) {
            return R.error("账号已被停用,请联系管理员");
        }

        CodeRecordEntity CodeRecordEntity = codeRecordService.getNoCerifyCode(user.getMobile(), SmsTypeEnum.LZ_LOGIN_VERIFICATION.getCode());

        if (CodeRecordEntity != null) {
            return R.error("短信验证码已经发送，请稍再试");
        }

        int count = codeRecordService.count(new QueryWrapper<CodeRecordEntity>().eq("send_account", user.getMobile()).ge("gmt_create", DateUtils.getStartOfDate(DateUtils.getCurrentDate())).le("gmt_create", DateUtils.getEndOfDate(DateUtils.getCurrentDate())));

        SysConfigEntity sysConfigEntity = sysConfigService.queryBykey(ConfigConstant.LOGIN_VERIFICATION_SEND_NUM);
        int max = 10;
        if (null != sysConfigEntity && StringUtils.isNotBlank(sysConfigEntity.getParamValue())) {
            max = Integer.parseInt(sysConfigEntity.getParamValue());
        }
      /*  if (count >= max) {
            return R.error("该用户当日发送登陆短信已达上限,请明天再试！");
        }*/

        try {
            SmsTemplateEntity smsTemplate = smsTemplateService.getOne(new QueryWrapper<SmsTemplateEntity>()
                    .eq("is_delete", 0)
                    .eq("name", SmsTypeEnum.LZ_LOGIN_VERIFICATION.getTemplateType()));
            //发送短信验证码
            String verifyCode = CommonUtil.getRandomNumber(6);

            LinkedHashMap<String, String> smsParams = new LinkedHashMap<>();
            smsParams.put("code", verifyCode);
            String result = "successful";
            //测试环境不发短信
            if (StringUtil.equals(environment, Constant.INVELOMENT_TYPE_TEST)) {
                verifyCode = "888888";
                codeRecordService.addCodeRecord(verifyCode, user, result);
                return R.ok();
            }

            SmsResult smsResult = dhgjSmsUtil.sendMessage(smsTemplate.getContent(), Constant.SING, mobile, smsParams, smsTemplate.getId());
            if (null != smsResult && smsResult.isSucc()) {
                result = smsResult.getResultStr();
                codeRecordService.addCodeRecord(verifyCode, user, result);
            }

        } catch (Exception e) {
            logger.error("SysLoginController sendSMS error", e);
            return R.error("系统错误，请联系管理员！");
        }

        return R.ok();
    }


    /**
     * 登录
     */
    @PostMapping("/sys/login")
    public Map<String, Object> login(@RequestBody SysLoginForm form) throws IOException {
        //用户信息
        SysUserEntity user = sysUserService.queryByUserName(form.getUserName());
        if (user == null) {
            StaffEntity staffEntity = staffService.selectByPhone(form.getUserName());
            if (staffEntity != null) {
                user = new SysUserEntity();
                user.setPassword(staffEntity.getPassword());
                user.setMobile(staffEntity.getMobile());
                user.setUserId(staffEntity.getId());
                user.setEmail(staffEntity.getEmail());
                user.setSalt(staffEntity.getSalt());
                user.setStatus(1);
                user.setType(1);
                user.setUsername(staffEntity.getMobile());
                user.setRealName(staffEntity.getName());
                user.setUserNo(staffEntity.getMobile());
            } else {
                return R.error("账号不存在!");
            }
        }
        //测试环境将不进行短信验证码，
        if (sendSMSCode) {
            //账号不存在、密码错误
            if (!user.getPassword().equals(new Sha256Hash(form.getPassword(), user.getSalt()).toHex())) {
                return R.error("密码不正确!");
            }
            //账号锁定
            if (user.getStatus() == 0) {
                return R.error("账号已被停用,请联系管理员");
            }
            String verifyCode = form.getVerifyCode();
            CodeRecordEntity codeRecordEntity = codeRecordService.getOne(new QueryWrapper<CodeRecordEntity>().eq("send_account", user.getMobile()).eq("verify_code", verifyCode).eq("is_check", 0).ge("gmt_create", DateUtils.addDateMinutes(new Date(), -30)));

            if (codeRecordEntity == null) {
                return R.error("短信验证码不正确！");
            }
            codeRecordEntity.setIsCheck(1);
            codeRecordService.updateById(codeRecordEntity);
        }
        //生成token，并保存到数据库
        R r = sysUserTokenService.createToken(user);
        Map<String,Integer> map = staffRoleService.getRoleByUserId(user.getUserId());
        return r.put("data",map);
    }

    /**
     * 退出
     */
    @PostMapping("/sys/logout")
    public R logout() {
        sysUserTokenService.logout(getUserId());
        return R.ok();
    }

}
