package com.yd.csf.api.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.base.feign.client.exchangerate.ApiExchangeRateFeignClient;
import com.yd.base.feign.request.exchangerate.ApiExchangeRateConvertRequest;
import com.yd.base.feign.response.exchangerate.ApiExchangeRateConvertResponse;
import com.yd.common.enums.CommonEnum;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.common.utils.CodeGenerator;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.api.dto.ApiSalarySplitSummaryPageDTO;
import com.yd.csf.api.service.ApiSalarySplitService;
import com.yd.csf.feign.dto.salarysplit.ApiSalarySplitBatchSaveDto;
import com.yd.csf.feign.dto.salarysplit.ApiSalarySplitPageDto;
import com.yd.csf.feign.dto.salarysplit.ApiSalarySplitStatisticsDto;
import com.yd.csf.feign.dto.salarysplit.ApiSalarySplitSummaryPageDto;
import com.yd.csf.feign.request.salarysplit.*;
import com.yd.csf.api.dto.ApiSalarySplitPageListDTO;
import com.yd.csf.feign.response.salarysplit.ApiQueryRemainingResponse;
import com.yd.csf.feign.response.salarysplit.ApiSalarySplitQueryRateResponse;
import com.yd.csf.service.model.FortuneAccount;
import com.yd.csf.service.model.SalarySplit;
import com.yd.csf.service.service.FortuneAccountService;
import com.yd.csf.service.service.ISalarySplitService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class ApiSalarySplitServiceImpl implements ApiSalarySplitService {

    @Autowired
    private FortuneAccountService fortuneAccountService;

    @Autowired
    private ISalarySplitService iSalarySplitService;

    @Autowired
    private ApiExchangeRateFeignClient apiExchangeRateFeignClient;

    /**
     * 分页查询-薪资拆分应发信息汇总列表
     * @param request
     * @return
     */
    @Override
    public Result<ApiSalarySplitSummaryPageDTO> summaryPage(ApiSalarySplitSummaryPageRequest request) {
        ApiSalarySplitSummaryPageDTO response = new ApiSalarySplitSummaryPageDTO();
        // 查询分页信息
        Page<ApiSalarySplitSummaryPageDto> page = new Page<>(request.getPageNo(), request.getPageSize());
        IPage<ApiSalarySplitSummaryPageDto> iPage = iSalarySplitService.summaryPage(page, request);
        response.setPage(iPage);
        return Result.success(response);
    }

    /**
     * 分页查询-薪资拆分应发信息列表
     * @param request
     * @return
     */
    @Override
    public Result<ApiSalarySplitPageListDTO> page(ApiSalarySplitPageRequest request) {
        ApiSalarySplitPageListDTO response = new ApiSalarySplitPageListDTO();
        // 查询分页信息
        Page<ApiSalarySplitPageDto> page = new Page<>(request.getPageNo(), request.getPageSize());
        IPage<ApiSalarySplitPageDto> iPage = iSalarySplitService.page(page, request);
        response.setPage(iPage);

        // 查询统计信息
        ApiSalarySplitStatisticsDto statisticsDto = new ApiSalarySplitStatisticsDto();
        FortuneAccount fortuneAccount = fortuneAccountService.queryOne(request.getFortuneAccountBizId());
        // 出账币种
        statisticsDto.setBeSplitCurrency(fortuneAccount != null ? fortuneAccount.getCurrency() : "");

        BigDecimal beSplitAmount = BigDecimal.ZERO;
        if (fortuneAccount != null) {
            // 查询所有拆分记录，计算已拆分总金额
            List<SalarySplit> salarySplits = iSalarySplitService.lambdaQuery()
                    .eq(SalarySplit::getFortuneAccountBizId, request.getFortuneAccountBizId())
                    .list();
            BigDecimal splitTotal = salarySplits.stream()
                    .map(SalarySplit::getFromAmount)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

            BigDecimal fortuneAmount = fortuneAccount.getHkdAmount() != null ? fortuneAccount.getHkdAmount() : BigDecimal.ZERO;
            beSplitAmount = fortuneAmount.subtract(splitTotal);
            if (beSplitAmount.compareTo(BigDecimal.ZERO) < 0) {
                beSplitAmount = BigDecimal.ZERO; // 防止负数
            }
        }
        statisticsDto.setBeSplitAmount(beSplitAmount);
        response.setStatisticsDto(statisticsDto);

        return Result.success(response);
    }

    /**
     * 批量保存
     * @param request
     * @return
     */
    @Override
    public Result batchSave(ApiSalarySplitBatchSaveRequest request) {
        //查询出账记录是否存在
        FortuneAccount fortuneAccount = fortuneAccountService.queryOne(request.getFortuneAccountBizId());
        if (fortuneAccount == null) {
            throw new BusinessException("出账记录不存在");
        }
        //薪资拆分应发记录-先删除后新增
        iSalarySplitService.deleteByFortuneAccountBizId(request.getFortuneAccountBizId());

        //批量新增
        if (CollectionUtils.isEmpty(request.getApiSalarySplitBatchSaveDtoList())) {
            return Result.success();
        }
        List<SalarySplit> salarySplitList = new ArrayList<>();
        for (ApiSalarySplitBatchSaveDto dto : request.getApiSalarySplitBatchSaveDtoList()) {
            SalarySplit salarySplit = new SalarySplit();
            BeanUtils.copyProperties(dto,salarySplit);
            //薪资拆分应发表唯一业务ID
            salarySplit.setSalarySplitBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_SALARY_SPLIT.getCode()));
            //发放编号
            salarySplit.setSalarySplitNo(CodeGenerator.generate10Code("SP"));
            //出账记录业务id
            salarySplit.setFortuneAccountBizId(request.getFortuneAccountBizId());
            salarySplitList.add(salarySplit);
        }
        iSalarySplitService.saveOrUpdateBatch(salarySplitList);
        return Result.success();
    }

    /**
     * 查询-原币种剩余总金额和原币种
     * @param request
     * @return
     */
    @Override
    public Result<ApiQueryRemainingResponse> queryRemaining(ApiQueryRemainingRequest request) {
        //查询出账记录是否存在
        FortuneAccount fortuneAccount = fortuneAccountService.queryOne(request.getFortuneAccountBizId());
        if (fortuneAccount == null) {
            throw new BusinessException("出账记录不存在");
        }
        BigDecimal beSplitAmount = BigDecimal.ZERO;
        // 查询所有拆分记录，计算已拆分总金额
        List<SalarySplit> salarySplits = iSalarySplitService.lambdaQuery()
                .eq(SalarySplit::getFortuneAccountBizId, request.getFortuneAccountBizId())
                .list();
        BigDecimal splitTotal = salarySplits.stream()
                .map(SalarySplit::getFromAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        BigDecimal fortuneAmount = fortuneAccount.getHkdAmount() != null ? fortuneAccount.getHkdAmount() : BigDecimal.ZERO;
        beSplitAmount = fortuneAmount.subtract(splitTotal);
        if (beSplitAmount.compareTo(BigDecimal.ZERO) < 0) {
            beSplitAmount = BigDecimal.ZERO; // 防止负数
        }
        ApiQueryRemainingResponse response = new ApiQueryRemainingResponse();
        response.setCurrency(fortuneAccount.getCurrency());
        response.setFromAmount(beSplitAmount);
        return Result.success(response);
    }

    /**
     * 查询-原币种和原币种金额——>目标币种即时汇率和目标币种金额
     * @param request
     * @return
     */
    @Override
    public Result<ApiSalarySplitQueryRateResponse> queryRate(ApiSalarySplitQueryRateRequest request) {
        //查询出账记录是否存在
        FortuneAccount fortuneAccount = fortuneAccountService.queryOne(request.getFortuneAccountBizId());
        if (fortuneAccount == null) {
            throw new BusinessException("出账记录不存在");
        }
        ApiExchangeRateConvertRequest convertRequest = new ApiExchangeRateConvertRequest();
        //原币种金额
        convertRequest.setAmount(request.getFromAmount());
        //原币种
        convertRequest.setFromCurrency(fortuneAccount.getCurrency());
        //目标币种
        convertRequest.setToCurrency(request.getToCurrency());
        //调用远程转换接口
        Result<ApiExchangeRateConvertResponse> result = apiExchangeRateFeignClient.convert(convertRequest);
        if (result != null && result.getData() != null) {
            ApiSalarySplitQueryRateResponse response = new ApiSalarySplitQueryRateResponse();
            BeanUtils.copyProperties(result.getData(),response);
            return Result.success(response);
        }
        return Result.success();
    }

}
