package com.red.circle.other.app.inner.endpoint.material.props;

import com.alibaba.fastjson.JSON;
import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateCustomizeCmd;
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.app.inner.service.material.props.PropsBackpackClientService;
import com.red.circle.other.infra.database.rds.entity.badge.BadgePictureConfig;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.badge.BadgePictureConfigService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.infra.utils.I18nUtils;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.model.user.ability.RegionConfig;
import com.red.circle.other.inner.endpoint.material.props.api.PropsBackpackClientApi;
import com.red.circle.other.inner.enums.material.BadgeConfigTypeEnum;
import com.red.circle.other.inner.enums.material.PropsCommodityType;
import com.red.circle.other.inner.model.cmd.material.DeletePropsCmd;
import com.red.circle.other.inner.model.cmd.material.GivePropsBackpackCmd;
import com.red.circle.other.inner.model.cmd.material.PropsBackpackQry;
import com.red.circle.other.inner.model.cmd.material.ReduceDaysAndUnUseCmd;
import com.red.circle.other.inner.model.dto.material.PropsBackpackDTO;
import com.red.circle.other.inner.model.dto.material.UsePropsDTO;

import java.util.*;

import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户道具背包服务.
 *
 * @author pengliang on 2023/6/3
 */
@Validated
@RestController
@RequestMapping(value = PropsBackpackClientApi.API_PREFIX, produces = MediaType.APPLICATION_JSON_VALUE)
@RequiredArgsConstructor
public class PropsBackpackClientEndpoint implements PropsBackpackClientApi {

  private final PropsBackpackClientService userPropsBackpackClientService;
  private final OfficialNoticeClient officialNoticeClient;
  private final UserProfileGateway userProfileGateway;
  private final UserRegionGateway userRegionGateway;
  private final PropsSourceRecordService propsSourceRecordService;
  private final BadgePictureConfigService badgePictureConfigService;

  @Override
  public ResultResponse<UsePropsDTO> switchUseProps(Long userId, Long propsId) {
    return ResultResponse.success(userPropsBackpackClientService.switchUseProps(userId, propsId));
  }

  @Override
  public ResultResponse<Void> unloadUseProps(Long userId, PropsCommodityType propsType) {
    userPropsBackpackClientService.unloadUseProps(userId, propsType);
    return ResultResponse.success();
  }

  @Override
  public ResultResponse<Void> deleteProps(DeletePropsCmd cmd) {
    userPropsBackpackClientService.deleteProps(cmd);
    return ResultResponse.success();
  }

  @Override
  public ResultResponse<Void> saveBatchBackpack(List<PropsBackpackDTO> props) {
    userPropsBackpackClientService.saveBatchBackpack(props);
    return ResultResponse.success();
  }

  @Override
  public ResultResponse<Void> saveBackpack(PropsBackpackDTO props) {
    userPropsBackpackClientService.saveBackpack(props);
    return ResultResponse.success();
  }

  @Override
  public ResultResponse<Void> giveProps(GivePropsBackpackCmd cmd) {
    userPropsBackpackClientService.giveProps(cmd);
    return ResultResponse.success();
  }
  @Override
  public ResultResponse<Void> givePropsNotify(Long userId ,String type,Integer days, Long propsId) {
    UserProfile user = userProfileGateway.getByUserId(userId);
    String url = null;
    PropsSourceRecord props = propsSourceRecordService.getPropsById(propsId);
    if (props != null) {
      url = props.getCover();
    }

    if (Objects.isNull(user)) {
      return ResultResponse.success();
    }

      Map<String, Object> map = new HashMap<>();
      map.put("propType", type);
      if (BadgeConfigTypeEnum.of(type)) {
          BadgePictureConfig badgePictureConfig = badgePictureConfigService.getByBadgeId(user.getOriginSys(), propsId);
          url = badgePictureConfig != null ? badgePictureConfig.getSelectUrl() : "";
      }

      RegionConfig region = userRegionGateway.getRegionConfigByUserId(userId);
      officialNoticeClient.send(
              NoticeExtTemplateCustomizeCmd.builder().toAccount(userId)
                      .noticeType(OfficialNoticeTypeEnum.GIVE_AWAY_PROPS)
                      .title(JSON.toJSONString(map))
                      .content(I18nUtils.getPropsRewardContent(type, days, I18nUtils.getLanguageByRegion(region.getRegionName())))
                      .expand(url)
                      .build());


    return ResultResponse.success();
  }

  @Override
  public ResultResponse<List<PropsBackpackDTO>> listNotExpiredUseProps(Long userId) {
    return ResultResponse.success(userPropsBackpackClientService.listNotExpiredUseProps(userId));
  }

  @Override
  public ResultResponse<List<PropsBackpackDTO>> listNotExpiredUseProps(Set<Long> userIds) {
    return ResultResponse.success(userPropsBackpackClientService.listNotExpiredUseProps(userIds));
  }

  @Override
  public ResultResponse<List<UsePropsDTO>> listNotExpiredUsePropsNobleVip(Long userId) {
    return ResultResponse.success(userPropsBackpackClientService.listNotExpiredUseProps(
        userId, List.of(PropsCommodityType.NOBLE_VIP)
    ));
  }

  @Override
  public ResultResponse<Map<Long, List<UsePropsDTO>>> mapNotExpiredUseProps(
      PropsBackpackQry qry) {
    return ResultResponse.success(userPropsBackpackClientService.mapNotExpiredUseProps(qry));
  }

  @Override
  public ResultResponse<Map<Long, List<UsePropsDTO>>> mapNotExpiredUsePropsNobleVip(
      Set<Long> userIds) {
    return ResultResponse.success(
        userPropsBackpackClientService.mapNotExpiredUseProps(new PropsBackpackQry()
            .setUserIds(userIds)
            .setPropsTypes(List.of(PropsCommodityType.NOBLE_VIP))
        )
    );
  }

  @Override
  public ResultResponse<Void> reduceDaysAndUnUse(ReduceDaysAndUnUseCmd cmd) {
    userPropsBackpackClientService.reduceDaysAndUnUse(cmd);
    return ResultResponse.success();
  }


  @Override
  public ResultResponse<List<PropsBackpackDTO>> listNotExpiredByType(Long userId,
      PropsCommodityType type) {
    return ResultResponse.success(
        userPropsBackpackClientService.listNotExpiredByType(userId, type));
  }

}
