package com.red.circle.console.app.service.app.dynamic;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.excel.exception.ExcelCommonException;
import com.red.circle.common.business.core.enums.ApprovalStatusEnum;
import com.red.circle.common.business.enums.ViolationEnum;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.console.app.convertor.dynamic.DynamicAppConvertor;
import com.red.circle.console.app.dto.clienobject.dynamic.PageDynamicContentCO;
import com.red.circle.console.inner.error.ConsoleErrorCode;
import com.red.circle.external.inner.endpoint.oss.OssServiceClient;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.inner.endpoint.dynamic.ApprovalDynamicClient;
import com.red.circle.other.inner.endpoint.dynamic.DynamicContentClient;
import com.red.circle.other.inner.endpoint.dynamic.DynamicPictureClient;
import com.red.circle.other.inner.endpoint.dynamic.DynamicTagClient;
import com.red.circle.other.inner.endpoint.dynamic.DynamicTimelineClient;
import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.model.cmd.approval.ApprovalDynamicContentCmd;
import com.red.circle.other.inner.model.cmd.dynamic.CreateDynamicVideoCmd;
import com.red.circle.other.inner.model.cmd.dynamic.CreateDynamicVideoCmd.DynamicVideoCmd;
import com.red.circle.other.inner.model.cmd.dynamic.DelDynamicContentCmd;
import com.red.circle.other.inner.model.cmd.dynamic.DynamicContentCmd;
import com.red.circle.other.inner.model.cmd.dynamic.DynamicContentQryCmd;
import com.red.circle.other.inner.model.cmd.dynamic.DynamicPictureCmd;
import com.red.circle.other.inner.model.cmd.dynamic.DynamicTimelineCmd;
import com.red.circle.other.inner.model.dto.dynamic.DynamicTagDTO;
import com.red.circle.other.inner.model.dto.dynamic.PageDynamicContentDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.sql.Timestamp;
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.stereotype.Service;

/**
 * <p>
 * 动态内容 服务类.
 * </p>
 *
 * @author pengshigang
 * @since 2022-4-15
 */

@Service
@RequiredArgsConstructor
public class DynamicContentServiceImpl implements DynamicContentService {

  private final RedisService redisService;
  private final OssServiceClient ossServiceClient;
  private final DynamicTagClient dynamicTagClient;
  private final UserProfileClient userProfileClient;
  private final RegionConfigClient regionConfigClient;
  private final DynamicAppConvertor dynamicAppConvertor;
  private final DynamicContentClient dynamicContentClient;
  private final DynamicPictureClient dynamicPictureClient;
  private final DynamicTimelineClient dynamicTimelineClient;
  private final ApprovalDynamicClient approvalDynamicClient;


  @Override
  public void deleteByIds(DelDynamicContentCmd cmd) {
    ResponseAssert.requiredSuccess(dynamicContentClient.deleteByIds(cmd));

  }

  @Override
  public PageResult<PageDynamicContentCO> page(DynamicContentQryCmd query) {

    PageResult<PageDynamicContentDTO> iPage = ResponseAssert.requiredSuccess(
        dynamicContentClient.pageDynamicContent(query));
    if (CollectionUtils.isEmpty(iPage.getRecords())) {
      return iPage.convert(dynamicAppConvertor::toPageDynamicContentCO);
    }

    Map<Long, UserProfileDTO> userMap = ResponseAssert.requiredSuccess(
        userProfileClient.mapByUserIds(getUserIds(iPage)));

    return iPage.convert(vo -> {
      PageDynamicContentCO dynamicContentCO = dynamicAppConvertor.toPageDynamicContentCO(vo);
      UserProfileDTO user = userMap.get(vo.getCreateUser());
      if (Objects.nonNull(user)) {
        dynamicContentCO.setUserBaseInfo(user);
        dynamicContentCO.setUserId(user.getId());
        dynamicContentCO.setUserSexName(getSexName(user.getUserSex()));
      }
      return dynamicContentCO;
    });
  }

  @Override
  public Integer createVideo(CreateDynamicVideoCmd cmd) {
    // 获取导入的数据列表
    List<DynamicVideoCmd> dynamicVideoCmdList = cmd.getDynamicVideoCmdList();
    if (CollectionUtils.isEmpty(dynamicVideoCmdList)) {
      throw new RuntimeException("数据为空！");
    }
    String key = "create_user_dynamic_video_" + DigestUtil.md5Hex16(cmd.toString());
    ResponseAssert.isTrue(ConsoleErrorCode.USER_DYNAMICS_CANNOT_BE_INSERTED_REPEATEDLY,
        redisService.lock(key, 60 * 5));
    Set<Long> userIdSet = dynamicVideoCmdList.stream()
        .map(DynamicVideoCmd::getUserId)
        .filter(Objects::nonNull)
        .collect(Collectors.toSet());
    //获取用户所在的区域
    Map<Long, String> regionIdMap = regionConfigClient.mapRegionIdByUserIds(userIdSet).getBody();
    //获取所有标签
    Map<String, DynamicTagDTO> dynamicTagMap = dynamicTagClient.getAllDynamicTag().getBody();
    dynamicVideoCmdList.forEach(dynamicVideoCmd -> {
      Timestamp date = new Timestamp(System.currentTimeMillis());
      Long dynamicId = IdWorkerUtils.getId();
      //获取用户区域
      String regionId = regionIdMap.get(dynamicVideoCmd.getUserId());
      Long tagId = null;
      //获取动态标签
      if (CharSequenceUtil.isNotBlank(dynamicVideoCmd.getTag())) {
        DynamicTagDTO dynamicTagDTO = dynamicTagMap.get(dynamicVideoCmd.getTag());
        if (Objects.nonNull(dynamicTagDTO)) {
          tagId = dynamicTagDTO.getId();
        }
      }
      dynamicContentClient.save(DynamicContentCmd.builder()
          .id(dynamicId)
          .sysOrigin(dynamicVideoCmd.getSysOrigin())
          .content(dynamicVideoCmd.getContent())
          .del(Boolean.FALSE)
          .location("")
          .tagId(tagId)
          .region(regionId)
          .type(dynamicVideoCmd.getType())
          .languageType(dynamicVideoCmd.getLanguageType())
          .createTime(date)
          .createUser(cmd.requiredReqUserId())
          .updateTime(date)
          .build()
      );
      dynamicPictureClient.save(DynamicPictureCmd.builder()
          .id(IdWorkerUtils.getId())
          .dynamicId(dynamicId)
          .resourceUrl(ossServiceClient.getAccessUrl(dynamicVideoCmd.getSourceUrl()).getBody())
          .miniResourceUrl(
              ossServiceClient.processImgSaveAsCompressZoom(dynamicVideoCmd.getSourceUrl(),
                  dynamicVideoCmd.getSourceUrl().replace(".", "-MINI-DYNAMIC."), 300).getBody())
          .violation(ViolationEnum.NORMAL.name())
          .createTime(date)
          .updateTime(date)
          .build()
      );
      dynamicTimelineClient.save(DynamicTimelineCmd.builder()
          .dynamicContentId(dynamicId)
          .own(dynamicVideoCmd.getOwn())
          .region(regionId)
          .createTime(date)
          .createUser(cmd.requiredReqUserId())
          .updateTime(date)
          .build()
      );
      approvalDynamicClient.save(ApprovalDynamicContentCmd.builder()
          .id(IdWorkerUtils.getId())
          .sysOrigin(dynamicVideoCmd.getSysOrigin())
          .userId(dynamicVideoCmd.getUserId())
          .dynamicId(dynamicId)
          .dynamicType(dynamicVideoCmd.getType())
          .approveStatus(ApprovalStatusEnum.PENDING.name())
          .originType(Boolean.FALSE)
          .createTime(date)
          .createUser(cmd.requiredReqUserId())
          .updateTime(date)
          .build()
      );
    });
    return dynamicVideoCmdList.size();
  }

  private String getSexName(Integer sex) {
    //用户性别:0 女，1 男，2 变性人
    if (Objects.equals(sex, 0)) {
      return "女";
    }
    if (Objects.equals(sex, 1)) {
      return "男";
    }
    return "未知";
  }

  private Set<Long> getUserIds(PageResult<PageDynamicContentDTO> iPage) {
    return iPage.getRecords().stream().map(PageDynamicContentDTO::getCreateUser)
        .collect(Collectors.toSet());
  }
}
