package com.red.circle.other.app.inner.service.approval.impl;

import com.red.circle.common.business.core.enums.DataApprovalTypeEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.inner.service.approval.ApprovalFamilySettingDataClientService;
import com.red.circle.other.infra.database.rds.entity.approval.ApprovalUserSettingData;
import com.red.circle.other.infra.database.rds.entity.family.FamilyBaseInfo;
import com.red.circle.other.infra.database.rds.service.approval.ApprovalUserSettingDataService;
import com.red.circle.other.infra.database.rds.service.family.FamilyBaseInfoService;
import com.red.circle.other.inner.model.cmd.approval.ApprovalFamilyCmd;
import com.red.circle.other.inner.model.cmd.approval.ApprovalProfileDescQryCmd;
import com.red.circle.other.inner.model.dto.approval.ApprovalFamilyDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.num.NumUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 家族资料审批
 *
 * @author zongpubin on 2024/1/20
 */
@Service
@RequiredArgsConstructor
public class ApprovalFamilySettingDataClientServiceImpl implements
    ApprovalFamilySettingDataClientService {

  private final FamilyBaseInfoService familyBaseInfoService;
  private final ApprovalUserSettingDataService approvalUserSettingDataService;

  @Override
  public PageResult<ApprovalFamilyDTO> pageFamilyApproval(
      ApprovalProfileDescQryCmd query) {
    PageResult<ApprovalUserSettingData> pageResult = approvalUserSettingDataService.pageFamilyApproval(
        query);
    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return pageResult.convert(approvalUserSettingData -> new ApprovalFamilyDTO());
    }

    Map<Long, FamilyBaseInfo> familyMap = getFamilyMap(pageResult);

    var result = pageResult.convert(approval -> {
      ApprovalFamilyDTO approvalDTO = new ApprovalFamilyDTO().setUserId(approval.getUserId());

      FamilyBaseInfo familyBaseInfo = familyMap.get(approval.getUserId());
      if (Objects.isNull(familyBaseInfo)) {
        return null;
      }
      approvalDTO.setFamilyAvatar(familyBaseInfo.getFamilyAvatar());
      approvalDTO.setFamilyId(familyBaseInfo.getId());
      approvalDTO.setFamilyName(familyBaseInfo.getFamilyName());
      approvalDTO.setFamilyNotice(familyBaseInfo.getFamilyNotice());
      approvalDTO.setFamilyAccount(familyBaseInfo.getFamilyAccount());

      return approvalDTO;
    });
    result.setRecords(result.getRecords().stream().filter(Objects::nonNull).collect(
        Collectors.toList()));
    return result;
  }

  @Override
  public void notPass(ApprovalFamilyCmd cmd) {
    getListByIds(cmd.getFamilyIds()).forEach(family -> {

      if (Objects.equals(DataApprovalTypeEnum.FAMILY_AVATAR.name(), cmd.getType())) {
        familyBaseInfoService.update().set(FamilyBaseInfo::getFamilyAvatar, "")
            .eq(FamilyBaseInfo::getId, family.getId()).execute();
      }

      if (Objects.equals(DataApprovalTypeEnum.FAMILY_NICKNAME.name(), cmd.getType())) {
        familyBaseInfoService.update().set(FamilyBaseInfo::getFamilyName, getFamilyName())
            .eq(FamilyBaseInfo::getId, family.getId()).execute();
      }

      if (Objects.equals(DataApprovalTypeEnum.FAMILY_NOTICE.name(), cmd.getType())) {
        familyBaseInfoService.update().set(FamilyBaseInfo::getFamilyNotice, "")
            .eq(FamilyBaseInfo::getId, family.getId()).execute();
      }
    });

  }

  private List<FamilyBaseInfo> getListByIds(List<Long> familyIds) {

    ResponseAssert.isFalse(CommonErrorCode.DATA_ERROR, CollectionUtils.isEmpty(familyIds));

    List<FamilyBaseInfo> familyList = familyBaseInfoService.listByIds(familyIds);

    ResponseAssert.notNull(CommonErrorCode.DATA_PARSING_ERROR, CollectionUtils.isEmpty(familyList));

    return familyList;
  }

  private String getFamilyName() {
    return "st_" + NumUtils.getRandomNumberString(6) + NumUtils.getRandomNumberString(7);
  }

  private Map<Long, FamilyBaseInfo> getFamilyMap(PageResult<ApprovalUserSettingData> page) {
    return familyBaseInfoService
        .mapByUserIds(page.getRecords().stream().map(ApprovalUserSettingData::getUserId).collect(
            Collectors.toSet()));
  }

}

