package com.hzs.member.login.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hzs.common.core.constant.msg.SystemMsgConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.exception.ServiceException;
import com.hzs.common.core.utils.ServletUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.ip.IpUtils;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.domain.member.base.CuMemberShare;
import com.hzs.common.domain.member.detail.CuMemberLogin;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import com.hzs.member.base.IMemberServiceApi;
import com.hzs.member.base.dto.LoginMember;
import com.hzs.member.base.service.ICuMemberService;
import com.hzs.member.detail.service.ICuMemberLoginService;
import com.hzs.member.login.service.IMemberLoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 登录/登出服务
 *
 * @author hzs
 */
@Slf4j
@Component
public class MemberLoginServiceImpl implements IMemberLoginService {

    @Autowired
    private ICuMemberLoginService iCuMemberLoginService;
    @Autowired
    private ICuMemberService iCuMemberService;

    @DubboReference
    IMemberServiceApi iMemberServiceApi;

    /**
     * 登录
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public LoginMember login(String username, String password) {
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password)) {
            // 用户/密码必须填写
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_REQUIRED));
        }

        // 登录名转大写
        // 2024.10.15 调整，因新团队迁移，兼容大小写编号，此处去掉登录名大写转小写
//        username = username.toUpperCase();

        // 查询用户信息
        R<LoginMember> memberResult = iMemberServiceApi.getMemberInfo(username);

        if (R.FAIL == memberResult.getCode()) {
            throw new ServiceException(memberResult.getMsg());
        }

        LoginMember loginMember = memberResult.getData();

        if (StringUtils.isNull(loginMember)) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }

        CuMemberExt member = loginMember.getCuMember();
        // 2024.10.15 兼容新团队，不能在直销系统登录
        if (ESystemType.DEFAULT.getValue() != member.getSystemType()) {
            // 不是直销会员，不能登录
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在，登录系统错误");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }

        try {
            // 是否更新会员
            boolean updateFlag = false;
            LambdaUpdateWrapper<CuMember> updateWrapper = new LambdaUpdateWrapper<>();
            if (null == member.getPkVertex()) {
                // 空单注册会员，如果体系为空处理
                CuMemberExt vertexMember = iCuMemberService.queryParentVertex(member.getPkId());
                if (null != vertexMember) {
                    updateWrapper.set(CuMember::getPkVertex, vertexMember.getPkVertex());
                    updateFlag = true;
                }
            }
//            if (StringUtils.isAnyEmpty(member.getCountryCode(), member.getGlobalCode())) {
//                // 国家编码或者全球编码为空，需要处理添加进去
//                iCuMemberService.generateNumber(member, member.getPkSettleCountry());
//                updateWrapper.set(CuMember::getCountryCode, member.getCountryCode());
//                updateWrapper.set(CuMember::getGlobalCode, member.getGlobalCode());
//                updateFlag = true;
//            }
            if (updateFlag) {
                updateWrapper.eq(CuMember::getPkId, member.getPkId());
                iCuMemberService.update(updateWrapper);
            }
        } catch (Exception e) {
            log.error("会员 {} 补全 体系 错误", member.getMemberCode());
        }

        // 用户未支付状态
        if (ECustomerType.FANS.getValue() != member.getCustomerType() && EPayStatus.UNPAID.getValue() == member.getPayStatus()) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }
        // 非正常点位（死点、已注销），不能登录
        if (ECategory.NORMAL.getValue() != member.getCategory()) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "非正常用户不能进行登录");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }
        // 账户状态校验
        if (EAccountStatus.FROZEN.getValue() == member.getAccountStatus()
                || EAccountStatus.SHUT_DOWN.getValue() == member.getAccountStatus()) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户已冻结或封停");
            // 温馨提示：输入信息有误！请稍后再试！
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.ACCCOUNT_STOP, username));
        }
//        // 服务协议状态校验（中国、服务协议已终止、非0元会员，不可进行登录）
//        if (member.getPkSettleCountry().equals(CountryConstants.CHINA_COUNTRY)
//                && EExpireStatus.TERMINATED.getValue() == member.getExpireStatus()
//                && member.getPkSettleGrade() != EGrade.START_UP.getIndex()) {
//            recordLoginLog(loginMember.getPkId(), EStatus.NO, "会员服务协议已终止");
//            // 对不起，您的会员资格已到期
//            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.SERVICE_TERMINATED, username));
//        }
        // 密码校验
        if (!SecurityUtils.matchesPassword(password, member.getLoginPwd())) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户密码错误");
            // 用户不存在/密码错误
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_ERROR, username));
        }

        recordLoginLog(loginMember.getPkId(), EStatus.YES, "登录成功");
        return loginMember;
    }

    /**
     * 分享登录
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public LoginMember shareLogin(String username, String password) {
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password)) {
            // 用户/密码必须填写
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_REQUIRED));
        }
        // 查询用户信息
        R<LoginMember> memberResult = iMemberServiceApi.getShareMemberInfo(username);

        if (R.FAIL == memberResult.getCode()) {
            throw new ServiceException(memberResult.getMsg());
        }

        if (StringUtils.isNull(memberResult.getData())) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }

        LoginMember loginMember = memberResult.getData();
        CuMemberShare cuMemberShare = loginMember.getCuMemberShare();
        // 密码校验
        if (!SecurityUtils.matchesPassword(password, cuMemberShare.getLoginPwd())) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户密码错误");
            // 用户不存在/密码错误
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_ERROR, username));
        }

        // TODO 日志改为异步MQ处理
        recordLoginLog(loginMember.getPkId(), EStatus.YES, "登录成功");
        return loginMember;
    }


    /**
     * @description: 免密登录
     * @author: zhang jing
     * @date: 2023/6/6 17:15
     * @param: [username]
     * @return: com.hzs.member.base.dto.LoginMember
     **/
    @Override
    public LoginMember passwordFreelogin(String username) {
        // 查询用户信息
        R<LoginMember> memberResult = iMemberServiceApi.getMemberInfo(username);

        if (R.FAIL == memberResult.getCode()) {
            if (username.length() >= 14) {
                // 如果上树会员表中不存在，并且用户编号是14位，则查询分享会员表
                return this.passwordFreeshareLogin(username);
            } else {
                throw new ServiceException(memberResult.getMsg());
            }
        }

        if (StringUtils.isNull(memberResult.getData())) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }

        LoginMember loginMember = memberResult.getData();
        CuMemberExt member = loginMember.getCuMember();
        // 用户未支付状态
        if (ECustomerType.FANS.getValue() != member.getCustomerType() && EPayStatus.UNPAID.getValue() == member.getPayStatus()) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }
        // 非正常点位（死点、已注销），不能登录
        if (ECategory.NORMAL.getValue() != member.getCategory()) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "非正常用户不能进行登录");
            // 对不起，您的账号: %s 不能进行登录
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.ACCCOUNT_NOT_LOGIN, username));
        }
        // 账户状态校验
        if (EAccountStatus.FROZEN.getValue() == member.getAccountStatus()
                || EAccountStatus.SHUT_DOWN.getValue() == member.getAccountStatus()) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户已冻结或封停");
            // 对不起，您的账号: %s 已停用
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.ACCCOUNT_STOP, username));
        }

        // 日志改为异步MQ处理
        recordLoginLog(loginMember.getPkId(), EStatus.YES, "登录成功");
        return loginMember;
    }

    /**
     * @description: 免密 分享登录
     * @author: zhang jing
     * @date: 2023/6/6 17:04
     * @param: [username]
     * @return: com.hzs.member.base.dto.LoginMember
     **/
    @Override
    public LoginMember passwordFreeshareLogin(String username) {
        // 查询用户信息
        R<LoginMember> memberResult = iMemberServiceApi.getShareMemberInfo(username);

        if (R.FAIL == memberResult.getCode()) {
            throw new ServiceException(memberResult.getMsg());
        }

        if (StringUtils.isNull(memberResult.getData())) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在");
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }

        LoginMember loginMember = memberResult.getData();
        // TODO 日志改为异步MQ处理
        recordLoginLog(loginMember.getPkId(), EStatus.YES, "登录成功");
        return loginMember;
    }

    /**
     * 小程序登录
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public LoginMember appletLogin(String username, String password, String loginId, String source) {
        // 用户名或密码为空 错误
        if (StringUtils.isAnyBlank(username, password)) {
            // 用户/密码必须填写
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_REQUIRED));
        }

        // 查询用户信息
        R<LoginMember> memberResult = iMemberServiceApi.getMemberInfo(username);
        LoginMember loginMember = memberResult.getData();

        if (StringUtils.isNull(loginMember)) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在", loginId, source);
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }

        CuMemberExt member = loginMember.getCuMember();

        // 用户未支付状态
        if (ECustomerType.FANS.getValue() != member.getCustomerType() && EPayStatus.UNPAID.getValue() == member.getPayStatus()) {
            recordLoginLog(null, EStatus.NO, username + " 登录用户不存在", loginId, source);
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }
        // 非正常点位（死点、已注销），不能登录
        if (ECategory.NORMAL.getValue() != member.getCategory()) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "非正常用户不能进行登录", loginId, source);
            // 登录用户: %s 不存在
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_NOT_EXIST, username));
        }
        // 账户状态校验
        if (EAccountStatus.FROZEN.getValue() == member.getAccountStatus()
                || EAccountStatus.SHUT_DOWN.getValue() == member.getAccountStatus()) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户已冻结或封停", loginId, source);
            // 对不起，您的账号: %s 已停用
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.ACCCOUNT_STOP, username));
        }
        // 密码校验
        if (!SecurityUtils.matchesPassword(password, member.getLoginPwd())) {
            recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户密码错误", loginId, source);
            // 用户不存在/密码错误
            throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_ERROR, username));
        }

        // 日志改为异步MQ处理
        recordLoginLog(loginMember.getPkId(), EStatus.YES, "登录成功", loginId, source);
        return loginMember;
    }

    /**
     * 记录登录信息
     *
     * @param pkMember 用户ID
     * @param eStatus  登录状态（成功、失败）
     * @param message  消息内容
     */
    private void recordLoginLog(Long pkMember, EStatus eStatus, String message) {
        CuMemberLogin cuMemberLogin = new CuMemberLogin();
        cuMemberLogin.setPkMember(pkMember);
        HttpServletRequest httpServletRequest = ServletUtils.getRequest();
        cuMemberLogin.setLoginId(IpUtils.getIpAddr(httpServletRequest));
        cuMemberLogin.setLoginDevice(ServletUtils.getHeader(httpServletRequest, "source"));
        cuMemberLogin.setStatus(eStatus.getValue());
        cuMemberLogin.setMessage(message);
        // 保存登录日志
        iCuMemberLoginService.save(cuMemberLogin);
    }

    /**
     * 记录登录信息
     *
     * @param pkMember 用户ID
     * @param eStatus  登录状态（成功、失败）
     * @param message  消息内容
     * @param loginId  登录IP
     * @param source   登录来源
     */
    private void recordLoginLog(Long pkMember, EStatus eStatus, String message, String loginId, String source) {
        CuMemberLogin cuMemberLogin = new CuMemberLogin();
        cuMemberLogin.setPkMember(pkMember);
        cuMemberLogin.setLoginId(StringUtils.isNotEmpty(loginId) ? loginId : "0.0.0.0");
        cuMemberLogin.setLoginDevice(source);
        cuMemberLogin.setStatus(eStatus.getValue());
        cuMemberLogin.setMessage(message);
        // 保存登录日志
        iCuMemberLoginService.save(cuMemberLogin);
    }

}
