package com.red.circle.other.app.inner.service.material.props.impl;

import com.alibaba.fastjson.JSON;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.inner.convertor.material.PropsResourcesInnerConvertor;
import com.red.circle.other.app.inner.service.material.props.PropsBackpackClientService;
import com.red.circle.other.app.inner.service.material.props.PropsSourceClientService;
import com.red.circle.other.infra.common.props.PropsResourcesCommon;
import com.red.circle.other.infra.database.cache.key.AdminFreeKeys;
import com.red.circle.other.infra.database.cache.key.GameListKeys;
import com.red.circle.other.infra.database.rds.entity.family.FamilyLevelConfig;
import com.red.circle.other.infra.database.rds.entity.props.PropsRedPacketSkin;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.family.FamilyLevelConfigService;
import com.red.circle.other.infra.database.rds.service.props.PropsRedPacketSkinService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.infra.utils.RedisUtils;
import com.red.circle.other.inner.enums.material.ConsolePropsTypeEnum;
import com.red.circle.other.inner.enums.material.PropsTypeEnum;
import com.red.circle.other.inner.model.cmd.material.PropsResourcesMergeCmd;
import com.red.circle.other.inner.model.cmd.material.PropsSourceRecordQryCmd;
import com.red.circle.other.inner.model.dto.material.PropsRedPacketSkinDTO;
import com.red.circle.other.inner.model.dto.material.PropsResourcesDTO;
import com.red.circle.other.inner.model.dto.material.PropsResourcesMergeDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * 道具资源.
 *
 * @author pengliang on 2023/11/7
 */
@Service
@RequiredArgsConstructor
public class PropsSourceClientServiceImpl implements PropsSourceClientService {

  private final PropsResourcesCommon propsResourcesCommon;
  private final FamilyLevelConfigService familyLevelConfigService;
  private final PropsSourceRecordService propsSourceRecordService;
  private final PropsRedPacketSkinService propsRedPacketSkinService;
  private final RedisService redisService;
    @Autowired
    @Qualifier("propsResourcesInnerConvertorImplNew")
    private  PropsResourcesInnerConvertor propsResourcesInnerConvertor;

  @Override
  public PropsResourcesDTO getById(Long id) {
    return propsResourcesInnerConvertor.toPropsResourcesDTO(propsSourceRecordService.getById(id));
  }

  @Override
  public Map<Long, PropsResourcesDTO> mapByIds(Set<Long> ids) {
    return propsResourcesInnerConvertor.toMapPropsResourcesDTO(
        propsSourceRecordService.mapByIds(ids));
  }

  @Override
  public PropsResourcesMergeDTO mapMergeByIds(PropsResourcesMergeCmd cmd) {
    return propsResourcesCommon.mapMergeByIds(cmd);
  }

  @Override
  public List<PropsResourcesDTO> listSysOriginPropsResources(String sysOrigin, String type) {
    return propsResourcesInnerConvertor.toListPropsResourcesDTO(
        propsSourceRecordService.listSysOrigin(sysOrigin, type));
  }

  @Override
  public List<PropsResourcesDTO> listExcludeFamily(String sysOrigin, String type) {
    return propsResourcesInnerConvertor.toListPropsResourcesDTO(
        propsSourceRecordService.listSysOrigin(sysOrigin, type,
            levelAvatarFrameIds(type, familyLevelConfigService.listAllLevel()))
    );
  }

  private Set<Long> levelAvatarFrameIds(String type, List<FamilyLevelConfig> levelConfigs) {
    Set<Long> props = null;

    if (CollectionUtils.isNotEmpty(levelConfigs) && Objects
        .equals(type, ConsolePropsTypeEnum.AVATAR_FRAME.getName())) {

      props = levelConfigs.stream().map(FamilyLevelConfig::getAvatarFrameId)
          .collect(Collectors.toSet());
    }
    return props;
  }

  @Override
  public void offShelfPropsResources(Long id, Boolean offShelf) {
    propsSourceRecordService.offShelf(id, offShelf);
  }

  @Override
  public PageResult<PropsResourcesDTO> pagePropsResourcesOps(PropsSourceRecordQryCmd qryCmd) {
    return propsResourcesInnerConvertor.toPagePropsResourcesDTO(
        propsSourceRecordService.query()
            .eq(PropsSourceRecord::getSysOrigin, qryCmd.getSysOrigin())
            .eq(Objects.nonNull(qryCmd.getType()), PropsSourceRecord::getType,
                qryCmd.getType())
            .eq(Objects.nonNull(qryCmd.getId()), PropsSourceRecord::getId,
                qryCmd.getId())
            .eq(Objects.nonNull(qryCmd.getDel()), PropsSourceRecord::getDel,
                qryCmd.getDel())
            .like(StringUtils.isNotBlank(qryCmd.getName()), PropsSourceRecord::getName,
                qryCmd.getName())
            .orderByDesc(PropsSourceRecord::getCreateTime)
            .page(qryCmd.getPageQuery())
    );
  }

  @Override
  public void addOrUpdatePropsResources(PropsResourcesDTO dto) {
    PropsSourceRecord propsSourceRecord = propsResourcesInnerConvertor.toPropsSourceRecord(dto);
    if (Objects.isNull(dto.getId())) {
      propsSourceRecordService.save(propsSourceRecord);
      if (Objects.equals(PropsTypeEnum.RED_PACKET.name(), propsSourceRecord.getType())) {
        propsRedPacketSkinService.save(new PropsRedPacketSkin().setId(propsSourceRecord.getId())
            .setImNotOpenedUrl(dto.getImNotOpenedUrl())
            .setImOpenedUrl(dto.getImOpenedUrl())
            .setImSendCoverUrl(dto.getImSendCoverUrl())
            .setRoomSendCoverUrl(dto.getRoomSendCoverUrl())
            .setRoomNotOpenedUrl(dto.getRoomNotOpenedUrl())
            .setRoomOpenedUrl(dto.getRoomOpenedUrl())
            .setImOpenedUrlTwo(dto.getImOpenedUrlTwo())
            .setSysOrigin(dto.getSysOrigin()));
      }
      return;
    }
    propsSourceRecordService.updateSelectiveById(propsSourceRecord);

    if (Objects.equals(PropsTypeEnum.RED_PACKET.name(), propsSourceRecord.getType())) {

      propsRedPacketSkinService.updateSelectiveById(
          new PropsRedPacketSkin().setId(propsSourceRecord.getId())
              .setImNotOpenedUrl(dto.getImNotOpenedUrl())
              .setImOpenedUrl(dto.getImOpenedUrl())
              .setImSendCoverUrl(dto.getImSendCoverUrl())
              .setRoomSendCoverUrl(dto.getRoomSendCoverUrl())
              .setRoomNotOpenedUrl(dto.getRoomNotOpenedUrl())
              .setRoomOpenedUrl(dto.getRoomOpenedUrl())
              .setImOpenedUrlTwo(dto.getImOpenedUrlTwo())
              .setSysOrigin(dto.getSysOrigin()));
    }
  }

  @Override
  public PropsRedPacketSkinDTO getPropsRedPacketSkin(Long id) {

    return propsResourcesInnerConvertor.toPropsRedPacketSkinDTO(
        propsRedPacketSkinService.getById(id));
  }

  @Override
  public void updateRedisCache(PropsResourcesDTO dto) {
    Set<String> strings = RedisUtils.redisScan(redisService.redisTemplate(), AdminFreeKeys.ADMIN_FREE_PROPS.getKey());
    if (CollectionUtils.isNotEmpty(strings)) {

      strings.forEach(s -> {
        //先判断是否存在hash中
        if (!redisService.hashHasKey(s,dto.getId().toString())) {
          if (dto.getAdminFree()) {
            //不存在 新增
            dto.setCount(50);
            redisService.hashPut(s, String.valueOf(dto.getId()), JSON.toJSONString(dto));
          }
        }else{
            if (!dto.getAdminFree()) {
                redisService.hashDelete(s, dto.getId().toString());
            }
        }
      });
    }

  }
}
