package com.liquidnet.service.adam.service.impl;

import com.liquidnet.common.third.secureaccess.biz.NiaAuthBiz;
import com.liquidnet.common.third.secureaccess.model.NiaAuthRequest;
import com.liquidnet.common.third.secureaccess.model.NiaAuthResult;
import com.liquidnet.common.third.secureaccess.util.NiaPidUtils;
import com.liquidnet.service.adam.constant.AdamTpaConst;
import com.liquidnet.service.adam.dto.AdamNiaLoginParam;
import com.liquidnet.service.adam.dto.vo.AdamLoginInfoVo;
import com.liquidnet.service.adam.dto.vo.AdamNiaUnboundVo;
import com.liquidnet.service.adam.dto.vo.AdamUserInfoVo;
import com.liquidnet.service.adam.service.AdamRdmService;
import com.liquidnet.service.adam.service.IAdamNiaLoginService;
import com.liquidnet.service.adam.support.AdamUserSessionSupport;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
@RequiredArgsConstructor
public class AdamNiaLoginServiceImpl implements IAdamNiaLoginService {

    private final NiaAuthBiz niaAuthBiz;
    private final AdamRdmService adamRdmService;
    private final AdamUserSessionSupport adamUserSessionSupport;

    @Override
    public ResponseDto<?> login(AdamNiaLoginParam param) {
        if (!niaAuthBiz.isReady()) {
            return ResponseDto.failure("10005", "网证认证服务暂未开通，请稍后再试");
        }

        log.info("[nia-login] 请求 bizSeq={}, idCardAuthDataLen={}",
                param.getBizSeq(), param.getIdCardAuthData() == null ? 0 : param.getIdCardAuthData().length());

        NiaAuthResult authResult = niaAuthBiz.authenticate(NiaAuthRequest.builder()
                .bizSeq(param.getBizSeq())
                .idCardAuthData(param.getIdCardAuthData())
                .build());

        if (!authResult.isSuccess()) {
            log.warn("[nia-login] 认证失败 bizSeq={}, stage={}, code={}, desc={}",
                    param.getBizSeq(),
                    authResult.getStage(),
                    authResult.getResultCode(),
                    authResult.getResultDesc());
            String errMsg = authResult.getResultDesc() != null && !authResult.getResultDesc().isEmpty()
                    ? authResult.getResultDesc() : "网证认证失败，请重试";
            return ResponseDto.failure("10005", errMsg);
        }
        if (!NiaPidUtils.isValidOpenId(authResult.getOpenId())) {
            log.warn("[nia-login] PID标识解析失败 bizSeq={}", param.getBizSeq());
            return ResponseDto.failure("10005", "网证认证失败，请重试");
        }

        String openId = authResult.getOpenId();
        String uid = adamRdmService.getUidByPlatformOpenId(AdamTpaConst.PLATFORM_NIA, openId);
        if (uid == null || uid.isEmpty()) {
            AdamNiaUnboundVo unboundVo = AdamNiaUnboundVo.builder()
                    .platform(AdamTpaConst.PLATFORM_NIA)
                    .openId(openId)
                    .build();
            log.info("[nia-login] 未绑定 bizSeq={}, bizSerialNo={}, openId={}",
                    param.getBizSeq(), authResult.getBizSerialNo(), openId);
            return ResponseDto.failure(ErrorMapping.get("10006"), unboundVo);
        }

        AdamUserInfoVo userInfoVo = adamRdmService.getUserInfoVoByUid(uid);
        if (userInfoVo == null || userInfoVo.getState() == 2) {
            log.warn("[nia-login] cancelled openId={}", openId);
            return ResponseDto.failure(ErrorMapping.get("10024"));
        }

        AdamLoginInfoVo loginInfoVo = AdamLoginInfoVo.getNew();
        loginInfoVo.setUserInfo(userInfoVo);
        loginInfoVo.setUserMemberVo(adamRdmService.getUserMemberVoByUid(uid));
        loginInfoVo.setToken(adamUserSessionSupport.issueToken(userInfoVo));

        log.info("[nia-login] LOGIN uid={}, openId={}", uid, openId);
        return ResponseDto.success(loginInfoVo);
    }
}
