package com.ytpm.lemonios.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.ytpm.agent.enums.UserStatusEnum;
import com.ytpm.agent.model.YtDitch;
import com.ytpm.app.enums.LoginType;
import com.ytpm.app.model.YtAppDefaultConfig;
import com.ytpm.app.model.YtDyzAnswerRecord;
import com.ytpm.app.model.YtDyzLoginRecord;
import com.ytpm.app.model.YtDyzPowerRecord;
import com.ytpm.app.model.YtDyzUser;
import com.ytpm.app.param.IosLoginParam;
import com.ytpm.app.param.LoginParam;
import com.ytpm.app.param.WxLoginParam;
import com.ytpm.app.view.IosUserInfo;
import com.ytpm.app.view.WxDefaultConfig;
import com.ytpm.app.view.WxLoginResult;
import com.ytpm.app.view.WxUserInfo;
import com.ytpm.constant.StrConstant;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.handle.CustomerException;
import com.ytpm.lemonios.config.ip2Regin.IP2ReginService;
import com.ytpm.lemonios.dao.AppUserMapper;
import com.ytpm.lemonios.dao.DitchMapper;
import com.ytpm.lemonios.dao.LoginRecordMapper;
import com.ytpm.lemonios.dao.QuestionMapper;
import com.ytpm.lemonios.redis.RedisService;
import com.ytpm.lemonios.service.AppUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@RefreshScope
public class AppUserServiceImpl implements AppUserService {

    @Resource
    private AppUserMapper appUserMapper;
    @Resource
    private LoginRecordMapper loginRecordMapper;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private RedisService redisService;
    @Resource
    private DitchMapper ditchMapper;
    @Resource
    private IP2ReginService ip2ReginService;

    @Value("${risk.config.banned.tips}")
    private String tips;
    @Value("${yt.ios.appid:}")
    private String appId;

    /**
     * openid查询用户信息
     */
    @Override
    public YtDyzUser selectByOpenid(String openid,Long ditchId) {
        return appUserMapper.getYtAppUser(openid,ditchId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public YtDyzUser crudForNewTrans(WxLoginParam param, WxUserInfo wxUserInfo, WxLoginResult loginResult) {
        //处理用户注册或登录更新信息
        YtDyzUser old = appUserMapper.getYtAppUser(loginResult.getOpenid(), param.getDitchId());
        if (Objects.isNull(old)) {
            old = registryUserByWx(param, wxUserInfo, loginResult);
        } else {
            deadWithUserCrud(old, wxUserInfo, param);
        }
        //设置最后一次答题问题ID、今日答题数、历史答题数
        setExtInfo(old,wxUserInfo.getHeadimgurl());
        // 添加用户登录记录
        addLoginRecord(param,old.getUserId(), LoginType.WX);
        return old;
    }

    /**
     * 微信渠道 注册用户
     */
    private YtDyzUser registryUserByWx(WxLoginParam param, WxUserInfo wxUserInfo, WxLoginResult loginResult) {
        YtDyzUser old = new YtDyzUser();
        old.setUserId(redisService.getAppUserId());
        old.setPhone(param.getPhone());
        old.setDeviceId(param.getDeviceId());
        old.setNickName(wxUserInfo.getNickname());
        old.setLastLoginTime(new Date());
        old.setRegistryTime(new Date());
        old.setLastLoginIp(param.getLoginIp());
        old.setLastLoginIpAddress(ip2ReginService.parseIPAddress(param.getLoginIp()));
        old.setLoginDays(1);
        old.setPower(0);
        old.setTotalVideo(0);
        old.setTotalIncome(BigDecimal.ZERO);
        old.setRedPacketAmount(BigDecimal.ZERO);
        old.setRedPacketBalance(BigDecimal.ZERO);
        old.setPointsBalance(BigDecimal.ZERO);
        old.setPointsTotal(BigDecimal.ZERO);
        old.setWithdrawTotal(BigDecimal.ZERO);
        old.setSignDays(0);
        old.setDitchId(param.getDitchId());
        old.setAppId(param.getAppId());
        old.setUserStatus(UserStatusEnum.NORMAL.getCode());
        old.setWxOpenId(loginResult.getOpenid());
        old.setHeadImg(wxUserInfo.getHeadimgurl());
        //根据设备ID获取平台ID 获取不到再生成平台ID
        String platformId = appUserMapper.getByDeviceId(param.getDeviceId(),wxUserInfo.getOpenid());
        old.setPlatformId(StrUtil.isBlank(platformId)?
                (StrConstant.PLATFORM_ID_PREFIX + IdUtil.getSnowflakeNextIdStr()):platformId);
        appUserMapper.addOne(old);
        return old;
    }


    /**
     * 处理用户数据
     */
    private void deadWithUserCrud(YtDyzUser old, WxUserInfo wxUserInfo, LoginParam param) {
        //处于风控状态的用户不允许登录
        if(!UserStatusEnum.NORMAL.getCode().equals(old.getUserStatus())
                && !UserStatusEnum.VISITOR_LOCK.getCode().equals(old.getUserStatus())){
            throw new CustomerException(getTipsMsg());
        }
        YtDyzUser newUser = new YtDyzUser();
        newUser.setUserId(old.getUserId());
        newUser.setNickName(wxUserInfo.getNickname());
        newUser.setHeadImg(wxUserInfo.getHeadimgurl());
        newUser.setLastLoginTime(new Date());
        newUser.setLastLoginIp(param.getLoginIp());
        newUser.setLastLoginIpAddress(ip2ReginService.parseIPAddress(param.getLoginIp()));
        newUser.setPhone(param.getPhone());
        newUser.setDeviceId(param.getDeviceId());
        setNewLoginDays(newUser, old);
        appUserMapper.updateUser(newUser);
    }


    /**
     * 更新登陆天数
     */
    private void setNewLoginDays(YtDyzUser newUser, YtDyzUser dyzUser) {
        YtDyzLoginRecord wxLoginRecord = loginRecordMapper.getLastLoginRecord(dyzUser.getUserId(), 0);
        YtDyzLoginRecord visitorLoginRecord = loginRecordMapper.getLastLoginRecord(dyzUser.getUserId(), 1);
        if (wxLoginRecord == null && visitorLoginRecord == null
                || wxLoginRecord != null && wxLoginRecord.getLoginTime() != null
                && DateUtil.compare(wxLoginRecord.getLoginTime(), newUser.getLastLoginTime(), "yyyy-MM-dd") < 0) {
            newUser.setLoginDays(dyzUser.getLoginDays() + 1);
        }
    }


    /**
     * 设置扩展信息
     */
    private void setExtInfo(YtDyzUser old, String headImgUrl) {
        old.setHeadImg(headImgUrl);
        old.setLastQuestionId(questionMapper.getLastQuestionId(old.getUserId()));
        old.setTodayAnswerCount(questionMapper.getAnswerCount(old.getUserId(),1));
        old.setHistoryAnswerCount(questionMapper.getAnswerCount(old.getUserId(),2));
        old.setAnswerRecordList(questionMapper.getAnswerRecords(old.getUserId()));
        old.setLoginRecordList(loginRecordMapper.getLoginRecords(old.getUserId()));
        // 构建答题历史记录简易版
        List<YtDyzAnswerRecord> recordList = questionMapper.getAnswerRecords(old.getUserId());
        List<String> viewList = new ArrayList<>();
        int count = recordList.size();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        for (YtDyzAnswerRecord ytDyzAnswerRecord : recordList) {
            String timeStr = count + ":" + sdf.format(ytDyzAnswerRecord.getAnswerTime());
            count--;
            viewList.add(timeStr);
        }
        old.setAnswerRecordTimeList(viewList);
    }


    /**
     * 增加用户登录记录
     */
    private void addLoginRecord(LoginParam param, String userId, LoginType loginType) {
        YtDyzLoginRecord loginRecord = new YtDyzLoginRecord();
        loginRecord.setRecordId(IdUtil.fastSimpleUUID());
        loginRecord.setUserId(userId);
        loginRecord.setLoginTime(new Date());
        loginRecord.setDeviceBrand(param.getBrand());
        loginRecord.setDeviceModel(param.getModel());
        loginRecord.setLoginIp(param.getLoginIp());
        loginRecord.setOperator(param.getIpOperator());
        loginRecord.setIpAddr(param.getIpLocation());
        loginRecord.setPhoneJson(param.getPhoneJson());
        loginRecord.setLoginType(loginType.getTypeName());
        loginRecordMapper.insertOne(loginRecord);
    }



    @Override
    public YtDyzUser crudForNewTransIos(IosLoginParam param, IosUserInfo userInfo, LoginType loginType) {
        YtDyzUser old = appUserMapper.getYtAppUserForIos(param.getIosId(), param.getDitchId());
        // 旧包兼容 处理通过配置appid生成 ditchId为null的用户
        if (old == null) {
            old = appUserMapper.getYtAppUserAndDitchNull(param.getIosId());
        }
        if (Objects.isNull(old)) {
            old = registryUserByIos(param, userInfo);
        } else {
            deadWithUserByIos(old, userInfo, param);
            old = appUserMapper.getYtAppUserForIos(param.getIosId(), param.getDitchId());
        }
        //设置最后一次答题问题ID、今日答题数、历史答题数
        setExtInfo(old, userInfo.getHeadimgurl());
        // 添加用户登录记录
        addLoginRecord(param,old.getUserId(), loginType);
        return old;
    }


    /**
     * 注册用户
     */
    private YtDyzUser registryUserByIos(IosLoginParam param, IosUserInfo userInfo) {
        YtDyzUser old = new YtDyzUser();
        old.setUserId(redisService.getAppUserId());
        old.setPhone(param.getPhone());
        old.setDeviceId(param.getDeviceId());
        old.setNickName(userInfo.getNickname());
        old.setLastLoginTime(new Date());
        old.setRegistryTime(new Date());
        old.setLastLoginIp(param.getLoginIp());
        old.setLastLoginIpAddress(ip2ReginService.parseIPAddress(param.getLoginIp()));
        old.setLoginDays(1);
        old.setPower(0);
        old.setTotalVideo(0);
        old.setTotalIncome(BigDecimal.ZERO);
        old.setRedPacketAmount(BigDecimal.ZERO);
        old.setRedPacketBalance(BigDecimal.ZERO);
        old.setPointsBalance(BigDecimal.ZERO);
        old.setPointsTotal(BigDecimal.ZERO);
        old.setWithdrawTotal(BigDecimal.ZERO);
        old.setDitchId(param.getDitchId());
        old.setSignDays(0);
        old.setUserStatus(UserStatusEnum.NORMAL.getCode());
        old.setIosId(param.getIosId());
        old.setHeadImg(userInfo.getHeadimgurl());
        old.setAppId(appId);
        if (param.getDitchId() != null){
            YtDitch ditch = ditchMapper.selectById(param.getDitchId());
            old.setDitchId(param.getDitchId());
            old.setAppId(ditch.getAppId());
        }
        //根据设备ID获取平台ID 获取不到再生成平台ID
        String platformId = appUserMapper.getByDeviceId(param.getDeviceId(),userInfo.getOpenid());
        old.setPlatformId(StrUtil.isBlank(platformId)?
                (StrConstant.PLATFORM_ID_PREFIX + IdUtil.getSnowflakeNextIdStr()):platformId);
        appUserMapper.addOne(old);
        return old;
    }

    /**
     * 处理用户数据
     */
    private void deadWithUserByIos(YtDyzUser dyzUser, IosUserInfo userInfo, LoginParam param) {
        //处于风控状态的用户不允许登录
        if(!UserStatusEnum.NORMAL.getCode().equals(dyzUser.getUserStatus())
                && !UserStatusEnum.VISITOR_LOCK.getCode().equals(dyzUser.getUserStatus())){
            throw new CustomerException(getTipsMsg());
        }
        YtDyzUser newUser = new YtDyzUser();
        newUser.setUserId(dyzUser.getUserId());
        newUser.setNickName(userInfo.getNickname());
        newUser.setHeadImg(userInfo.getHeadimgurl());
        newUser.setLastLoginTime(new Date());
        newUser.setLastLoginIp(param.getLoginIp());
        newUser.setLastLoginIpAddress(ip2ReginService.parseIPAddress(param.getLoginIp()));
        newUser.setPhone(param.getPhone());
        newUser.setDeviceId(param.getDeviceId());
        // 更新用户渠道信息
        if (param.getDitchId() != null){
            newUser.setDitchId(param.getDitchId());
            YtDitch ditch = ditchMapper.selectById(param.getDitchId());
            newUser.setAppId(ditch.getAppId());
        }
        setNewLoginDays(newUser, dyzUser);
        appUserMapper.updateUser(newUser);
    }


    @Override
    public Result<?> addDefaultConfig(YtDitch param) {
        ditchMapper.insertOne(param);
        WxDefaultConfig lastOne = appUserMapper.getLastOne(param.getAppId());
        YtAppDefaultConfig appDefaultConfig = new YtAppDefaultConfig();
        appDefaultConfig.setConfigName(param.getDitchName());
        appDefaultConfig.setDitchId(param.getDitchId().toString());
        appDefaultConfig.setOpenId("");
        appDefaultConfig.setSecret(lastOne.getSecret());
        appDefaultConfig.setAppKey("");
        appDefaultConfig.setAppType(lastOne.getAppType());
        appDefaultConfig.setAppId(lastOne.getAppId());
        appDefaultConfig.setCanUseRoot(lastOne.getCanUseRoot());
        appDefaultConfig.setCanUseAdb(lastOne.getCanUseAdb());
        appDefaultConfig.setCanAccumulation(lastOne.getCanAccumulation());
        appDefaultConfig.setCanSimulator(lastOne.getCanSimulator());
        appDefaultConfig.setPowerWaitTime(lastOne.getPowerWaitTime());
        appDefaultConfig.setInterstitialIntervalTime(lastOne.getInterstitialIntervalTime());
        appUserMapper.saveAppConfig(appDefaultConfig);
        return Result.resultOk(RepMessage.ADD_SUCCESS);
    }

    @Override
    public void addPower(String userId) {
        appUserMapper.addOnePower(userId);
        YtDyzPowerRecord record = new YtDyzPowerRecord();
        record.setUserId(userId);
        record.setRecordId(IdUtil.fastSimpleUUID());
        record.setAddTime(new Date());
        record.setType(2);
        record.setRemark("增加体力");
        appUserMapper.addPowerRecord(record);
    }


    private String getTipsMsg(){
        String[] split = tips.split(",");
        return split[RandomUtil.randomInt(split.length)];
    }


}
