package cn.newfeifan.mall.module.member.convert.signin;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.newfeifan.mall.framework.common.pojo.PageResult;
import cn.newfeifan.mall.framework.common.util.collection.MapUtils;
import cn.newfeifan.mall.framework.common.util.date.DateUtils;
import cn.newfeifan.mall.module.member.controller.admin.signin.vo.record.MemberSignInRecordRespVO;
import cn.newfeifan.mall.module.member.controller.app.signin.vo.record.AppMemberSignInRecordRespVO;
import cn.newfeifan.mall.module.member.dal.dataobject.signin.MemberSignInConfigDO;
import cn.newfeifan.mall.module.member.dal.dataobject.signin.MemberSignInRecordDO;
import cn.newfeifan.mall.module.member.dal.dataobject.user.MemberUserDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.time.LocalDate;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertMap;

/**
 * 签到记录 Convert
 *
 * @author 非繁源码
 */
@Mapper
public interface MemberSignInRecordConvert {

    MemberSignInRecordConvert INSTANCE = Mappers.getMapper(MemberSignInRecordConvert.class);

    default PageResult<MemberSignInRecordRespVO> convertPage(PageResult<MemberSignInRecordDO> pageResult, List<MemberUserDO> users) {
        PageResult<MemberSignInRecordRespVO> voPageResult = convertPage(pageResult);
        // user 拼接
        Map<Long, MemberUserDO> userMap = convertMap(users, MemberUserDO::getId);
        voPageResult.getList().forEach(record -> MapUtils.findAndThen(userMap, record.getUserId(),
                memberUserRespDTO -> record.setNickname(memberUserRespDTO.getNickname())));
        return voPageResult;
    }

    PageResult<MemberSignInRecordRespVO> convertPage(PageResult<MemberSignInRecordDO> pageResult);

    PageResult<AppMemberSignInRecordRespVO> convertPage02(PageResult<MemberSignInRecordDO> pageResult);

    AppMemberSignInRecordRespVO coverRecordToAppRecordVo(MemberSignInRecordDO memberSignInRecordDO);
    default AppMemberSignInRecordRespVO coverRecordToAppRecordVo(MemberSignInRecordDO memberSignInRecordDO,boolean upgradeOrNot,Long social,String socialStatusName){
        if ( memberSignInRecordDO == null ) {
            return null;
        }

        AppMemberSignInRecordRespVO appMemberSignInRecordRespVO = new AppMemberSignInRecordRespVO();

        appMemberSignInRecordRespVO.setDay( memberSignInRecordDO.getDay() );
        appMemberSignInRecordRespVO.setPoint( memberSignInRecordDO.getPoint() );
        appMemberSignInRecordRespVO.setExperience( memberSignInRecordDO.getExperience() );
        appMemberSignInRecordRespVO.setCreateTime( memberSignInRecordDO.getCreateTime() );
        appMemberSignInRecordRespVO.setContinueDay( memberSignInRecordDO.getContinueDay() );
        appMemberSignInRecordRespVO.setUpgradeOrNot(upgradeOrNot);
        appMemberSignInRecordRespVO.setSocial(social);
        appMemberSignInRecordRespVO.setSocialStatusName(socialStatusName);

        return appMemberSignInRecordRespVO;
    }

    default MemberSignInRecordDO convert(Long userId, MemberSignInRecordDO lastRecord, List<MemberSignInConfigDO> configs) {
        // 1. 计算是第几天签到
        configs.sort(Comparator.comparing(MemberSignInConfigDO::getDay));
//        MemberSignInConfigDO lastConfig = CollUtil.getLast(configs); // 最大签到天数配置
        // 1.2. 计算今天是第几天签到 (只有连续签到才加否则重置为 1)

        // 获取当月对应的天数
        LocalDate today = LocalDate.now();
        int  day = today.getDayOfMonth();

        // 2.1 初始化签到信息
        MemberSignInRecordDO record = new MemberSignInRecordDO().setUserId(userId)
                .setDay(day).setPoint(0).setExperience(0);

        if (lastRecord != null && DateUtils.isYesterday(lastRecord.getCreateTime())) {
            record.setContinueDay(lastRecord.getContinueDay() + 1);
        }

        // 2.2 获取签到对应的积分
        MemberSignInConfigDO config = CollUtil.findOne(configs, item -> ObjUtil.equal(item.getDay(), record.getDay()));
        if (config == null) {
            return record;
        }
        record.setPoint(config.getPoint());
        record.setExperience(config.getExperience());
        return record;
    }

}
