package com.red.circle.wallet.infra.database.mongo.service.bank.impl;

import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.date.ZonedDateTimeUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.wallet.infra.database.mongo.entity.bank.UserBankWithdrawMoneyApply;
import com.red.circle.wallet.infra.database.mongo.service.bank.UserBankWithdrawMoneyApplyService;
import com.red.circle.wallet.inner.model.cmd.UserBankApprovalMoneyApplyCmd;
import com.red.circle.wallet.inner.model.cmd.UserBankWithdrawMoneyApplyQryCmd;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

/**
 * 用户银行卡提现申请记录 实现.
 *
 * @author pengliang on 2023/2/15
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserBankWithdrawMoneyApplyServiceImpl implements UserBankWithdrawMoneyApplyService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void add(UserBankWithdrawMoneyApply apply) {
    mongoTemplate.save(apply);
  }

  @Override
  public void updateBankCard(Long id, String bankCard) {
    mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(id)),
        new Update().set("bankCardType", bankCard),
        UserBankWithdrawMoneyApply.class);
  }

  @Override
  public List<UserBankWithdrawMoneyApply> listAll() {
    return mongoTemplate.find(Query.query(new Criteria()), UserBankWithdrawMoneyApply.class);
  }

  @Override
  public Map<Long, UserBankWithdrawMoneyApply> mapByIds(Set<Long> ids) {

    List<UserBankWithdrawMoneyApply> applies = mongoTemplate.find(
        Query.query(Criteria.where("id").in(ids)),
        UserBankWithdrawMoneyApply.class);

    if (CollectionUtils.isEmpty(applies)) {
      return CollectionUtils.newHashMap();
    }

    return applies.stream().collect(Collectors.toMap(UserBankWithdrawMoneyApply::getId, v -> v));
  }

  @Override
  public List<UserBankWithdrawMoneyApply> listBankWithdrawMoneyApply(
      UserBankWithdrawMoneyApplyQryCmd query) {

    Criteria criteria = Criteria.where("sysOrigin").is(query.getSysOrigin());

    if (StringUtils.isNotBlank(query.getBankCardType())) {
      criteria.and("bankCardType").is(query.getBankCardType());
    }

    if (Objects.nonNull(query.getLastId())) {
      criteria.and("id").lt(query.getLastId());
    }

    if (Objects.nonNull(query.getAcceptUserId())) {
      criteria.and("acceptUserId").is(query.getAcceptUserId());
    }

    if (Objects.nonNull(query.getSubmitUserId())) {
      criteria.and("submitUserId").is(query.getSubmitUserId());
    }

    if (StringUtils.isNotBlank(query.getAcceptMethod())) {
      criteria.and("acceptMethod").is(query.getAcceptMethod());
    }
    log.warn("amountType入参--{}", query.getAmountType());
    if (StringUtils.isNotBlank(query.getAmountType()) && "SALARY_DIAMOND".equals(query.getAmountType())) {
      criteria.and("amountType").is(query.getAmountType());
    }else {
      criteria.and("amountType").ne("SALARY_DIAMOND");
    }

    if (StringUtils.isNotBlank(query.getLatestApprovalStatus())) {
      criteria.and("latestApprovalStatus").is(query.getLatestApprovalStatus());
    }

    if (Objects.nonNull(query.getStartTime()) && Objects.nonNull(query.getEndTime())) {
      criteria.andOperator(
          Criteria.where("createTime").gte(TimestampUtils.convert(query.getStartTime())),
          Criteria.where("createTime").lte(TimestampUtils.convert(query.getEndTime()))
      );
    }

    return mongoTemplate.find(Query.query(criteria)
            .with(Sort.by(Sort.Order.desc("id")))
            .limit(query.getLimit()),
        UserBankWithdrawMoneyApply.class);
  }

  @Override
  public UserBankWithdrawMoneyApply getById(Long id) {

    return mongoTemplate.findOne(Query.query(Criteria.where("id").is(id)),
        UserBankWithdrawMoneyApply.class);
  }

  @Override
  public void approvalMoneyApply(UserBankApprovalMoneyApplyCmd apply) {

    mongoTemplate.updateFirst(Query.query(Criteria.where("id").in(apply.getId())),
        new Update()
            .set("updateTime", TimestampUtils.now())
            .set("updateUser", apply.getUpdateUser())
            .set("updateUserOrigin", apply.getUpdateUserOrigin())
            .set("latestApprovalStatus", apply.getLatestApprovalStatus())
            .set("settlementResult", apply.getSettlementResult())
            .push("approvalProcesses", apply.getProcess()),
        UserBankWithdrawMoneyApply.class);

  }

}
