package com.liquidnet.client.admin.zhengzai.adam.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.liquidnet.client.admin.zhengzai.adam.service.IAdamCaomeiPassportAdminService;
import com.liquidnet.common.cache.redis.util.RedisDataSourceUtil;
import com.liquidnet.service.adam.constant.AdamRedisConst;
import com.liquidnet.service.adam.dto.AdamCaomeiPassportListDto;
import com.liquidnet.service.adam.dto.AdamCaomeiPassportUserBadgeDto;
import com.liquidnet.service.adam.dto.param.AdamCaomeiPassportSearchParam;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportBadgeItemVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportDetailVo;
import com.liquidnet.service.adam.dto.vo.AdamCaomeiPassportListVo;
import com.liquidnet.service.adam.entity.AdamCaomeiPassport;
import com.liquidnet.service.adam.entity.AdamRealName;
import com.liquidnet.service.adam.entity.AdamUser;
import com.liquidnet.service.adam.entity.AdamUserInfo;
import com.liquidnet.service.adam.mapper.AdamCaomeiBadgeMapper;
import com.liquidnet.service.adam.mapper.AdamCaomeiPassportMapper;
import com.liquidnet.service.adam.mapper.AdamRealNameMapper;
import com.liquidnet.service.adam.mapper.AdamUserInfoMapper;
import com.liquidnet.service.adam.mapper.AdamUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AdamCaomeiPassportAdminServiceImpl implements IAdamCaomeiPassportAdminService {

    @Autowired
    private AdamCaomeiPassportMapper adamCaomeiPassportMapper;
    @Autowired
    private AdamUserMapper adamUserMapper;
    @Autowired
    private AdamUserInfoMapper adamUserInfoMapper;
    @Autowired
    private AdamRealNameMapper adamRealNameMapper;
    @Autowired
    private AdamCaomeiBadgeMapper adamCaomeiBadgeMapper;
    @Autowired
    private RedisDataSourceUtil redisDataSourceUtil;

    @Override
    public PageInfo<AdamCaomeiPassportListVo> listPassports(AdamCaomeiPassportSearchParam param) {
        if (param == null) {
            param = new AdamCaomeiPassportSearchParam();
        }
        List<AdamCaomeiPassportListDto> rows = adamCaomeiPassportMapper.selectPassportAdminList(
                param.getPassportNo(),
                param.getUserName(),
                param.getMobile(),
                param.getIdCard(),
                param.getBindStatus()
        );
        PageInfo<AdamCaomeiPassportListDto> dtoPage = new PageInfo<>(rows);
        List<AdamCaomeiPassportListVo> voList = dtoPage.getList().stream().map(d -> {
            AdamCaomeiPassportListVo vo = new AdamCaomeiPassportListVo();
            BeanUtils.copyProperties(d, vo);
            return vo;
        }).collect(Collectors.toList());
        PageInfo<AdamCaomeiPassportListVo> voPage = new PageInfo<>(voList);
        voPage.setTotal(dtoPage.getTotal());
        return voPage;
    }

    @Override
    public AdamCaomeiPassportDetailVo getPassportDetail(String passportNo) {
        if (StringUtils.isBlank(passportNo)) {
            return null;
        }
        AdamCaomeiPassport passport = adamCaomeiPassportMapper.selectOne(
                Wrappers.lambdaQuery(AdamCaomeiPassport.class)
                        .eq(AdamCaomeiPassport::getPassportNo, passportNo.trim())
        );
        if (passport == null) {
            return null;
        }
        AdamCaomeiPassportDetailVo vo = new AdamCaomeiPassportDetailVo();
        vo.setMid(passport.getMid());
        vo.setPassportNo(passport.getPassportNo());
        vo.setStatus(passport.getStatus());
        vo.setUserId(passport.getUserId());
        vo.setBoundAt(passport.getBoundAt());
        vo.setBatchNo(passport.getBatchNo());

        String uid = passport.getUserId();
        if (StringUtils.isBlank(uid)) {
            vo.setBadges(Collections.emptyList());
            return vo;
        }

        AdamUser user = adamUserMapper.selectOne(Wrappers.lambdaQuery(AdamUser.class).eq(AdamUser::getUid, uid));
        AdamUserInfo userInfo = adamUserInfoMapper.selectOne(Wrappers.lambdaQuery(AdamUserInfo.class).eq(AdamUserInfo::getUid, uid));
        vo.setNickname(userInfo != null ? StringUtils.defaultString(userInfo.getNickname()) : "");
        vo.setMobile(user != null ? maskMobile(user.getMobile()) : "");

        AdamRealName realName = adamRealNameMapper.selectOne(
                Wrappers.lambdaQuery(AdamRealName.class)
                        .eq(AdamRealName::getUid, uid)
                        .eq(AdamRealName::getState, 1)
                        .orderByDesc(AdamRealName::getMid)
                        .last("limit 1")
        );
        if (realName != null) {
            vo.setRealName(StringUtils.defaultString(realName.getName()));
            vo.setIdCard(maskIdCard(realName.getIdCard()));
        } else {
            vo.setRealName("");
            vo.setIdCard("");
        }

        List<AdamCaomeiPassportUserBadgeDto> badgeRows = adamCaomeiPassportMapper.selectUserBadgesByUid(uid);
        vo.setBadges(badgeRows.stream().map(b -> {
            AdamCaomeiPassportBadgeItemVo item = new AdamCaomeiPassportBadgeItemVo();
            item.setBadgeId(b.getBadgeId());
            item.setBadgeName(b.getBadgeName());
            item.setIcon(b.getIcon());
            item.setClaimedAt(b.getClaimedAt());
            item.setSource(b.getSource());
            return item;
        }).collect(Collectors.toList()));

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean unbindPassport(String passportNo) {
        if (StringUtils.isBlank(passportNo)) {
            return false;
        }
        AdamCaomeiPassport passport = adamCaomeiPassportMapper.selectOne(
                Wrappers.lambdaQuery(AdamCaomeiPassport.class)
                        .eq(AdamCaomeiPassport::getPassportNo, passportNo.trim())
        );
        if (passport == null) {
            return false;
        }
        if (passport.getStatus() == null || passport.getStatus() != 1) {
            return false;
        }
        String uid = passport.getUserId();
        Date now = new Date();
        passport.setStatus(0);
        passport.setUserId("");
        passport.setUnboundAt(now);
        passport.setUpdatedAt(now);
        boolean updated = adamCaomeiPassportMapper.updateById(passport) > 0;
        if (!updated) {
            return false;
        }
        if (StringUtils.isNotBlank(uid)) {
            // 解绑后，清理该用户由“绑定护照”自动发放的护照纪念徽章
            adamCaomeiBadgeMapper.deletePassportTypeBadgesByUid(uid);
            // 清理用户草莓徽章缓存，避免前端短时间读到解绑前数据
            redisDataSourceUtil.getRedisAdamUtil().del(AdamRedisConst.INFO_CAOMEI_BADGE_USER.concat(uid));
        }
        return true;
    }

    private static String maskMobile(String mobile) {
        if (StringUtils.isBlank(mobile)) {
            return "";
        }
        if (mobile.length() >= 11) {
            return mobile.substring(0, 3) + "****" + mobile.substring(7);
        }
        return mobile;
    }

    private static String maskIdCard(String idCard) {
        if (StringUtils.isBlank(idCard)) {
            return "";
        }
        if (idCard.length() > 8) {
            return idCard.substring(0, 4) + "****" + idCard.substring(idCard.length() - 4);
        }
        return "****";
    }
}
