package com.xhpc.user.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.xhpc.common.api.UserTypeService;
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.core.web.domain.AjaxResult;
import com.xhpc.common.core.web.service.BaseService;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.security.service.TokenService;
import com.xhpc.common.util.LogUserUtils;
import com.xhpc.common.util.UserTypeUtil;
import com.xhpc.system.api.domain.SysUser;
import com.xhpc.system.api.model.LoginUser;
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 extends BaseService implements IXhpcAppUserUserService {

    @Autowired
    private XhpcAppUserMapper xhpcAppUserMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private LogUserUtils logUserUtils;

    @Autowired
    private UserTypeService userTypeService;


    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(HttpServletRequest request,String phone) {
        LoginUser logUser = logUserUtils.getLogUser(request);
        startPage();
        return xhpcAppUserMapper.selectAppUserList(phone,logUser.getTenantId());
    }

    @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"));
        String tenantId = StringUtils.valueOf(map.get("tenantId"));
        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);
                }
            }
            //添加最后一次登录数据
            xhpcAppUserMapper.addUserLoginTime(info.getAppUserId(),info.getPhone(),UserTypeUtil.USER_TYPE,openid,Integer.valueOf(type),null,tenantId,new Date());
            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());
        xhpcAppUser.setTenantId(tenantId);
        xhpcAppUserMapper.insert(xhpcAppUser);
        redisService.deleteObject("pvToken:"+phone);
        return appLogin(phone, type, openid, tenantId);
    }

    /**
     * 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"));
        String tenantId = StringUtils.valueOf(map.get("tenantId"));
        if("18123374652".equals(phone) && "123456".equals(code)){
            if("1".equals(type)){
                return appLogin(phone, "1", "ot6ul4nlSC5ZZOC4rTLS5hedFTGk", tenantId);
            }
            return appLogin(phone, "2", "2088912814256712", tenantId);
        }
        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, tenantId);
    }

    /**
     * 登录
     */
    @Transactional
    public R<?> appLogin(String username, String type, String openid, String tenantId) {
        // 用户名或密码为空 错误
        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, "用户名不在指定范围");
        }

        //判断账号
        String sub = username.substring(0, 2);
        if (UserTypeUtil.COMMUNIT.equals(sub) || UserTypeUtil.CUSTOMERS.equals(sub)){
            R user = userTypeService.getUser(username, null, null, null,tenantId);
            if(user !=null && user.getData() !=null){
                Map<String, Object> map = (Map<String, Object>)user.getData();
                LoginUser userInfo = new LoginUser();
                SysUser sysUser = new SysUser();
                sysUser.setUserName(username);
                long appUserId = Long.parseLong(map.get("appUserId").toString());
                sysUser.setUserId(appUserId);
                userInfo.setSysUser(sysUser);
                userInfo.setUsername(username);
                userInfo.setOpenId(openid);
                userInfo.setTenantId(map.get("tenantId").toString());
                if(UserTypeUtil.COMMUNIT.equals(username.substring(0,2))){
                    userInfo.setUserType(UserTypeUtil.COMMUNIT_TYPE);
                    userInfo.setUserTypeUtil(UserTypeUtil.COMMUNIT);
                }else{
                    userInfo.setUserType(UserTypeUtil.CUSTOMERS_TYPE);
                    userInfo.setUserTypeUtil(UserTypeUtil.CUSTOMERS);
                }
                if(UserTypeUtil.COMMUNIT.equals(sub)){
                    if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                        xhpcAppUserMapper.updateCommunityPersonnel(appUserId,openid,null,UserConstants.LOGIN,null);
                    } else {
                        xhpcAppUserMapper.updateCommunityPersonnel(appUserId,null,openid,null,UserConstants.LOGIN);
                    }
                }else{
                    if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                        xhpcAppUserMapper.updateCustomersPersonnel(appUserId,openid,null,UserConstants.LOGIN,null);
                    } else {
                        xhpcAppUserMapper.updateCustomersPersonnel(appUserId,null,openid,null,UserConstants.LOGIN);
                    }
                }
               //添加最后一次登录数据
                xhpcAppUserMapper.addUserLoginTime(appUserId,username,userInfo.getUserType(),openid,Integer.valueOf(type),null,tenantId,new Date());

                redisService.deleteObject("pvToken:" + username);
                // 获取登录token
                return R.ok(tokenService.createToken(userInfo));
            }else{
                return R.fail(HttpStatus.DATA_ERROR, "账号不正确，请重新输入");
            }
        }
        // 查询用户信息
        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);
            }
            xhpcAppUser.setTenantId(tenantId);
            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);
        userInfo.setUserType(UserTypeUtil.USER_TYPE);
        userInfo.setUsername(username);
        userInfo.setOpenId(openid);
        userInfo.setUserid(user.getAppUserId());
        userInfo.setTenantId(tenantId);
        userInfo.setUserTypeUtil(UserTypeUtil.USER);
        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());

        //添加最后一次登录数据
        xhpcAppUserMapper.addUserLoginTime(user.getAppUserId(),username,userInfo.getUserType(),openid,Integer.valueOf(type),UserConstants.LOGIN,tenantId,new Date());
        // 获取登录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();
            Integer userType = loginUser.getUserType();
            Long userid = loginUser.getUserid();
            String openId = loginUser.getOpenId();
            String tenantId = loginUser.getTenantId();
            R user = userTypeService.getUser(null, userid, userType, null,tenantId);
            if(user !=null && user.getData() !=null){
                if(UserTypeUtil.USER_TYPE==userType){
                    XhpcAppUser appUser = xhpcAppUserMapper.getAppUserByPhone(username);
                    if (!StringUtils.isNull(appUser)) {
                        if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                            appUser.setWeixinLogin(UserConstants.NO_LOGIN);
                        } else {
                            appUser.setAlipayLogin(UserConstants.NO_LOGIN);
                        }
                        xhpcAppUserMapper.update(appUser);
                        //添加最后一次登录数据
                        xhpcAppUserMapper.addUserLoginTime(appUser.getAppUserId(),username,userType,openId,Integer.valueOf(type),UserConstants.NO_LOGIN,tenantId,new Date());
                    }
                }else if(UserTypeUtil.COMMUNIT_TYPE.equals(userType)){
                    if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                        xhpcAppUserMapper.updateCommunityPersonnel(userid,null,null,UserConstants.NO_LOGIN,null);
                    } else {
                        xhpcAppUserMapper.updateCommunityPersonnel(userid,null,null,null,UserConstants.NO_LOGIN);
                    }
                    //添加最后一次登录数据
                    xhpcAppUserMapper.addUserLoginTime(userid,username,userType,openId,Integer.valueOf(type),UserConstants.NO_LOGIN,tenantId,new Date());
                }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(userType)){
                    if (StatusConstants.OPERATION_WX_TYPE.equals(type)) {
                        xhpcAppUserMapper.updateCustomersPersonnel(userid,null,null,UserConstants.NO_LOGIN,null);
                    } else {
                        xhpcAppUserMapper.updateCustomersPersonnel(userid,null,null,null,UserConstants.NO_LOGIN);
                    }
                    //添加最后一次登录数据
                    xhpcAppUserMapper.addUserLoginTime(userid,username,userType,openId,Integer.valueOf(type),UserConstants.NO_LOGIN,tenantId,new Date());
                }
            }
            // 删除用户缓存记录
            tokenService.delLoginUser(loginUser.getToken());
        }
        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"));
        String tenantId = StringUtils.valueOf(map.get("tenantId"));
        Map<String, Object> userLoginTime = xhpcAppUserMapper.getUserLoginTime(Integer.valueOf(type), openid,tenantId);
        if(userLoginTime ==null){
            return R.fail(HttpStatus.USER_LOGIN, "请重新登录");
        }
        if(UserConstants.NO_LOGIN.equals(userLoginTime.get("status").toString())){
            return R.fail(HttpStatus.USER_LOGIN, "请重新登录");
        }
        return appLogin(userLoginTime.get("account").toString(), type, openid, tenantId);
    }

    /**
     * 小程序用户详情
     * @param
     * @return 结果
     */
    @Override
    public AjaxResult appInfo(HttpServletRequest request) {
        LoginUser loginUser = logUserUtils.getLogUser(request);
        Object version = redisService.getCacheObject("global:version");
        Object servicePhone = redisService.getCacheObject("global:phone");
        //根据不同的用户类型查询不同的信息
        Long userid = loginUser.getUserid();
        Integer userType = loginUser.getUserType();
        R user = userTypeService.getUser(null, loginUser.getUserid(), loginUser.getUserType(), null,loginUser.getTenantId());
        if(user !=null && user.getData() !=null){
            Map<String, Object> map = (Map<String, Object>)user.getData();
            //发票、留言板、版本、客服电话
            String invoice =null;
            if(UserTypeUtil.USER_TYPE.equals(userType)){
                 invoice = redisService.getCacheObject("global:invoice:" + UserTypeUtil.USER + userid);
            }else if(UserTypeUtil.INTERNET_TYPE.equals(userType)){
                 invoice = redisService.getCacheObject("global:invoice:"+UserTypeUtil.INTERNET+userid);
            }else if(UserTypeUtil.COMMUNIT_TYPE.equals(userType)){
                invoice = redisService.getCacheObject("global:invoice:"+UserTypeUtil.COMMUNIT+userid);
            }else{
                invoice = redisService.getCacheObject("global:invoice:"+UserTypeUtil.CUSTOMERS+userid);
            }
            if(invoice==null){
                map.put("invoiceNumber","0");
            }else{
                map.put("invoiceNumber",invoice);
            }
            String guestbook =null;
            if(UserTypeUtil.USER_TYPE.equals(userType)){
                guestbook = redisService.getCacheObject("userNotReadMessageCount:" + UserTypeUtil.USER_TYPE + ":" + map.get("phone").toString() + ":0:" + loginUser.getTenantId());
            }else if(UserTypeUtil.INTERNET_TYPE.equals(userType)){
                guestbook = redisService.getCacheObject("userNotReadMessageCount:" + UserTypeUtil.INTERNET_TYPE + ":" + map.get("phone").toString() + ":0:" + loginUser.getTenantId());
            }else if(UserTypeUtil.COMMUNIT_TYPE.equals(userType)){
                guestbook = redisService.getCacheObject("userNotReadMessageCount:" + UserTypeUtil.COMMUNIT_TYPE + ":" + map.get("account").toString() + ":0:" + loginUser.getTenantId());
            }else{
                guestbook = redisService.getCacheObject("userNotReadMessageCount:" + UserTypeUtil.CUSTOMERS_TYPE + ":" + map.get("account").toString() + ":0:" + loginUser.getTenantId());
            }
            map.put("guestbook",guestbook);
            map.put("version",version);
            map.put("servicePhone",servicePhone);
            map.put("activity",1);
            map.put("activitySize",1);
            map.put("activityImg","https://xhpc-bucket1.oss-cn-hangzhou.aliyuncs.com/bunengshanchu/1.png");
            map.put("socSize",redisService.getCacheObject("global:SOC"));

            return AjaxResult.success(map);
        }else{
            return AjaxResult.error("请重新登录");
        }
    }

    /**
     * 注销账号
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    @Transactional
    public R<?> logout(HttpServletRequest request,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, "验证码错误");
        }
        LoginUser loginUser = tokenService.getLoginUser(request);
        Long userid = loginUser.getUserid();
        Integer userType = loginUser.getUserType();
        String tenantId = loginUser.getTenantId();
        if(UserTypeUtil.USER_TYPE.equals(userType)){
            XhpcAppUser xhpcAppUser = xhpcAppUserMapper.getAppUserByPhone(phone);
            if (StringUtils.isNull(xhpcAppUser)) {
                return R.fail(HttpStatus.ERROR_STATUS, "用户不存在");
            }
            xhpcAppUserMapper.deleteById(xhpcAppUser.getAppUserId());
        }else{
            return R.fail(HttpStatus.ERROR_STATUS, "用户不能注销");
        }
        redisService.deleteObject("pvToken:" + phone);
        return R.ok();
    }

    @Override
    public R<?> updateIsRefund(Long userId, Integer userType, Integer isRefund) {

        if(isRefund>2 || isRefund<0){
            return R.fail(HttpStatus.ERROR_STATUS, "参数错误");
        }
        if(userType==0){
            int i = xhpcAppUserMapper.updateUserIsRefund(userId, isRefund);
            if(i>0){
                return R.ok();
            }else{
                return R.fail(HttpStatus.ERROR_STATUS, "修改失败");
            }
        }else if(userType==2){
            int i = xhpcAppUserMapper.updateCommunityIsRefund(userId, isRefund,null,null);
            if(i>0){
                return R.ok();
            }else{
                return R.fail(HttpStatus.ERROR_STATUS, "修改失败");
            }
        }
        return R.fail(HttpStatus.ERROR_STATUS, "参数错误");
    }

    @Override
    public R<?> batteryProtect(HttpServletRequest request, Integer soc,Integer socProtect,Integer userType) {
        LoginUser loginUser = logUserUtils.getLogUser(request);
        //根据不同的用户类型查询不同的信息
        Long userid = loginUser.getUserid();
        R user = userTypeService.getUser(null, loginUser.getUserid(), loginUser.getUserType(), null,loginUser.getTenantId());
        if(user !=null && user.getData() !=null){
            Map<String, Object> map = (Map<String, Object>)user.getData();
            if(UserTypeUtil.USER_TYPE.equals(userType)){
                XhpcAppUser appUser = xhpcAppUserMapper.getAppUserByPhone(map.get("phone").toString());
                appUser.setSocProtect(socProtect);
                appUser.setSoc(soc);
                xhpcAppUserMapper.update(appUser);
            }else if(UserTypeUtil.COMMUNIT_TYPE.equals(userType)){
                xhpcAppUserMapper.updateCommunityIsRefund(userid, null,socProtect,soc);
            }else if(UserTypeUtil.CUSTOMERS_TYPE.equals(userType)){
                xhpcAppUserMapper.updateCustomersSocProtect(userid,socProtect,soc);
            }
            return R.fail(HttpStatus.SUCCESS, "设置成功");
        }
        return R.fail(HttpStatus.ERROR_STATUS, "设置失败");
    }


}
