package cn.pluss.platform.controller;

import cn.pluss.platform.annotation.OpLog;
import cn.pluss.platform.api.PageInfo;
import cn.pluss.platform.api.Result;
import cn.pluss.platform.api.ResultGenerator;
import cn.pluss.platform.constants.CommonError;
import cn.pluss.platform.constants.ProjectConstant;
import cn.pluss.platform.dto.ChangePwdDTO;
import cn.pluss.platform.entity.PhoneValidateCode;
import cn.pluss.platform.entity.UserApp;
import cn.pluss.platform.entity.UserInfo;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.phoneValidateCode.PhoneValidateCodeService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.userInfo.UserInfoService;
import cn.pluss.platform.util.MD5Util;
import cn.pluss.platform.util.StringUtil;
import cn.pluss.platform.util.ValidateCodeUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.validation.Valid;
import java.util.*;

/**
 * @author djh
 */
@RestController
@RequestMapping("/userInfo")
@RequiredArgsConstructor
@Slf4j
@Api(value = "UserInfo控制类", tags = {"用户相关接口"})
public class UserInfoController {

    private final UserInfoService userInfoNewService;
    private final UserAppService userAppService;
    private final PhoneValidateCodeService phoneValidateCodeService;
    private final ValidateCodeUtil validateCodeUtil;

    @Setter(onMethod_ = {@Autowired})
    private RestTemplate restTemplate;

    @GetMapping({"/bind/{inviteCode}", "/bind/"})
    public Result<Object> bindInviteCode(@PathVariable(value = "inviteCode", required = false) String inviteCode) {
        if (inviteCode == null) {
            throw new MsgException("缺少邀请码");
        }

        userInfoNewService.bindInviteCode(inviteCode);
        return ResultGenerator.genSuccessResult("操作成功", "操作成功");
    }

    @GetMapping
    @ApiOperation(value = "获取全部", notes = "返回分页过后的数据", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "查询页码", paramType = "query", dataType = "Integer", defaultValue = "0"),
            @ApiImplicitParam(name = "size", value = "每页数据量", paramType = "query", dataType = "Integer", defaultValue = "0")})
    public Result<PageInfo<UserInfo>> list(@RequestParam(defaultValue = "1") Integer page,
                                           @RequestParam(defaultValue = "10") Integer size) {
        if (size == null || size == 0) {
            size = ProjectConstant.PAGE_SIZE;
        }
        if (page == null || page == 0) {
            page = 1;
        }
        Map<String, Object> map = new HashMap<>();
        map.put("pageSize", size);
        map.put("offset", (page - 1) * size);
        List<UserInfo> userInfoList = userInfoNewService.queryUserInfoPage(map);
        Integer count = userInfoNewService.queryUserInfoPageCount(map);
        // 返回参数
        PageInfo<UserInfo> pager = new PageInfo<>(count.longValue(), (long) StringUtil.getPageCount(count, size), page.longValue(), size.longValue(), userInfoList);
        return ResultGenerator.genSuccessResult(pager);
    }


//    @NoRepeatSubmit
    @PostMapping
    @ApiOperation(tags = {"页面-注册", "页面-H5注册", "页面-分享_直接开户"}, value = "用户注册", notes = "添加新的数据", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "UserInfo", value = "待添加的UserInfo实例", paramType = "body", dataType = "UserInfo", required = true)})
    public Result<Object> add(@RequestBody UserInfo userInfo) {
        String s = StringUtil.passwordCheck(userInfo.getPassword());
        if (s == null){
            return ResultGenerator.genFailResult("密码不合规");
        }
        userInfoNewService.register(userInfo);
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/verifyPhoneIsExist")
    @ApiOperation(tags = {"页面-注册", "页面-H5注册", "页面-分享注册", "页面-会员开卡", "页面-分享_直接开户"}, value = "未注册手机号并获取验证码", notes = "验证该手机号是否注册，未注册即发送验证码", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店", paramType = "String", dataType = "String", required = true),
            @ApiImplicitParam(name = "phone", value = "手机号", paramType = "String", dataType = "String", required = true),
    })
    public Result<Object> verifyPhoneIsExist(String phone) {
        if (StringUtils.isBlank(phone)) {
            return ResultGenerator.genFailResult("手机号不能为空！");
        }

        PhoneValidateCode phoneValidateCode = new PhoneValidateCode();
        phoneValidateCode.setPhone(phone);
        String checkCode = StringUtil.random(6);
        phoneValidateCode.setCode(checkCode);
        Result<Object> result = validateCodeUtil.requestValidateCodeALi(phoneValidateCode.getPhone(), checkCode);
//        if (result != null) {
//            return result;
//        }
        //根据当前手机号查询当前手机号是否有验证码信息
        phoneValidateCodeService.saveOrReplaceIfExist(phoneValidateCode);
        return ResultGenerator.genSuccessResult();
    }

    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除数据", notes = "根据id删除数据", httpMethod = "DELETE")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "查询的id实例", paramType = "path", dataType = "Integer", required = true)})
    public Result delete(@PathVariable Long id) {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfoNewService.deleteUserInfo(userInfo);
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/forgetPassword")
    @ApiOperation(tags = {"页面-忘记密码"}, value = "忘记密码", notes = "忘记密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "UserInfo", value = "更新的UserInfo实例", paramType = "body", dataType = "UserInfo", required = true),})
    public Result<Object> forgetPassword(@RequestBody UserInfo userInfo) {
        String s = StringUtil.passwordCheck(userInfo.getPassword());
        if (s == null){
            return ResultGenerator.genFailResult("密码不合规");
        }
        userInfoNewService.forgetPwd(userInfo);
        return ResultGenerator.genSuccessResult();
    }

    // 修改密码
    @PostMapping("/updatePassword")
    @ApiOperation(value = "修改密码", notes = "修改密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "UserInfo", value = "更新的UserInfo实例", paramType = "body", dataType = "UserInfo", required = true),})
    public Result updatePassword(@RequestBody UserInfo userInfo) {
        UserApp tokenUa = userAppService.queryUserAppByToken();
        if (!Objects.equals(tokenUa.getUserId(), userInfo.getId())) {
            throw new MsgException(CommonError.NO_AUTHORIZATION);
        }

        MsgException.checkNull(userInfo.getId(), "无用户id!");
        MsgException.checkBlank(userInfo.getCheckCode(), "无验证码!");

        UserInfo queryUserInfo = new UserInfo();
        queryUserInfo.setId(userInfo.getId());

        // 查询当前用户信息
        queryUserInfo = userInfoNewService.queryUserInfo(queryUserInfo);

        MsgException.checkNull(queryUserInfo, CommonError.NO_EXIST_ACCOUNT);

        // 验证原始密码
        if (!MD5Util.MD5Encode(userInfo.getOldPassword(), "utf-8").equalsIgnoreCase(queryUserInfo.getPassword())) {
            return ResultGenerator.genFailResult("原始密码错误！");
        }

        LambdaQueryWrapper<PhoneValidateCode> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(PhoneValidateCode::getPhone, queryUserInfo.getPhone())
                .orderByDesc(PhoneValidateCode::getSendDt)
                .last("limit 1");
        PhoneValidateCode existValidCode = phoneValidateCodeService.getOne(qWrapper);
        MsgException.checkNull(existValidCode, "验证码不存在或验证码已失效");

        if (!Objects.equals(existValidCode.getCode(), userInfo.getCheckCode())) {
            if (existValidCode.getAttempt() == null) {
                existValidCode.setAttempt(1);
                phoneValidateCodeService.updateById(existValidCode);
                throw new MsgException("验证码错误");
            }

            int newAttemptCount = existValidCode.getAttempt() + 1;
            if (newAttemptCount == 5) {
                // 删除验证码
                phoneValidateCodeService.removeById(existValidCode.getId());
                throw new MsgException("验证码错误，请重新获取验证码");
            }
        } else {
            // 删除验证码
            phoneValidateCodeService.removeById(existValidCode.getId());
        }

        // 修改密码
        UserInfo updateUserInfo = new UserInfo();
        updateUserInfo.setId(queryUserInfo.getId());
        updateUserInfo.setPassword(MD5Util.MD5Encode(userInfo.getPassword(), "utf-8"));
        updateUserInfo.setUpdateTime(new Date());
        userInfoNewService.updateById(updateUserInfo);

        // 修改小程序密码
        UserApp userApp = new UserApp().setUserId(updateUserInfo.getId());
        userApp = userAppService.queryUserApp(userApp);
        if (userApp != null && "promoter".equals(userApp.getUserType())) {
            String url = "https://shop.shouyinbei.net/web/wmerchant.php?c=site&a=entry&ctrl=store&ac=oauth&op=set_password&do=web&m=we7_wmall&i=1";
            url += "&password=" + updateUserInfo.getPassword();
            url += "&mobile=" + queryUserInfo.getLoginName();
            log.info("==================>修改小程序请求链接为: {}<=================", url);
            try {
                String result = restTemplate.getForObject(url, String.class);
                log.info("==================>修改小程序密码结果: {}<=================", result);
            } catch (Exception e) {
                log.info("==================>修改小程序密码异常: {}<=================", e.getMessage());
            }
        }
        // ============

        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/{loginName}/{password}")
    @ApiOperation(tags = {"页面-登录", "页面-切换商户"}, value = "登录", notes = "登录接口", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginName", value = "查询的loginName", paramType = "path", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "查询的password", paramType = "path", required = true, dataType = "String")})
    public Result<Map<String, Object>> detail(@PathVariable("loginName") String loginName, @PathVariable("password") String password) {
        Map<String, Object> login = userInfoNewService.login(loginName, password);
        return ResultGenerator.genSuccessResult(login);
    }

    // 修改手机号
    @PostMapping("/changePhone")
    @ApiOperation(value = "修改手机号", notes = "修改手机号", httpMethod = "POST")
    public Result<Object> changePhone(@Valid @RequestBody ChangePwdDTO changePwdDTO) {
        userInfoNewService.changePhone(changePwdDTO);
        return ResultGenerator.genSuccessResult();
    }

    // @PostMapping("/changeRate")
    // public Result<Object> changeRate(@RequestBody Map<String, Object>param) {
    //     userInfoNewService.apiChangeRate(param.get("userId").toString(), Integer.parseInt(param.get("rate").toString()));
    //     return ResultGenerator.genSuccessResult("修改成功，费率次日生效", null);
    // }

    @GetMapping("/userMerchantBaseInfo")
    public Result<JSONObject> getUserMerchantBaseInfo() {
        JSONObject result = userInfoNewService.getUserMerchantBaseInfo();
        return ResultGenerator.genSuccessResult(result);
    }

    @PostMapping("/savePayPassword")
    public Result<Object> savePayPassword(@RequestBody UserInfo userInfo) {
        userInfoNewService.savePayPassword(userInfo);
        return ResultGenerator.genSuccessResult("保存安全密码成功", null);
    }

    @PostMapping("/verifyPayPassword")
    public Result<Object> verifyPayPassword(@RequestBody Map<String, Object> param) {
        String payPassword = param.get("payPassword").toString();
        userInfoNewService.apiVerifyPayPassword(payPassword);
        return ResultGenerator.genSuccessResult("支付密码校验通过", null);
    }

    @OpLog(opCode = "APP_FACE_CERT", opDetail = "APP人脸识别通过", opName = "APP人脸识别结果")
    @PostMapping("/verifyFaceCert")
    public Result<Object> verifyFaceCert() {
        userInfoNewService.appVerifyFaceCert();
        return ResultGenerator.genSuccessResult("修改成功", null);
    }

    @OpLog(opCode = "APP_FACE_CERT", opDetail = "APP人脸识别失败", opName = "APP人脸识别结果")
    @PostMapping("/verifyFaceCertFail")
    public Result<Object> faceCertFail() {
        userInfoNewService.appVerifyFaceCert();
        return ResultGenerator.genSuccessResult("修改成功", null);
    }
}
