package com.crm.pay.service.impl;

import com.crm.pay.dao.repository.CustomInfoRepository;
import com.crm.pay.service.CustomFundHistoryService;
import com.crm.pay.service.CustomInfoService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.entity.custom.fund.history.CustomFundHistoryAddEntity;
import com.crm.rely.backend.model.pojo.table.CustomInfoTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
public class CustomInfoServiceImpl implements CustomInfoService {

    @Autowired
    private CustomInfoRepository customInfoRepository;

    @Autowired
    private CustomFundHistoryService customFundHistoryService;

    @Override
    public CustomInfoTable getById(Long customId) throws ServiceException {

        CustomInfoTable customInfoTable = customInfoRepository.getFirstById(customId);
        if (customInfoTable == null) {
            throw new ServiceException(Constants.LOGIN_NOT_EXIST_ERROR);
        }
        return customInfoTable;

    }

    @Override
    public CustomInfoTable findFirstById(Long customId) throws ServiceException {

        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(customId);
        if (customInfoTable == null) {
            throw new ServiceException(Constants.LOGIN_NOT_EXIST_ERROR);
        }
        return customInfoTable;

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCnyAmountById(Long customId, BigDecimal cnyAmount) throws ServiceException {
        updateCnyAmountById(customId, cnyAmount, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCnyAmountById(Long customId, BigDecimal cnyAmount, String remarks) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(customId);
        if (customInfoTable == null) {
            return;
        }
        BigDecimal amount;
        if (customInfoTable.getCnyAmount() == null) {
            amount = BigDecimal.ZERO;
        } else {
            amount = customInfoTable.getCnyAmount();
        }
        amount = amount.add(cnyAmount);
        if (cnyAmount.compareTo(BigDecimal.ZERO) < 0 && amount.compareTo(BigDecimal.ZERO) < 0) {
            throw ServiceException.exception(PayConstants.INSUFFICIENT_FUNDS);
        }
        customInfoTable.setCnyAmount(amount);
        customInfoRepository.save(customInfoTable);
        addHistory(customInfoTable, 3, cnyAmount, remarks);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCnyAmountByCId(Long cId, BigDecimal cnyAmount) throws ServiceException {
        updateCnyAmountByCId(cId, cnyAmount, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateCnyAmountByCId(Long cId, BigDecimal cnyAmount, String remarks) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.findFirstByCId(cId);
        if (customInfoTable == null) {
            return;
        }
        BigDecimal amount;
        if (customInfoTable.getCnyAmount() == null) {
            amount = BigDecimal.ZERO;
        } else {
            amount = customInfoTable.getCnyAmount();
        }
        amount = amount.add(cnyAmount);
        if (cnyAmount.compareTo(BigDecimal.ZERO) < 0 && amount.compareTo(BigDecimal.ZERO) < 0) {
            throw ServiceException.exception(PayConstants.INSUFFICIENT_FUNDS);
        }
        customInfoTable.setCnyAmount(amount);
        customInfoRepository.save(customInfoTable);
        addHistory(customInfoTable, 3, cnyAmount, remarks);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUsdAmountById(Long customId, BigDecimal usdAmount) throws ServiceException {
        updateUsdAmountById(customId, usdAmount, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUsdAmountById(Long customId, BigDecimal usdAmount, String remarks) throws ServiceException {

        CustomInfoTable customInfoTable = customInfoRepository.findFirstById(customId);
        if (customInfoTable == null) {
            return;
        }
        BigDecimal amount;
        if (customInfoTable.getUsdAmount() == null) {
            amount = BigDecimal.ZERO;
        } else {
            amount = customInfoTable.getUsdAmount();
        }
        amount = amount.add(usdAmount);
        if (usdAmount.compareTo(BigDecimal.ZERO) < 0 && amount.compareTo(BigDecimal.ZERO) < 0) {
            throw ServiceException.exception(PayConstants.INSUFFICIENT_FUNDS);
        }
        customInfoTable.setUsdAmount(amount);
        customInfoRepository.save(customInfoTable);
        addHistory(customInfoTable, 2, usdAmount, remarks);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUsdAmountByCId(Long cId, BigDecimal usdAmount) throws ServiceException {
        updateUsdAmountByCId(cId, usdAmount, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUsdAmountByCId(Long cId, BigDecimal usdAmount, String remarks) throws ServiceException {
        CustomInfoTable customInfoTable = customInfoRepository.findFirstByCId(cId);
        if (customInfoTable == null) {
            return;
        }
        BigDecimal amount;
        if (customInfoTable.getUsdAmount() == null) {
            amount = BigDecimal.ZERO;
        } else {
            amount = customInfoTable.getUsdAmount();
        }
        amount = amount.add(usdAmount);
        if (usdAmount.compareTo(BigDecimal.ZERO) < 0 && amount.compareTo(BigDecimal.ZERO) < 0) {
            throw ServiceException.exception(PayConstants.INSUFFICIENT_FUNDS);
        }
        customInfoTable.setUsdAmount(amount);
        customInfoRepository.save(customInfoTable);
        addHistory(customInfoTable, 2, usdAmount, remarks);
    }

    private void addHistory(CustomInfoTable customInfoTable, Integer sourceType, BigDecimal amount, String remarks) throws ServiceException {
        CustomFundHistoryAddEntity entity = new CustomFundHistoryAddEntity();
        entity.setCustomId(customInfoTable.getId());
        entity.setCId(customInfoTable.getCId());
        entity.setAgentId(customInfoTable.getAgentId());
        entity.setAmount(amount);
        entity.setRemarks(remarks);
        entity.setSourceType(sourceType);
        customFundHistoryService.add(entity);
    }
}
