package com.dk.mdm.service.mac;

import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.model.pojo.PageList;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.mdm.infrastructure.convert.mac.MacTransferConvert;
import com.dk.mdm.infrastructure.convert.mac.MacTransferItemConvert;
import com.dk.mdm.mapper.mac.MacTransferItemMapper;
import com.dk.mdm.mapper.mst.MoneyAccountItemMapper;
import com.dk.mdm.mapper.mst.MoneyAccountMapper;
import com.dk.mdm.model.pojo.mac.MacTransfer;
import com.dk.mdm.mapper.mac.MacTransferMapper;
import com.dk.common.service.BaseService;
import com.dk.common.mapper.BaseMapper;
import com.dk.mdm.model.pojo.mac.MacTransferItem;
import com.dk.mdm.model.pojo.mst.MoneyAccount;
import com.dk.mdm.model.pojo.mst.MoneyAccountItem;
import com.dk.mdm.model.query.mac.*;
import com.dk.mdm.model.response.mac.*;
import com.dk.mdm.model.vo.mac.MacTransferVO;
import com.dk.mdm.model.vo.mac.MacTransferItemVO;
import com.dk.mdm.service.common.CommonService;
import com.dk.mdm.service.mst.MoneyAccountService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class MacTransferService extends BaseService<MacTransfer> {

	@Override
	public String getPrimaryKey() {
		return "trf_id";
	}

	@Override
	public BaseMapper<MacTransfer> getRepository() {
		return macTransferMapper;
	}

	@Autowired
	private MacTransferMapper macTransferMapper;

	@Autowired
	private MacTransferItemMapper macTransferItemMapper;

	@Autowired
	private MoneyAccountService moneyAccountService;

	@Autowired
	private MoneyAccountMapper moneyAccountMapper;

	@Autowired
	private MoneyAccountItemMapper moneyAccountItemMapper;

	@Autowired
	private AccountService accountService;

	@Autowired
	private CommonService commonService;

	@Autowired
	private MacTransferConvert macTransferConvert;

	@Autowired
	private MacTransferItemConvert macTransferItemConvert;

	/**
	 * @desc : 条件查询
	 * @author : 付斌
	 * @date : 2023/1/9 10:40
	 */
	@Pagination
	public ResponseResultVO<PageList<MacTransferResponse>> selectByCond(MacTransferQuery macTransferQuery) {
		List<MacTransferResponse> list = macTransferMapper.selectByCond(macTransferQuery);
		for(int i =0;i<list.size();i++){ //显示明细第一条的 内容
			MacTransferResponse  macTransferResponse = list.get(i);
			// 转账明细
			List<MacTransferItemResponse> itemList = macTransferItemMapper.selectByCond(new MacTransferItemQuery().setTrfId(list.get(i).getTrfId()));
	     if(itemList.size()>0){
			 MacTransferItemResponse macTransferItemResponse = itemList.get(0);
			 macTransferResponse.setTrfInMac(macTransferItemResponse.getTrfInMac());
			 macTransferResponse.setTrfOutMac(macTransferItemResponse.getTrfOutMac());
			 macTransferResponse.setAmtTrf(macTransferItemResponse.getAmtTrf());
			 macTransferResponse.setTrfInMacName(macTransferItemResponse.getTrfInMacName());
			 macTransferResponse.setTrfOutMacName(macTransferItemResponse.getTrfOutMacName());
		 }
		}

		return super.mergeListWithCount(macTransferQuery, list,
				macTransferMapper.countByCond(macTransferQuery));
	}

	/**
	 * @desc : 查询转账明细
	 * @author : 付斌
	 * @date : 2024-02-28 13:25
	 */
	@Pagination
	public ResponseResultVO<Map<String, Object>> selectMacTransferInfoById(String id) {
		Map<String, Object> result = new HashMap<>();
		// 转账明细
		List<MacTransferItemResponse> macTransferItemResponse = macTransferItemMapper.selectByCond(new MacTransferItemQuery().setTrfId(id));
		result.put("macTransferItem", macTransferItemResponse);

		// 附件
		return ResponseResultUtil.success(result);
	}

	/**
	 * @desc   : 条件查询
	 * @author : 付斌
	 * @date   : 2023/2/29 10:40
	 */
	@Pagination
	public ResponseResultVO selectById(String id) {
		MacTransferResponse macTransferResponse = macTransferMapper.selectById(id);
		return ResponseResultUtil.success(macTransferResponse);
	}

	/**
	 * @desc : 新建
	 * @author : 付斌
	 * @date : 2023/2/29 10:49
	 */
	@Transactional(
			rollbackFor = {Exception.class}
	)
	public ResponseResultVO<?> insert(MacTransferVO macTransferVO) {
		// 转化实体
		MacTransfer macTransfer = macTransferConvert.convertToPo(macTransferVO);

		// 获取编码和主键UuId
		Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.MACTRANSFER.getName(),true);
		macTransfer.setTrfId(codeMap.get("outId").toString()).setTrfNo(codeMap.get("outNote").toString());
		macTransferMapper.insert(macTransfer);

		// 明细保存
		if (macTransferVO.getItemList() != null && macTransferVO.getItemList().size() > 0) {
			for (MacTransferItemVO macTransferItemVO : macTransferVO.getItemList()) {
				MacTransferItem macTransferItem = macTransferItemConvert.convertToPo(macTransferItemVO);
				macTransferItem.setTrfId(macTransfer.getTrfId()).setCpId(macTransfer.getCpId()).setMakeStaff(macTransfer.getMakeStaff());
				macTransferItemMapper.insert(macTransferItem);

				// 更新资金账户
				MoneyAccount moneyAccountForUpdate = moneyAccountMapper.selectByIdForUpdate(macTransferItem.getTrfOutMac());
				// 如果账户不允许为负数
				if(!moneyAccountForUpdate.getFlgNegative()){
					// 如果账户余额比转出金额小，就不允许转出
					if(moneyAccountForUpdate.getBalance().compareTo(macTransferItem.getAmtTrf()) == -1){
						throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.MAC_BALANCE_NO_LESS.getMessage());
					}
				}

				// 插入转出流水
				MoneyAccountItem moneyAccountItem = new MoneyAccountItem();
				moneyAccountItem.setMacId(macTransferItem.getTrfOutMac()).setFlowType(Constant.FlowType.ZHUAN_ZHANG.getName())
						.setInvoiceId(macTransferItem.getItemId()).setAmtInflow(macTransferItem.getAmtTrf().negate()).setAccDate(macTransfer.getAccDate())
						.setMakeStaff(macTransferVO.getMakeStaff()).setCpId(macTransfer.getCpId());
				moneyAccountItemMapper.insert(moneyAccountItem);

				MoneyAccount moneyAccountUpdate = new MoneyAccount();
				moneyAccountUpdate.setBalance(moneyAccountForUpdate.getBalance().subtract(macTransferItem.getAmtTrf()))
						.setMacId(moneyAccountForUpdate.getMacId());
				moneyAccountService.updateByUuid(moneyAccountUpdate);

				// 插入转入流水
				moneyAccountItem = new MoneyAccountItem();
				moneyAccountItem.setMacId(macTransferItem.getTrfInMac()).setFlowType(Constant.FlowType.ZHUAN_ZHANG.getName())
						.setInvoiceId(macTransferItem.getItemId()).setAmtInflow(macTransferItem.getAmtTrf()).setAccDate(macTransfer.getAccDate())
						.setMakeStaff(macTransferVO.getMakeStaff()).setCpId(macTransfer.getCpId());
				moneyAccountItemMapper.insert(moneyAccountItem);

				// 更新资金账户
				moneyAccountForUpdate = moneyAccountMapper.selectByIdForUpdate(macTransferItem.getTrfInMac());
				moneyAccountUpdate = new MoneyAccount();
				moneyAccountUpdate.setBalance(moneyAccountForUpdate.getBalance().add(macTransferItem.getAmtTrf()))
						.setMacId(moneyAccountForUpdate.getMacId());
				moneyAccountService.updateByUuid(moneyAccountUpdate);
			}
		}
		return ResponseResultUtil.success();
	}

	/**
	 * @desc : 更新
	 * @author : 付斌
	 * @date : 2023/2/29 10:49
	 */
	@Transactional(
			rollbackFor = {Exception.class}
	)
	public ResponseResultVO<?> update(MacTransferVO macTransferVO) {
		MacTransfer macTransferForUpdate =  macTransferMapper.selectByIdForUpdate(macTransferVO.getTrfId());
		if(!macTransferForUpdate.getFlgValid()){
			throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVOICE_ISFLGVALID_FALSE.getMessage());
		}
		// 如果是期初转账，不允许操作
		if(macTransferForUpdate.getTrfType() == 0){
			throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVOICE_ISQICHU.getMessage());
		}

		// 将之前的明细全部删除
		List<MacTransferItem> MacTransferItemOriginalList = macTransferItemMapper.selectByZIdForUpdate(macTransferVO.getTrfId());
		// 需要重新计算的资金账户
		List<String> macList = new ArrayList<>();
		for (MacTransferItem macTransferItem : MacTransferItemOriginalList) {
			// 删除收付款明细
			macTransferItemMapper.deleteById(macTransferItem.getItemId());
			// 删除账户流水
			moneyAccountItemMapper.deleteByInvoiceId(macTransferItem.getItemId());

			if (!macList.contains(macTransferItem.getTrfOutMac())) {
				macList.add(macTransferItem.getTrfOutMac());
			}
			if (!macList.contains(macTransferItem.getTrfInMac())) {
				macList.add(macTransferItem.getTrfInMac());
			}
		}

		// 新增明细
		if (macTransferVO.getItemList() != null && macTransferVO.getItemList().size() > 0) {
			for (MacTransferItemVO macTransferItemVO : macTransferVO.getItemList()) {
				MacTransferItem macTransferItem = macTransferItemConvert.convertToPo(macTransferItemVO);
				macTransferItem.setItemId(null);
				macTransferItemMapper.insert(macTransferItem);

				// 插入转出流水
				MoneyAccountItem moneyAccountItem = new MoneyAccountItem();
				moneyAccountItem.setMacId(macTransferItem.getTrfOutMac()).setFlowType(Constant.FlowType.ZHUAN_ZHANG.getName())
						.setInvoiceId(macTransferItem.getItemId()).setAmtInflow(macTransferItem.getAmtTrf().negate()).setAccDate(macTransferVO.getAccDate())
						.setMakeStaff(macTransferVO.getMakeStaff()).setCpId(macTransferVO.getCpId());
				moneyAccountItemMapper.insert(moneyAccountItem);

				// 插入转入流水
				moneyAccountItem = new MoneyAccountItem();
				moneyAccountItem.setMacId(macTransferItem.getTrfInMac()).setFlowType(Constant.FlowType.ZHUAN_ZHANG.getName())
						.setInvoiceId(macTransferItem.getItemId()).setAmtInflow(macTransferItem.getAmtTrf()).setAccDate(macTransferVO.getAccDate())
						.setMakeStaff(macTransferVO.getMakeStaff()).setCpId(macTransferVO.getCpId());
				moneyAccountItemMapper.insert(moneyAccountItem);

				if (!macList.contains(macTransferItem.getTrfOutMac())) {
					macList.add(macTransferItem.getTrfOutMac());
				}
				if (!macList.contains(macTransferItem.getTrfInMac())) {
					macList.add(macTransferItem.getTrfInMac());
				}
			}
		}
		// 转化实体
		MacTransfer macTransfer = macTransferConvert.convertToPo(macTransferVO);
		super.updateByUuid(macTransfer);

		// 更新账户余额
		for (String macId : macList) {
			accountService.updateMac(macId);
		}

		return ResponseResultUtil.success();
	}

	/**
	 * @desc : 查询转账明细（编辑用）
	 * @author : 付斌
	 * @date : 2024-03-02 17:27
	 */
	public ResponseResultVO<?> getMacTransferForUpdate(String id) {
		Map<String, Object> dataInfo = new HashMap<>();
		MacTransferResponse macTransferResponse = macTransferMapper.selectById(id);
		dataInfo.put("data", macTransferResponse);

		// 转账明细
		List<MacTransferItemResponse> macTransferItemResponse = macTransferItemMapper.selectByCond(new MacTransferItemQuery().setTrfId(id));
		dataInfo.put("dataItem", macTransferItemResponse);

		return ResponseResultUtil.success(dataInfo);
	}

	/**
	 * @desc : 作废
	 * @author : 付斌
	 * @date : 2024-03-08 16:38
	 */
	public ResponseResultVO<?> invalid(String id) {
		MacTransfer macTransferForUpdate = macTransferMapper.selectByIdForUpdate(id);
		// 并发校验
		if (!macTransferForUpdate.getFlgValid()) {
			throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.ISFLGVALID_FALSE.getMessage());
		}
		// 如果是期初转账，不允许操作
		if(macTransferForUpdate.getTrfType() == 0){
			throw new BaseBusinessException(ResponseCodeEnum.OPERATE_FAIL.getCode(), ErrorCodeEnum.INVOICE_ISQICHU.getMessage());
		}

		// 将之前的明细全部删除
		List<MacTransferItem> MacTransferItemOriginalList = macTransferItemMapper.selectByZIdForUpdate(id);
		// 需要重新计算的资金账户
		List<String> macList = new ArrayList<>();
		for (MacTransferItem macTransferItem : MacTransferItemOriginalList) {
			// 删除收付款明细
			macTransferItemMapper.deleteById(macTransferItem.getItemId());
			// 删除账户流水
			moneyAccountItemMapper.deleteByInvoiceId(macTransferItem.getItemId());

			if (!macList.contains(macTransferItem.getTrfOutMac())) {
				macList.add(macTransferItem.getTrfOutMac());
			}
			if (!macList.contains(macTransferItem.getTrfInMac())) {
				macList.add(macTransferItem.getTrfInMac());
			}
		}

		// 更新账户余额
		for (String macId : macList) {
			accountService.updateMac(macId);
		}

		// 作废
		MacTransfer macTransferUpdate = new MacTransfer();
		macTransferUpdate.setFlgValid(false).setTrfId(id);
		super.updateByUuid(macTransferUpdate);
		return ResponseResultUtil.success();
	}
}
