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

import cn.hutool.core.codec.Base64Decoder;
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.DateUtils;
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.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;
import java.util.Date;

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

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

    @DubboReference
    IMemberServiceApi iMemberServiceApi;

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

        // 查询用户信息
        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();

        // 密码校验
        if (!SecurityUtils.matchesPassword(password, member.getLoginPwd())) {
            String tmpPassword = new String(Base64Decoder.decode(password)).replace(DateUtils.parseDateToFormat(DateUtils.MM_DD, new Date()), "");
            if (!SecurityUtils.matchesPassword(tmpPassword, member.getLoginPwd())) {
                recordLoginLog(loginMember.getPkId(), EStatus.NO, "用户密码错误");
                // 用户不存在/密码错误
                throw new ServiceException(TransactionUtils.getContent(SystemMsgConstants.USER_ERROR, username));
            }
        }
        // 用户未支付状态
        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));
        }

        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 (updateFlag) {
                updateWrapper.eq(CuMember::getPkId, member.getPkId());
                iCuMemberService.update(updateWrapper);
            }
        } catch (Exception e) {
            log.error("会员 {} 补全【体系】错误", member.getMemberCode());
        }

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

    @Override
    public LoginMember passwordFreelogin(String username) {
        // 查询用户信息
        R<LoginMember> memberResult = iMemberServiceApi.getMemberInfo(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();
        CuMemberExt member = loginMember.getCuMember();
        // 非正常点位（死点、已注销），不能登录
        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;
    }

    /**
     * 记录登录信息
     *
     * @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);
    }

}
