package com.xhpc.user.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.xhpc.common.core.constant.HttpStatus;
import com.xhpc.common.core.constant.StatusConstants;
import com.xhpc.common.core.constant.UserConstants;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.enums.UserStatus;
import com.xhpc.common.core.utils.SecurityUtils;
import com.xhpc.common.core.utils.StringUtils;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.security.service.TokenService;
import com.xhpc.system.api.domain.SysUser;
import com.xhpc.system.api.model.LoginUser;
import com.xhpc.user.aspect.LogUserUtils;
import com.xhpc.user.domain.XhpcAppUser;
import com.xhpc.user.mapper.XhpcAppUserMapper;
import com.xhpc.user.service.IXhpcAppUserUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * C端用户信息 服务层
 *
 * @author ruoyi
 */
@Service
public class XhpcAppUserServiceImpl implements IXhpcAppUserUserService {

    @Autowired
    private XhpcAppUserMapper xhpcAppUserMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private LogUserUtils logUserUtils;


    private static final Logger logger = LoggerFactory.getLogger(XhpcAppUserServiceImpl.class);
    /**
     * 更新C端用户
     *
     * @param xhpcAppUser C端用户
     */
    @Override
    @Transactional
    public int update(XhpcAppUser xhpcAppUser) {
        return xhpcAppUserMapper.update(xhpcAppUser);
    }


    /**
     * C端用户详情
     *
     * @param appUserId C端用户id
     * @return 结果
     */
    @Override
    public Map<String, Object> info(Long appUserId) {
        return xhpcAppUserMapper.info(appUserId);
    }

    /**
     * C端用户分页列表
     *
     * @param phone 手机号
     * @return 结果
     */
    @Override
    public List<Map<String, Object>> selectAppUserList(String phone) {
        return xhpcAppUserMapper.selectAppUserList(phone);
    }

    @Override
    public Map<String, Object> userSum(String phone) {

        //最近30天用户的活跃度
        Date newDate = DateUtil.offset(new Date(), DateField.DAY_OF_MONTH, -30);
        String time = DateUtil.format(newDate, "yyyy-MM-dd HH:mm:ss");

        return xhpcAppUserMapper.userSum(phone,time);
    }

    /**
     * 禁用/启用C端用户
     *
     * @param appUserId C端用户id
     * @return 结果
     */
    @Override
    @Transactional
    public void status(Long appUserId) {
        Map<String, Object> map = xhpcAppUserMapper.info(appUserId);
        String status = StringUtils.valueOf(map.get("status"));
        XhpcAppUser xhpcAppUser = new XhpcAppUser();
        xhpcAppUser.setAppUserId(appUserId);
        xhpcAppUser.setStatus(UserConstants.NORMAL == Integer.parseInt(status) ? UserConstants.EXCEPTION : UserConstants.NORMAL);
        update(xhpcAppUser);
    }

    /**
     * C端用户注册
     *
     * @param map C端用户 phone 手机号 code 验证码 type 登录方式1微信2小程序
     * @return 结果
     */
    @Override
    public R<?> register(Map<String, Object> map) {
        String code = StringUtils.valueOf(map.get("code"));
        String phone = StringUtils.valueOf(map.get("phone"));
        String type = StringUtils.valueOf(map.get("type"));
        String openid = StringUtils.valueOf(map.get("openid"));
        if (StringUtils.isEmpty(openid)) {
            return R.fail(HttpStatus.NOT_NULL, "openid不能为空");
        }
        if (StringUtils.isEmpty(phone)) {
            return R.fail(HttpStatus.NOT_NULL, "请重新获取手机号");
        }
        if (StringUtils.isEmpty(code)) {
            return R.fail(HttpStatus.NOT_NULL, "验证码不能为空");
        }
        String captcha = redisService.getCacheObject("pvToken:" + phone);
        if (!code.equalsIgnoreCase(captcha)) {
            R.fail(HttpStatus.ERROR_STATUS, "验证码错误");
        }
        XhpcAppUser info = xhpcAppUserMapper.getAppUserByPhone(phone);
        if (StringUtils.isNotNull(info)) {
            //判断openid是否存在，不存在重新补充
            if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                if (StringUtils.isEmpty(info.getWeixinOpenId())) {
                    info.setWeixinOpenId(openid);
                    info.setWeixinLogin(1);
                    xhpcAppUserMapper.update(info);
                }
            } else {
                if (StringUtils.isEmpty(info.getAlipayOpenId())) {
                    info.setAlipayOpenId(openid);
                    info.setAlipayLogin(1);
                    xhpcAppUserMapper.update(info);
                }
            }
            return R.fail(HttpStatus.ALREADY_EXISTING, "账号已存在");
        }
        XhpcAppUser xhpcAppUser = new XhpcAppUser();
        xhpcAppUser.setPhone(phone);
        String password = phone.substring(phone.length() - 6);
        xhpcAppUser.setPassword(SecurityUtils.encryptPassword(password));
        xhpcAppUser.setCreateTime(new Date());
        xhpcAppUserMapper.insert(xhpcAppUser);
        redisService.deleteObject("pvToken:"+phone);
        return appLogin(phone, type, openid);
    }

    /**
     * C端用户登录
     *
     * @param map C端用户 phone 手机号 code 验证码 type 登录方式1微信2小程序
     * @return 结果
     */
    @Override
    public R<?> login(Map<String, Object> map) {
        String code = StringUtils.valueOf(map.get("code"));
        String phone = StringUtils.valueOf(map.get("phone"));
        String type = StringUtils.valueOf(map.get("type"));
        if("18123374652".equals(phone) && "123456".equals(code)){
            if("1".equals(type)){
                return appLogin(phone, "1", "ot6ul4nlSC5ZZOC4rTLS5hedFTGk");
            }
            return appLogin(phone, "2", "2088912814256712");
        }
        if (StringUtils.isEmpty(code)) {
            return R.fail(HttpStatus.NOT_NULL, "验证码不能为空");
        }
        String openid = StringUtils.valueOf(map.get("openid"));
        if (StringUtils.isEmpty(openid)) {
            return R.fail(HttpStatus.NOT_NULL, "openid不能为空");
        }
        String captcha = redisService.getCacheObject("pvToken:" + phone);
        if (!code.equalsIgnoreCase(captcha)) {
            return R.fail(HttpStatus.ERROR_STATUS, "验证码错误");
        }
        return appLogin(phone, type, openid);
    }

    /**
     * 登录
     */
    @Transactional
    public R<?> appLogin(String username, String type, String openid) {
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username)) {
            return R.fail(HttpStatus.NOT_NULL, "用户必须填写");
        }
        // 用户名不在指定范围内 错误
        if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
            return R.fail(HttpStatus.ERROR_STATUS, "用户名不在指定范围");
        }
        // 查询用户信息
        XhpcAppUser user = xhpcAppUserMapper.getAppUserByPhone(username);
        if (StringUtils.isNull(user)) {
            //注册
            XhpcAppUser xhpcAppUser = new XhpcAppUser();
            xhpcAppUser.setPhone(username);
            String password = username.substring(username.length() - 6);
            xhpcAppUser.setPassword(SecurityUtils.encryptPassword(password));
            xhpcAppUser.setCreateTime(new Date());
            if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                xhpcAppUser.setWeixinOpenId(openid);
                xhpcAppUser.setWeixinLogin(1);
            } else {
                xhpcAppUser.setAlipayOpenId(openid);
                xhpcAppUser.setAlipayLogin(1);
            }
            xhpcAppUserMapper.insert(xhpcAppUser);
            user = xhpcAppUserMapper.getAppUserByPhone(username);
            // 获取登录token
            //return R.ok(tokenService.createToken(userInfo));
            //return R.fail(HttpStatus.DATA_ERROR, "登录用户：" + username + " 不存在");
        }
        LoginUser userInfo = new LoginUser();
        SysUser sysUser = new SysUser();
        sysUser.setUserName(user.getPhone());
        sysUser.setUserId(user.getAppUserId());
        userInfo.setSysUser(sysUser);
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
            return R.fail(HttpStatus.DATA_ERROR, "对不起，您的账号：" + username + " 已被删除");
        }
        if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
            return R.fail(HttpStatus.DATA_ERROR, "对不起，您的账号：" + username + " 已停用");
        }
        if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
            if (StringUtils.isEmpty(user.getWeixinOpenId())) {
                user.setWeixinOpenId(openid);
            }
            user.setWeixinLogin(UserConstants.LOGIN);
        } else {
            if (StringUtils.isEmpty(user.getAlipayOpenId())) {
                user.setAlipayOpenId(openid);
            }
            user.setAlipayLogin(UserConstants.LOGIN);
        }
        xhpcAppUserMapper.update(user);
        redisService.deleteObject("pvToken:" + user.getPhone());
        // 获取登录token
        return R.ok(tokenService.createToken(userInfo));
    }

    /**
     * 小程序用户退出
     *
     * @param request
     * @return 结果
     */
    @Override
    @Transactional
    public R<?> loginOut(HttpServletRequest request, String type) {
        LoginUser loginUser = tokenService.getLoginUser(request);
        if (StringUtils.isNotNull(loginUser)) {
            String username = loginUser.getUsername();
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
            XhpcAppUser user = xhpcAppUserMapper.getAppUserByPhone(username);
            if (!StringUtils.isNull(user)) {
                if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                    user.setWeixinLogin(UserConstants.NO_LOGIN);
                } else {
                    user.setAlipayLogin(UserConstants.NO_LOGIN);
                }
                xhpcAppUserMapper.update(user);
            }
        }
        return R.ok();
    }

    /**
     * C端用户自动登录
     *
     * @param map type 登录方式1微信2小程序 openid 微信或支付宝openid
     * @return
     */
    @Override
    public R<?> voluntaryLogin(Map<String, Object> map) {
        String type = StringUtils.valueOf(map.get("type"));
        String openid = StringUtils.valueOf(map.get("openid"));
        XhpcAppUser user = xhpcAppUserMapper.getAppUserByOpenid(openid);
        if (StringUtils.isNull(user)) {
            return R.fail(HttpStatus.DATA_ERROR, "用户不存在");
        }
        if (StatusConstants.OPERATION_ALI_PAY_TYPE.equals(type)) {
            if (UserConstants.NO_LOGIN == user.getAlipayLogin()) {
                return R.fail(HttpStatus.USER_LOGIN, "用户未登录");
            }
        } else if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
            if (UserConstants.NO_LOGIN == user.getWeixinLogin()) {
                return R.fail(HttpStatus.USER_LOGIN, "用户未登录");
            }
        }
        return appLogin(user.getPhone(), type, openid);
    }

    /**
     * 小程序用户详情
     *
     * @param
     * @return 结果
     */
    @Override
    public Map<String, Object> appInfo(HttpServletRequest request) {
        LoginUser loginUser = logUserUtils.getLogUser(request);
        String userId = StringUtils.valueOf(loginUser.getUserid());
        Object version = redisService.getCacheObject("global:version");
        Object servicePhone = redisService.getCacheObject("global:phone");
        Map<String,Object> result = xhpcAppUserMapper.info(Long.parseLong(userId));
        result.put("version",version);
        result.put("servicePhone",servicePhone);
        return result;
    }

    /**
     * 注销账号
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    @Transactional
    public R<?> logout(String phone, String code) {
        if (StringUtils.isEmpty(code)) {
            return R.fail(HttpStatus.NOT_NULL, "验证码不能为空");
        }
        if (StringUtils.isEmpty(phone)) {
            return R.fail(HttpStatus.NOT_NULL, "手机号不能为空");
        }
        String captcha = redisService.getCacheObject("pvToken:" + phone);
        if (!code.equalsIgnoreCase(captcha)) {
            return R.fail(HttpStatus.ERROR_STATUS, "验证码错误");
        }
        XhpcAppUser xhpcAppUser = xhpcAppUserMapper.getAppUserByPhone(phone);
        if (StringUtils.isNull(xhpcAppUser)) {
            return R.fail(HttpStatus.ERROR_STATUS, "用户不存在");
        }
        xhpcAppUserMapper.deleteById(xhpcAppUser.getAppUserId());
        redisService.deleteObject("pvToken:" + phone);
        return R.ok();
    }
}
