package com.ff.weijinxiao.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ff.weijinxiao.common.CommonResult;
import com.ff.weijinxiao.domain.*;
import com.ff.weijinxiao.dto.request.GetSmsCodeRequest;
import com.ff.weijinxiao.dto.request.SmsLoginRequest;
import com.ff.weijinxiao.jwt.JwtHelper;
import com.ff.weijinxiao.service.*;
import com.ff.weijinxiao.util.JsonTool;
import com.ff.weijinxiao.util.ResultTool;
import com.ff.weijinxiao.util.SmsUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.ff.weijinxiao.controller.WechatControoler.getSessionKey;

/**
 * 账号管理
 */
@RestController
@RequestMapping("/api/user")
@Api(value = "用户controller", tags = {"用户实体操作接口"})
@Slf4j
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private CUserService cUserService;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private SystemLogService systemLogService;

    @Resource
    private SmsJourService smsJourService;

    @PostMapping("/login")
    @ApiOperation(value = "用户登录接口", notes = "用户登录")
    public Map<String, Object> loginUser(@ApiParam(required = true, value = "账号") @RequestParam String account,
                                         @ApiParam(required = true, value = "密码") @RequestParam String password,
                                         HttpServletRequest request) throws Exception {
        Map<String, Object> result = new HashMap<>();
        //String temp = JwtHelper.generateToken("olNHy5J7LWeJa0WN-1HMhJQelMZ4");
        //System.out.println(temp);
        User user = userService.findUserByAccount(account);
        if (null != user) {
            if (user.getStatus() == 0) {
                return ResultTool.genFailResult(ResultTool.ErrorCode_2, "帐号异常，请联系管理员");
            }
            if (null != user.getPassword() && user.getPassword().equals(password)) {
                //普通登录
                //记录日志
                SystemLog systemLog = new SystemLog();
                systemLog.setLogUser(user.getName());
                systemLog.setLogAccount(account);
                systemLog.setLogUrl("/api/user/login");
                systemLog.setLogContent("登录系统");
                systemLog.setLogIp(getRemoteIP(request));
                systemLogService.save(systemLog);
                result.put("code", 10000);
                result.put("message", "登录成功");
                Map<String, Object> data = new HashMap<String, Object>();
                data.put("token", JwtHelper.generateToken(account));
                List<String> roles = new ArrayList<String>();
                roles.add("admin");
                data.put("roles", roles);
                data.put("account", user.getAccount());//登录账号
                data.put("name", user.getName());//登陆姓名

                result.put("data", data);
                return result;
            }
        } else {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "用户不存在");
        }
        return ResultTool.genFailResult(ResultTool.ErrorCode_1, "登录失败");

    }

    @PostMapping("/logout")
    @ApiOperation(value = "用户退出接口", notes = "用户退出")
    public Map<String, Object> loginUser(HttpServletRequest request) throws Exception {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 10000);
        return result;
    }

    @PostMapping("/changepw")
    @ApiOperation(value = "用户修改密码接口", notes = "修改密码")
    public Map<String, Object> changePassword(@ApiParam(required = true, value = "旧密码") @RequestParam String oldpassword,
                                              @ApiParam(required = true, value = "新密码") @RequestParam String newpassword,
                                              HttpServletRequest request) throws Exception {
        Map<String, Object> result = new HashMap<>();
        String token = request.getHeader("token");
        String account = JwtHelper.parseToken(token);
        User user = userService.findUserByAccount(account);
        if (null != user && null != oldpassword) {
            if (user.getPassword().equals(oldpassword)) {
                user.setPassword(newpassword);
                userService.saveUser(user);
                result.put("message", "密码修改完成");
                result.put("code", 10000);
            } else {
                result.put("code", 10001);
                result.put("message", "旧密码验证失败");
            }

        } else {
            result.put("code", 10001);
            result.put("message", "修改密码失败");
        }

        return result;
    }

    @GetMapping("/info")
    @ApiOperation(value = "用户信息获取", notes = "获取登录用户信息")
    public Map<String, Object> getInfo(HttpServletRequest request) {
        Map<String, Object> result = new HashMap<>();
        String token = request.getHeader("token");
        String account = "";
        if (null != token) {
            account = JwtHelper.parseToken(token);
            User user = userService.findUserByAccount(account);
            if (null == user) {
                result.put("code", 10003);
                result.put("message", "用户不存在");
                return result;
            }
            Map<String, Object> data = new HashMap<String, Object>();
            List<String> roles = new ArrayList<String>();
            roles.add("admin");
            data.put("roles", roles);
            data.put("name", user.getName());
            result.put("code", 10000);
            result.put("data", data);
        } else {
            result.put("code", 10002);
            result.put("message", "用户不存在");
        }

        return result;

    }


    @PostMapping("/update")
    @ApiOperation(value = "更新用户信息", notes = "更新用户信息")
    public Map<String, Object> updateUser(@RequestBody User user) {
        try {
            User orginal = userService.findById(user.getId());
            if (null == orginal) {
                return ResultTool.genFailResult(ResultTool.ErrorCode_1, "获取信息失败");
            }
            userService.saveUser(user);
            return ResultTool.genSuccessResult("修改成功");
        } catch (Exception e) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_2, "修改失败:" + e.getMessage());
        }
    }

    @PostMapping("/create")
    @ApiOperation(value = "创建用户信息", notes = "创建用户信息")
    public Map<String, Object> saveUser(@RequestBody User user, HttpServletRequest request) {
        try {
            userService.saveUser(user);
            return ResultTool.genSuccessResult("创建成功");
        } catch (Exception e) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_2, "创建失败:" + e.getMessage());
        }
    }


    @PostMapping("/delete")
    @ApiOperation(value = "删除用户信息", notes = "删除用户信息")
    public Map<String, Object> deleteUser(@ApiParam(required = true, value = "用户id") @RequestBody String jsonId) {
        Integer id = JsonTool.parseJsonIdStr(jsonId);
        if (id < 0) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "id参数错误");
        }
        User user = userService.findById(id);
        if (null == user) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "用户不存在");
        }
        user.setDeleted(1);
        userService.saveUser(user);

        return ResultTool.genSuccessResult("删除成功");
    }

    @GetMapping("/findbyid")
    @ApiOperation(value = "根据id查询用户信息", notes = "根据id查询用户信息")
    public Map<String, Object> findById(@ApiParam(required = true, value = "用户id") @RequestParam String id,
                                        HttpServletRequest request) {

        Map<String, Object> result = new HashMap<>();
        try {
            User user = userService.findById(Integer.valueOf(id));
            if (null != user) {
                result.put("data", user);
                result.put("message", "查询成功");
                result.put("code", ResultTool.SuccessCode);
            } else {
                result.put("message", "查询失败，没有结果");
                result.put("code", ResultTool.ErrorCode_1);
            }

        } catch (Exception e) {
            e.printStackTrace();
            result.put("message", "查询失败" + e.getMessage());
            result.put("code", ResultTool.ErrorCode_2);
        }

        return result;
    }


    @GetMapping("/list")
    @ApiOperation(value = "查询用户列表", notes = "查询用户列表")
    public Map<String, Object> findList(@ApiParam(required = false, value = "用户名字") @RequestParam(required = false) String userName,
                                        @ApiParam(required = false, value = "用户帐号") @RequestParam(required = false) String account,
                                        @ApiParam(required = false, value = "用户手机号码") @RequestParam(required = false) String phone,
                                        HttpServletRequest request) {

        Map<String, Object> result = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("GT_id", 0);
        param.put("EQ_deleted", 0);
        if (null != userName && userName.length() > 0) {
            param.put("LIKE_name", userName);
        }
        if (null != account && account.length() > 0) {
            param.put("EQ_account", account);
        }
        if (null != phone && phone.length() > 0) {
            param.put("EQ_phone", phone);
        }
        List<User> list = userService.findList(param);
        if (null != list && list.size() > 0) {
            result.put("data", list);
            result.put("total", list.size());
            result.put("message", "查询成功");
            result.put("code", 10000);
        } else {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "没有查询到数据");
        }

        return result;
    }

    @GetMapping("/listpage")
    @ApiOperation(value = "查询用户分页列表", notes = "查询用户分页列表")
    public Map<String, Object> findListPage(@ApiParam(required = false, value = "用户名字") @RequestParam(required = false) String name,
                                            @ApiParam(required = false, value = "用户帐号") @RequestParam(required = false) String account,
                                            @ApiParam(required = false, value = "用户手机号码") @RequestParam(required = false) String phone,
                                            @ApiParam(required = false, value = "页码 1开始") @RequestParam(required = false) Integer pageNo,
                                            @ApiParam(required = false, value = "每页显示条数 默认10") @RequestParam(required = false) Integer pageSize) {

        Map<String, Object> result = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        if (null == pageNo) {
            pageNo = 1;
        } else if (pageNo < 1) {
            pageNo = 1;
        }
        if (null == pageSize) {
            pageSize = 10;
        }
        param.put("GT_id", 0);
        param.put("EQ_deleted", 0);
        if (null != name && name.length() > 0) {
            param.put("LIKE_name", name);
        }
        if (null != account && account.length() > 0) {
            param.put("EQ_account", account);
        }
        if (null != phone && phone.length() > 0) {
            param.put("EQ_phone", phone);
        }
        Page<User> list = userService.findPage(pageNo, pageSize, param);
        if (null != list && list.getTotalElements() > 0) {
            result.put("data", list);
            result.put("message", "分页查询成功");
            result.put("code", 10000);
        } else {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "没有查询到数据");
        }

        return result;
    }


    public String getRemoteIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    @PostMapping("/wxapi/create")
    @ApiOperation(value = "注册用户信息", notes = "注册用户信息")
    public Map<String, Object> registerUser(@RequestBody UserInfo userInfo, HttpServletRequest request) {
        try {
            String token = request.getHeader("token");
            String openId = JwtHelper.parseToken(token);
            CUser cUser = cUserService.findByOpenId(openId);
            if (null == cUser) {
                return ResultTool.genFailResult(ResultTool.ErrorCode_2, "注册用户失败");
            }
            userInfoService.saveUserInfo(userInfo);
            cUser.setUserInfo(userInfo);
            return ResultTool.genSuccessResult("注册用户成功");
        } catch (Exception e) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_2, "注册用户失败:" + e.getMessage());
        }
    }

    @PostMapping("/wxapi/getSmsCode")
    @ApiOperation(value = "获取短信验证码", notes = "获取短信验证码")
    public CommonResult getSmsCode(@RequestBody GetSmsCodeRequest getSmsCodeRequest) {
        log.info("getSmsCode: {}", getSmsCodeRequest);
        try {
            String phone = getSmsCodeRequest.getPhone();
            if (StrUtil.isBlank(phone)) {
                return CommonResult.failed("手机号码不可以为空");
            }
            //检查今日发送次数
            Date compareDate = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000);
            Integer count = smsJourService.countAllByPhoneAndCreateTimeGreaterThanEqual(phone, compareDate);
            if (null != count && count > 10) {
                return CommonResult.failed("今日短信发送次数已达上限");
            }
            String smsCode = RandomUtil.randomNumbers(6);
            SmsUtil.sendSms(phone, smsCode);
            SmsJour smsJour = new SmsJour();
            smsJour.setPhone(phone);
            smsJour.setSmsCode(smsCode);
            smsJour.setIsValid(1);
            smsJourService.saveSmsJour(smsJour);
            return CommonResult.success("发送验证码成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            return CommonResult.failed();
        }
    }

    @PostMapping(value = "/wxapi/login")
    @ApiOperation(value = "手机号码登录", notes = "手机号码登录")
    public Map<String, Object> wxlogin(@RequestBody SmsLoginRequest smsLoginRequest) {
        log.info("wxlogin :" + smsLoginRequest);
        Map<String, Object> result = new HashMap<>();
        String phone = smsLoginRequest.getPhone();
        String smsCode = smsLoginRequest.getSmsCode();
        if (StrUtil.isBlank(phone) || StrUtil.isBlank(smsCode)) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "手机和短信验证码不能为空");
        }
        SmsJour smsJour = smsJourService.findByPhoneAndSmsCode(phone, smsCode);
        if (null == smsJour) {
            return ResultTool.genFailResult(ResultTool.ErrorCode_1, "短信验证码错误");
        }
        if (null != smsJour) {
            Date createTime = smsJour.getCreateTime();
            if (System.currentTimeMillis() - createTime.getTime() > 5 * 60 * 1000) {
                return ResultTool.genFailResult(ResultTool.ErrorCode_1, "验证码已过期");
            }
            if (smsJour.getIsValid() == 0) {
                return ResultTool.genFailResult(ResultTool.ErrorCode_1, "验证码已失效");
            }
        }
        String code = smsLoginRequest.getCode();
        if (StrUtil.isNotBlank(code)) {
            Map<String, Object> data = getSessionKey(code);
            log.info(data.toString());

            if (data != null && data.containsKey("openid")) {
                String openId = data.get("openid").toString();
                if (StringUtils.isBlank(openId)) {
                    return ResultTool.genFailResult(ResultTool.ErrorCode_1, "code换openId失败");
                }
                CUser cUser = cUserService.findByOpenId(openId);
                if (null == cUser) {
                    cUser = new CUser();
                    cUser.setOpenId(openId);
                    cUserService.saveCUser(cUser);
                }
                String token = JwtHelper.generateToken(openId);
                UserInfo userInfo = cUser.getUserInfo();
                if (null == userInfo) {
                    //未绑定用户或者注册
                    result.put("registed", false);
                } else {
                    result.put("registed", true);
                    Date validityTime = userInfo.getValidityTime();
                    if (null == validityTime) {
                        validityTime = DateUtil.date();
                        validityTime = addDate(validityTime, 30);
                        userInfo.setValidityTime(validityTime);
                        userInfoService.saveUserInfo(userInfo);
                    }
                }
                result.put("userinfo", userInfo);
                result.put("token", token);
                result.put("code", 10000);
                result.put("message", "code换取openId成功");
            } else {
                result.put("code", 10001);
                result.put("registed", false);
                result.put("message", "code换取openId失败");
            }
        }
        smsJour.setIsValid(0);
        smsJourService.saveSmsJour(smsJour);
        return result;

    }


    public Date addDate(Date date, long day) {
        long time = date.getTime(); // 得到指定日期的毫秒数
        day = day * 24 * 60 * 60 * 1000; // 要加上的天数转换成毫秒数
        time += day; // 相加得到新的毫秒数
        return DateUtil.date(time); // 将毫秒数转换成日期
    }

}
