package com.ruoyi.web.controller.buyerapi;

import com.ruoyi.buyerapi.domain.BuyerCompanyInfo;
import com.ruoyi.buyerapi.domain.Member;
import com.ruoyi.buyerapi.mapper.BuyerCompanyInfoMapper;
import com.ruoyi.buyerapi.service.IBuyerCompanyInfoService;
import com.ruoyi.buyerapi.service.IBuyerMenuService;
import com.ruoyi.buyerapi.service.IBuyerUserService;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.commonapi.entity.enums.VerificationEnums;
import com.ruoyi.commonapi.enums.ResultCode;
import com.ruoyi.commonapi.enums.ResultUtil;
import com.ruoyi.commonapi.service.SmsUtil;
import com.ruoyi.commonapi.service.VerificationService;
import com.ruoyi.commonapi.vo.ResultMessage;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.BuyerPermissionService;
import com.ruoyi.framework.web.service.MemberService;
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.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 买家端,会员接口
 *
 * @author zq
 * @since 2020/11/16 10:07 下午
 */
@Slf4j
@RestController
@Api(tags = "平台会员接口")
@RequestMapping("/buyer/member")
public class MemberBuyerController {

    @Autowired
    private MemberService memberService;
    @Autowired
    private SmsUtil smsUtil;
    @Autowired
    private VerificationService verificationService;
    @Autowired
    private IBuyerMenuService buyerMenuService;
    @Autowired
    private BuyerPermissionService buyerPermissionService;
    @Autowired
    private IBuyerCompanyInfoService buyerCompanyInfoService;
    @Autowired
    private IBuyerUserService buyerUserService;
    @Autowired
    private RedisCache redisCache;

    @ApiOperation(value = "登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query")
    })
    @PostMapping("/userLogin")
    public AjaxResult userLogin(@NotNull(message = "用户名不能为空") @RequestParam String username,
                                @NotNull(message = "密码不能为空") @RequestParam String password) {
//        verificationService.check(uuid, VerificationEnums.LOGIN);
        return AjaxResult.success(memberService.usernameLogin(username, password));
    }

//    @ApiOperation(value = "短信登录接口")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "query"),
//            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query")
//    })
//    @PostMapping("/smsLogin")
//    public ResultMessage<Object> smsLogin(@NotNull(message = "手机号为空") @RequestParam String mobile,
//                                          @NotNull(message = "验证码为空") @RequestParam String code,
//                                          @RequestHeader String uuid) {
//        if (smsUtil.verifyCode(mobile, VerificationEnums.LOGIN, uuid, code)) {
//            return ResultUtil.data(memberService.mobilePhoneLogin(mobile));
//        } else {
//            throw new ServiceException(ResultCode.VERIFICATION_SMS_CHECKED_ERROR.message());
//        }
//    }

    @ApiOperation(value = "注册用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "mobilePhone", value = "手机号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query")
    })
    @GetMapping("/register")
    public AjaxResult register(@NotNull(message = "用户名不能为空") @RequestParam String username,
                               @NotNull(message = "密码不能为空") @RequestParam String password,
                               @NotNull(message = "确认密码不能为空") @RequestParam String confirmPassword,
                               @NotNull(message = "手机号为空") @RequestParam String mobilePhone,
                               @RequestHeader String uuid,
                               @NotNull(message = "验证码不能为空") @RequestParam String code) {
        if (password.equals(confirmPassword)) {
            if (smsUtil.verifyCode(mobilePhone, VerificationEnums.REGISTER, uuid, code)) {
                memberService.register(username, password, mobilePhone);
                AjaxResult.success();
            } else {
                throw new ServiceException(ResultCode.VERIFICATION_SMS_CHECKED_ERROR.message());
            }
        } else {
            throw new ServiceException(ResultCode.VERIFICATION_PASSWORD_ERROR.message());
        }
        return AjaxResult.success("注册成功，请返回登录");
    }

    @ApiOperation(value = "获取当前登录用户接口")
    @GetMapping
    public ResultMessage<SysUser> getUserInfo() {
        return ResultUtil.data(memberService.getUserInfo());
    }

    @ApiOperation(value = "通过图形验证码重置密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "手机号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "code", value = "图形验证码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "uuid", value = "uuid", required = true, paramType = "query")
    })
    @PostMapping("/resetByCode")
    public ResultMessage<Member> resetByCode(@RequestBody Member member) {
        String userName = member.getUsername();
        String code = member.getCode();
        String uuid = member.getUuid();
        SysUser sysUser = buyerUserService.selectUserByUserName(userName);
        if (sysUser != null) {
            validateCaptcha(userName, code, uuid);
            smsUtil.sendSmsCode(userName, VerificationEnums.FIND_USER, uuid);
            return ResultUtil.success();
        } else if (sysUser == null) {
            return ResultUtil.error(201, "账号不存在,请先注册");
        } else {
            throw new ServiceException(ResultCode.VERIFICATION_SMS_CHECKED_ERROR.message());
        }
    }

    @ApiOperation(value = "通过短信重置密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "手机号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, paramType = "query"),
            @ApiImplicitParam(name = "uuid", value = "uuid", required = true, paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "query")
    })
    @PostMapping("/resetByMobile")
    public AjaxResult resetByMobile(@RequestBody Member member) {
        String username = member.getUsername();
        String code = member.getCode();
        String uuid = member.getUuid();
        //校验短信验证码是否正确
        if (smsUtil.verifyCode(username, VerificationEnums.FIND_USER, uuid, code)) {
            SysUser user = memberService.findByMobile(username);
            user.setPassword(SecurityUtils.encryptPassword(member.getPassword()));
            buyerUserService.resetPwd(user);
            return AjaxResult.success();
        } else {
            return AjaxResult.error(500, "验证码错误,请重新输入");
        }
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = buyerPermissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = buyerPermissionService.getMenuPermission(user);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        // 公司信息
        if (null != user.getCompanyId()) {
            BuyerCompanyInfo buyerCompanyInfo = buyerCompanyInfoService.selectBuyerCompanyInfoByUserId(user.getUserId());
            ajax.put("buyerCompanyInfo", buyerCompanyInfo);
        }
        return ajax;
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        Long userId = SecurityUtils.getUserId();
        List<SysMenu> menus = buyerMenuService.selectMenuTreeByUserId(userId);
        return AjaxResult.success(buyerMenuService.buildMenus(menus));
    }

    /**
     * 校验验证码
     *
     * @param username 用户名
     * @param code     验证码
     * @param uuid     唯一标识
     * @return 结果
     */
    public void validateCaptcha(String username, String code, String uuid) {
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(Constants.SYS_MANAGE, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(Constants.SYS_MANAGE, username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
    }
}
