package com.ytpm.question.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ytpm.agent.enums.AdRecordEnum;
import com.ytpm.agent.enums.UserStatusEnum;
import com.ytpm.app.enums.LoginType;
import com.ytpm.app.model.YtDyzLoginRecord;
import com.ytpm.app.model.YtDyzUser;
import com.ytpm.app.param.DyzAdRecordParam;
import com.ytpm.app.param.LoginParam;
import com.ytpm.app.param.VisitorLoginParam;
import com.ytpm.app.view.WxDefaultConfig;
import com.ytpm.constant.StrConstant;
import com.ytpm.feign.RiskFeign;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.handle.AbstractLoginService;
import com.ytpm.handle.CommonException;
import com.ytpm.handle.CustomerException;
import com.ytpm.question.dao.AppUserMapper;
import com.ytpm.question.dao.LoginRecordMapper;
import com.ytpm.question.dao.QuestionMapper;
import com.ytpm.question.redis.RedisService;
import com.ytpm.question.service.AdService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 游客登陆 回调实现类
 *
 * @author lih
 * @date 2025/9/4
 */

@Slf4j
@Component
public class VisitorLoginServiceImpl extends AbstractLoginService {

    @Resource
    private AppUserMapper appUserMapper;
    @Resource
    private LoginRecordMapper loginRecordMapper;
    @Resource
    private QuestionMapper questionMapper;
    @Resource
    private RiskFeign riskFeign;
    @Resource
    private RedisService redisService;
    @Resource
    private AdService adService;

    @Override
    protected WxDefaultConfig getLoginConfig(Integer appType) {
        if (appType == null) {
            throw new CommonException("appType is null");
        }
        return appUserMapper.getDefaultConfig(appType);
    }

    @Override
    protected YtDyzUser queryUserByDeviceAndDitch(String deviceId, Long ditchId) {
        return appUserMapper.getByDeviceAndDitch(deviceId, ditchId);
    }

    @Override
    protected LoginType getLoginType() {
        return LoginType.VISITOR;
    }

    @Override
    protected void updateUserStatus(YtDyzUser ytDyzUser, UserStatusEnum statusEnum, String reason) {
        if (ytDyzUser != null) {
            YtDyzUser newUser = new YtDyzUser();
            newUser.setUserId(ytDyzUser.getUserId());
            newUser.setUserStatus(statusEnum.getCode());
            newUser.setRiskReason(reason);
            if (UserStatusEnum.NORMAL == statusEnum) {
                newUser.setRiskReason("");
            }
            appUserMapper.updateUser(newUser);
        }
    }

    @Override
    protected void validateParams(LoginParam loginParam, HttpServletRequest request) {
        // deviceId空值处理
        if (StrUtil.isEmpty(loginParam.getDeviceId())) {
            log.warn("[visitor login validate]deviceId is empty!");
            // 尝试从phoneJson中获取
            if (StrUtil.isNotEmpty(loginParam.getPhoneJson())) {
                JSONObject phoneJson = JSONObject.parseObject(loginParam.getPhoneJson());
                if (phoneJson.get("device_basic") != null) {
                    String deviveId = phoneJson.getJSONObject("device_basic").getString("device_id");
                    loginParam.setDeviceId(deviveId);
                }
            }
        }
        if (StrUtil.isNotEmpty(loginParam.getRequestId())) {
            log.info("[visitor login validate]requestId check...");
            // 游客登陆幂等校验
            String redisKey = StrUtil.format("visitor:requestId:{}:{}:{}", loginParam.getDitchId(),
                    loginParam.getAppType(), loginParam.getDeviceId());
            if (!redisService.hasKey(redisKey)) {
                throw new IllegalArgumentException("重复请求");
            }
            String cacheKey = redisService.getStr(redisKey);
            if (!StrUtil.equals(cacheKey, loginParam.getRequestId())) {
                throw new IllegalArgumentException("重复请求");
            }
            redisService.del(redisKey);
        }
    }

    @Override
    protected List<YtDyzUser> queryDyzUserByParam(LoginParam loginParam, Map<String, Object> thirdPartyLoginInfo) {
        return appUserMapper.getLastRegistryUser(loginParam.getDeviceId());
    }

    @Override
    protected YtDyzUser registryUser(LoginParam loginParam, YtDyzUser user, Map<String, Object> paramMap) {
        user.setUserId(redisService.getAppUserId());
        user.setPhone(loginParam.getPhone());
        user.setDeviceId(loginParam.getDeviceId());
        user.setNickName("visitor_" + RandomUtil.randomString(10));
        user.setLastLoginTime(new Date());
        user.setRegistryTime(new Date());
        user.setLastLoginIp(loginParam.getLoginIp());
        user.setLoginDays(1);
        user.setPower(0);
        user.setTotalVideo(0);
        user.setTotalIncome(BigDecimal.ZERO);
        user.setRedPacketAmount(BigDecimal.ZERO);
        user.setRedPacketBalance(BigDecimal.ZERO);
        user.setPointsBalance(BigDecimal.ZERO);
        user.setPointsTotal(BigDecimal.ZERO);
        user.setWithdrawTotal(BigDecimal.ZERO);
        user.setDitchId(loginParam.getDitchId());
        user.setSignDays(0);
        user.setAppId(loginParam.getAppId());
        user.setUserStatus(UserStatusEnum.NORMAL.getCode());
        String platformId = appUserMapper.getPlatformByDeviceId(loginParam.getDeviceId());
        user.setPlatformId(StrUtil.isBlank(platformId) ?
                (StrConstant.PLATFORM_ID_PREFIX + IdUtil.getSnowflakeNextIdStr()) : platformId);
        appUserMapper.addOne(user);
        return user;
    }

    @Override
    protected void deadWithUserCrud(LoginParam loginParam, YtDyzUser old, Map<String, Object> paramMap) {
        YtDyzUser newUser = new YtDyzUser();
        newUser.setUserId(old.getUserId());
        newUser.setLastLoginTime(new Date());
        newUser.setLastLoginIp(loginParam.getLoginIp());
        newUser.setPhone(loginParam.getPhone());
        newUser.setDeviceId(loginParam.getDeviceId());
        //如果当前登录是本日第一次登录则登录天数+1
//        int loginCount = loginRecordMapper.getTodayLoginCount(old.getUserId());
//        if (loginCount < 1) {
//            newUser.setLoginDays(old.getLoginDays() + 1);
//        }
        appUserMapper.updateUser(newUser);
    }

    @Override
    protected void saveLoginRecord(YtDyzLoginRecord loginRecord) {
        loginRecordMapper.insertOne(loginRecord);
    }

    @Override
    protected Result<?> remoteCheckLoginRisk(YtDyzUser ytDyzUser) {
        return riskFeign.checkLoginRisk(ytDyzUser);
    }

    @Override
    protected Result<?> remoteCheckRegRisk(YtDyzUser user) {
        return riskFeign.checkRegRisk(user);
    }

    /**
     * 设置扩展信息
     */
    @Override
    protected void setExtInfo(YtDyzUser old, Map<String, Object> paramMap) {
        super.setExtInfo(old, paramMap);
        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()));
    }


    // 仅保存登陆时的三条广告信息 并传入登陆实体用于后续 risk风控校验
    protected void saveVisitorAdRecord(YtDyzUser ytDyzUser, LoginParam loginParam, WxDefaultConfig defaultConfig) {
        super.saveVisitorAdRecord(ytDyzUser, loginParam, defaultConfig);
        VisitorLoginParam visitorLoginParam = (VisitorLoginParam) loginParam;
        List<DyzAdRecordParam> preAdList = visitorLoginParam.getPreAdList();
        // 保存登陆前传递的广告记录
        List<String> adRecordIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(preAdList)) {
            BigDecimal totalRevenue = BigDecimal.ZERO;
            for (DyzAdRecordParam adRecordParam : preAdList) {
                if (adRecordParam == null) {
                    continue;
                }
                adRecordParam.setUserId(ytDyzUser.getUserId());
                adRecordParam.setNickName(ytDyzUser.getNickName());
                adRecordParam.setAppId(ytDyzUser.getAppId());
                adRecordParam.setLoginStatus(AdRecordEnum.LOGIN_BEFORE.getCode());
                String recordId = adService.saveRecordAndChangeUser(adRecordParam, ytDyzUser);
                adRecordIds.add(recordId);
                totalRevenue = adRecordParam.getRevenue() == null ? totalRevenue : totalRevenue.add(adRecordParam.getRevenue());
            }
            log.info(StrUtil.format("[visitor adRecords] userId:{} recordCount:{} revenue:{} ",
                    ytDyzUser.getUserId(), adRecordIds.size(), totalRevenue));
        }
        if(CollUtil.isEmpty(adRecordIds)) {
            throw new CustomerException(StrUtil.emptyToDefault(defaultConfig.getLowValueTip(), RepMessage.RISK_VISITOR_LOWER_VALUE));
        }
        ytDyzUser.setPreAdRecordList(adService.queryRecordByIds(adRecordIds));
    }

}