package cn.superdesk.uniorder.service.accounting.unified.customer.impl;

import cn.superdesk.uniorder.common.enums.pay.UnifiedOrderPayStateEnum;
import cn.superdesk.uniorder.common.enums.pay.UnifiedOrderPayTypeEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.dao.mapper.invoice.common.InvoiceBankInfoMapper;
import cn.superdesk.uniorder.common.numerical.AnCollectionUtils;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderDimCreateByEnum;
import cn.superdesk.uniorder.dao.entity.accounting.unified.customer.AccountingUnifiedCustomer;
import cn.superdesk.uniorder.dao.entity.accounting.unified.customer.AccountingUnifiedCustomerOrder;
import cn.superdesk.uniorder.dao.entity.accounting.unified.customer.AccountingUnifiedCustomerOrderGoods;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrder;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoods;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApply;
import cn.superdesk.uniorder.dao.entity.organisation.SysEnterprise;
import cn.superdesk.uniorder.dao.entity.organisation.SysOrganization;
import cn.superdesk.uniorder.dao.entity.sys.SysOderUser;
import cn.superdesk.uniorder.dao.entity.invoice.common.InvoiceBankInfo;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.customer.*;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderGoodsMapperEx;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderMapper;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderMapperEx;
import cn.superdesk.uniorder.dao.mapper.base.UnifiedOrderReturnGoodsMapperEx;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyMapperEx;
import cn.superdesk.uniorder.dao.mapper.organisation.SysEnterpriseMapperEx;
import cn.superdesk.uniorder.dao.mapper.organisation.SysOrganizationMapperEx;
import cn.superdesk.uniorder.dao.mapper.scheduler.SysQuartzScheduleTaskStatementOfAccountMapper;
import cn.superdesk.uniorder.dao.mapper.sys.SysConfigMapper;
import cn.superdesk.uniorder.dao.mapper.sys.SysOderUserMapperEx;
import cn.superdesk.uniorder.dao.mapper.sys.SysOrderMapper;
import cn.superdesk.uniorder.dao.mapper.invoice.common.InvoiceBankInfoMapperEx;
import cn.superdesk.uniorder.dto.vo.accounting.unified.customer.ViewDzMainBankInfo;
import cn.superdesk.uniorder.dto.vo.accounting.unified.customer.statement.CustomerStatementOfAccountDetailItemVo;
import cn.superdesk.uniorder.dto.vo.accounting.unified.customer.statement.CustomerStatementOfAccountDetailVo;
import cn.superdesk.uniorder.service.accounting.unified.customer.*;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderCreditService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderGoodsService;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderService;
import cn.superdesk.uniorder.service.sys.SysConfigService;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Description: 客户结算 对账单 公共方法
 * @Author: linjinyu
 * @CreateDate: 2021/1/20 下午4:14
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/1/20 下午4:14
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class AccountingUnifiedCustomerServiceCommonImpl implements AccountingUnifiedCustomerServiceCommon {

	@Autowired
	private AccountingUnifiedCustomerMapper   accountingUnifiedCustomerMapper;
	@Autowired
	private AccountingUnifiedCustomerMapperEx accountingUnifiedCustomerMapperEx;
	@Autowired
	private AccountingUnifiedCustomerService  accountingUnifiedCustomerService;

	@Autowired
	private AccountingUnifiedCustomerXGoodsMapper  accountingUnifiedCustomerXGoodsMapper;
	@Autowired
	private AccountingUnifiedCustomerXGoodsService accountingUnifiedCustomerXGoodsService;


	/****************************************** 对账单 订单 商品 表 将要弃用 start ******************************************/
	@Autowired
	private AccountingUnifiedCustomerOrderMapper   accountingUnifiedCustomerOrderMapper;
	@Autowired
	private AccountingUnifiedCustomerOrderMapperEx accountingUnifiedCustomerOrderMapperEx;

	@Autowired
	private AccountingUnifiedCustomerOrderGoodsMapper   accountingUnifiedCustomerOrderGoodsMapper;
	@Autowired
	private AccountingUnifiedCustomerOrderGoodsMapperEx accountingUnifiedCustomerOrderGoodsMapperEx;

	@Autowired
	private AccountingUnifiedCustomerOrderService      accountingUnifiedCustomerOrderService;
	@Autowired
	private AccountingUnifiedCustomerOrderGoodsService accountingUnifiedCustomerOrderGoodsService;

	/****************************************** 对账单 订单 商品 表 将要弃用   end ******************************************/

	@Autowired
	private InvoiceBankInfoMapper   unifiedBankInfoMapper;
	@Autowired
	private InvoiceBankInfoMapperEx unifiedBankInfoMapperEx;

	@Autowired
	private SysConfigMapper     sysConfigMapper;
	@Autowired
	private SysOrderMapper      sysOrderMapper;
	@Autowired
	private SysOderUserMapperEx sysOderUserMapper;

	@Autowired
	private UnifiedOrderMapper              unifiedOrderMapper;
	@Autowired
	private UnifiedOrderMapperEx            unifiedOrderMapperEx;
	@Autowired
	private UnifiedOrderGoodsMapperEx       unifiedOrderGoodsMapperEx;
	@Autowired
	private UnifiedOrderReturnGoodsMapperEx unifiedOrderReturnGoodsMapperEx;


	@Autowired
	private UnifiedOrderService       unifiedOrderService;
	@Autowired
	private UnifiedOrderGoodsService  unifiedOrderGoodsService;
	@Autowired
	private UnifiedOrderCreditService unifiedOrderCreditService;

	@Autowired
	private SysQuartzScheduleTaskStatementOfAccountMapper sysQuartzScheduleTaskStatementOfAccountMapper;

	@Autowired
	private SysEnterpriseMapperEx   sysEnterpriseMapperEx;
	@Autowired
	private SysOrganizationMapperEx sysOrganizationMapper;

	@Autowired
	private InvoiceApplyMapperEx invoiceApplyMapperEx;

	@Autowired
	private SysConfigService sysConfigService;

	/****************************************** 装箱 转换 start ******************************************/
	/**
	 * 装箱
	 *
	 * @param accountingUnifiedCustomerOrder
	 * @param unifiedOrder
	 */
	public void convertUnifiedOrder2AccountingUnifiedCustomerOrder(AccountingUnifiedCustomerOrder accountingUnifiedCustomerOrder, UnifiedOrder unifiedOrder) {

		accountingUnifiedCustomerOrder.setId(null);

		accountingUnifiedCustomerOrder.setOrderId(unifiedOrder.getId());
		accountingUnifiedCustomerOrder.setOrderSn(unifiedOrder.getOrderSn());

		accountingUnifiedCustomerOrder.setPrice(unifiedOrder.getAmount());
		accountingUnifiedCustomerOrder.setPayType(unifiedOrder.getPayType());

		accountingUnifiedCustomerOrder.setOrderType(unifiedOrder.getServiceNo());
		accountingUnifiedCustomerOrder.setStatus(unifiedOrder.getCompletState());

		accountingUnifiedCustomerOrder.setDispatchPrice(unifiedOrder.getTransportAmount());

		accountingUnifiedCustomerOrder.setOrganizationId(unifiedOrder.getProjectId());
		// 企业ID
		accountingUnifiedCustomerOrder.setEnterpriseId(unifiedOrder.getPurchaseVirtId());

		accountingUnifiedCustomerOrder.setMerchName(unifiedOrder.getSaleName());

		accountingUnifiedCustomerOrder.setRealnameId(Integer.parseInt(unifiedOrder.getPurchaseUserId().toString()));

		// accountingUnifiedCustomerOrder.setExamineId(examineId);
		// accountingUnifiedCustomerOrder.setRemark(order.get);
		// accountingUnifiedCustomerOrder.setMyOrderId(order.getId());

		accountingUnifiedCustomerOrder.setFinishTime(unifiedOrder.getUpdateTime());
		accountingUnifiedCustomerOrder.setCreateTime(unifiedOrder.getCreateTime());

		//add dz 1029
		accountingUnifiedCustomerOrder.setAddressAddress(unifiedOrder.getRecAddress());
		accountingUnifiedCustomerOrder.setAddressMobile(unifiedOrder.getRecUserPhone());
		accountingUnifiedCustomerOrder.setAddressRealname(unifiedOrder.getRecUserName());
	}

	/**
	 * 装箱
	 *
	 * @param accountingUnifiedCustomerOrderGoods
	 * @param unifiedOrderGoods
	 * @param accountingUnifiedCustomerOrderId
	 */
	public void convertUnifiedOrderGoods2AccountingUnifiedCustomerOrderGoods(AccountingUnifiedCustomerOrderGoods accountingUnifiedCustomerOrderGoods, UnifiedOrderGoods unifiedOrderGoods, Long accountingUnifiedCustomerOrderId) {

		accountingUnifiedCustomerOrderGoods.setDzOrderId(accountingUnifiedCustomerOrderId);
		accountingUnifiedCustomerOrderGoods.setGoodId(unifiedOrderGoods.getId());

		accountingUnifiedCustomerOrderGoods.setOptionname(unifiedOrderGoods.getGoodsName());

		// 这个逻辑 也是错的 mark by linjinyu at 202012241722
		accountingUnifiedCustomerOrderGoods.setPrice(new BigDecimal(unifiedOrderGoods.getPrice().doubleValue() * unifiedOrderGoods.getQuantity().doubleValue()));
		accountingUnifiedCustomerOrderGoods.setTotal(unifiedOrderGoods.getQuantity());
		accountingUnifiedCustomerOrderGoods.setTotalPrice(new BigDecimal(unifiedOrderGoods.getPrice().doubleValue() * unifiedOrderGoods.getQuantity().doubleValue()));

		accountingUnifiedCustomerOrderGoods.setUnitPrice(unifiedOrderGoods.getPrice());

		//accountingUnifiedCustomerOrderGoods.setTaxCode(taxCode);
		//accountingUnifiedCustomerOrderGoods.setDispatchPrice(dispatchPrice);
		//accountingUnifiedCustomerOrderGoods.setFiscalCode(fiscalCode);
		//accountingUnifiedCustomerOrderGoods.setGoodno(sysGood.getGoodsName());
		//accountingUnifiedCustomerOrderGoods.setUnit(sysGood.);
	}

	/****************************************** 装箱 转换   end ******************************************/

	public void checkAndFixAccountingUnifiedCustomerOfAccountingAmountOfQuantityOrder(AccountingUnifiedCustomer statementOfAccount) {


		List<CustomerStatementOfAccountDetailItemVo> viewDzorderList = null;

		switch (AccountingOrderDimCreateByEnum.get(statementOfAccount.getDimCreateBy())) {
			case 订单:

				viewDzorderList = getCustomerStatementOfAccountDetailFillItemDimOrder2Goods(statementOfAccount.getId());
				break;
			case 商品:

				viewDzorderList = getCustomerStatementOfAccountDetailFillItemDimGoods2Goods(statementOfAccount.getId());
				break;
			case 流水:
				break;
		}

		if (AnCollectionUtils.isEmpty(viewDzorderList)) {
			return;
		}

		BigDecimal goodsAmount = viewDzorderList
				.stream()
				.map(item -> item.getPrice() == null ? BigDecimal.ZERO : item.getPrice().multiply(new BigDecimal(item.getQuantity())))
				.reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal goodsCostAmount = viewDzorderList
				.stream()
				.map(item -> item.getCostPrice() == null ? BigDecimal.ZERO : item.getCostPrice().multiply(new BigDecimal(item.getQuantity())))
				.reduce(BigDecimal.ZERO, BigDecimal::add);

		Integer quantityOrder = 0;
		quantityOrder = viewDzorderList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn())).collect(Collectors.toList()).size();


		AccountingUnifiedCustomer forUpdate = new AccountingUnifiedCustomer();
		forUpdate.setId(statementOfAccount.getId());
		forUpdate.setAccountingAmount(goodsAmount);
		forUpdate.setQuantityOrder(quantityOrder);
		accountingUnifiedCustomerMapper.updateByPrimaryKeySelective(forUpdate);

	}

	/****************************************** 对账单 详情 start ******************************************/
	@Override
	public CustomerStatementOfAccountDetailVo getCustomerStatementOfAccountDetailDimOrder2Goods(Long accountingOrderId) {

		Map<String, Object> params = new HashMap<>();
		// accounting_unified_customer.id
		params.put("id", accountingOrderId);

		// 用id 查询,只会有一个吧? NND 这不就是accounting_unified_customer吗?还这样写,唉,没空改,但这有点弱智
		List<CustomerStatementOfAccountDetailVo> customerStatementOfAccountDetailVoList = accountingUnifiedCustomerMapperEx.getAccountingUnifiedCustomerView(params);


		if (AnCollectionUtils.isEmpty(customerStatementOfAccountDetailVoList)) {
			return null;
		} else {


			/****************************************** 填充对账单信息 start ******************************************/
			CustomerStatementOfAccountDetailVo customerStatementOfAccountDetailVo = customerStatementOfAccountDetailVoList.get(0);

			// 填充 收货人信息
			customerStatementOfAccountDetailVoFillPurchaseInfo(customerStatementOfAccountDetailVo);

			// 填充 企业信息 项目信息
			customerStatementOfAccountDetailVoFillVirtInfo(customerStatementOfAccountDetailVo);

			// 填充 收款方 信息
			customerStatementOfAccountDetailVoFillBankinfo(customerStatementOfAccountDetailVo);
			/****************************************** 填充对账单信息   end ******************************************/


			/****************************************** 填充对账单 订单商品信息 TODO 待重构 将弃用 start ******************************************/
			List<CustomerStatementOfAccountDetailItemVo> customerStatementOfAccountDetailItemVoList = getCustomerStatementOfAccountDetailFillItemDimOrder2Goods(customerStatementOfAccountDetailVo.getId());

			// TODO 填充发票信息 很大的问题呀
//			customerStatementOfAccountDetailItemVoFillInvoiceInfo(customerStatementOfAccountDetailItemVoList);
			customerStatementOfAccountDetailItemVoFillOrderEff(customerStatementOfAccountDetailItemVoList);
			customerStatementOfAccountDetailVo.setOrders(customerStatementOfAccountDetailItemVoList);
			/****************************************** 填充对账单 订单信息 TODO 待重构 将弃用   end ******************************************/

			return customerStatementOfAccountDetailVo;

		}

	}

	@Override
	public CustomerStatementOfAccountDetailVo getCustomerStatementOfAccountDetailDimGoods2Goods(Long accountingOrderId) {

		/****************************************** 填充对账单信息 start ******************************************/

		AccountingUnifiedCustomer accountingUnifiedCustomer = accountingUnifiedCustomerService.findById(accountingOrderId);

		if (null == accountingUnifiedCustomer) {
			return null;
		}

		CustomerStatementOfAccountDetailVo customerStatementOfAccountDetailVo = AnBeanUtils.copy(accountingUnifiedCustomer, CustomerStatementOfAccountDetailVo.class);

		log.info("观察COPY情况 \n{}\n{}", AnJsonUtils.toJson(accountingUnifiedCustomer), AnJsonUtils.toJson(customerStatementOfAccountDetailVo));

		// 填充 收货人信息
		customerStatementOfAccountDetailVoFillPurchaseInfo(customerStatementOfAccountDetailVo);

		// 填充 企业信息 项目信息
		customerStatementOfAccountDetailVoFillVirtInfo(customerStatementOfAccountDetailVo);

		// 填充 收款方 信息
		customerStatementOfAccountDetailVoFillBankinfo(customerStatementOfAccountDetailVo);

		/****************************************** 填充对账单信息   end ******************************************/


		/****************************************** 填充对账单 订单信息 start ******************************************/
		List<CustomerStatementOfAccountDetailItemVo> customerStatementOfAccountDetailItemVoList = getCustomerStatementOfAccountDetailFillItemDimGoods2Goods(customerStatementOfAccountDetailVo.getId());

		// TODO 填充发票信息 很大的问题呀
//		customerStatementOfAccountDetailItemVoFillInvoiceInfo(customerStatementOfAccountDetailItemVoList);

		customerStatementOfAccountDetailItemVoFillOrderEff(customerStatementOfAccountDetailItemVoList);
		customerStatementOfAccountDetailVo.setOrders(customerStatementOfAccountDetailItemVoList);
		/****************************************** 填充对账单 订单信息   end ******************************************/

		return customerStatementOfAccountDetailVo;
	}

	private void customerStatementOfAccountDetailVoFillPurchaseInfo(CustomerStatementOfAccountDetailVo customerStatementOfAccountDetailVo) {
		SysOderUser orderUser = sysOderUserMapper.selectByUserId(customerStatementOfAccountDetailVo.getPurchaseUserId());

		if (orderUser != null) {
			customerStatementOfAccountDetailVo.setPurchaseUserName(orderUser.getRealname());
			customerStatementOfAccountDetailVo.setPurchasePhone(orderUser.getMobile());
			customerStatementOfAccountDetailVo.setBillEmail(orderUser.getBillEmail());
		}
	}

	private void customerStatementOfAccountDetailVoFillVirtInfo(CustomerStatementOfAccountDetailVo customerStatementOfAccountDetailVo) {

		SysEnterprise enterprise = sysEnterpriseMapperEx.findByVirtId(customerStatementOfAccountDetailVo.getEnterpriseId());

		if (enterprise != null) {

			customerStatementOfAccountDetailVo.setProjectId(enterprise.getOrganizationId());

			SysOrganization organization = sysOrganizationMapper.getByOutOrgId(enterprise.getOrganizationId());
			if (organization != null) {
				customerStatementOfAccountDetailVo.setProjectName(organization.getOrganizationName());
			}

			customerStatementOfAccountDetailVo.setEnterpriseName(enterprise.getEnterpriseName());
		}
	}

	private void customerStatementOfAccountDetailVoFillBankinfo(CustomerStatementOfAccountDetailVo customerStatementOfAccountDetailVo) {

		if (null != customerStatementOfAccountDetailVo.getBankInfoId()) {

			InvoiceBankInfo    bankInfo           = unifiedBankInfoMapper.selectByPrimaryKey(customerStatementOfAccountDetailVo.getBankInfoId());
			ViewDzMainBankInfo viewDzMainBankInfo = AnBeanUtils.copy(bankInfo, ViewDzMainBankInfo.class);
			customerStatementOfAccountDetailVo.setBankInfo(viewDzMainBankInfo);
		} else {
			ViewDzMainBankInfo viewDzMainBankInfo = new ViewDzMainBankInfo();
			viewDzMainBankInfo.setCompanyName("楼宇云仓商贸(深圳)有限公司");
			viewDzMainBankInfo.setBankAccount("7559 4355 0010 501");
			viewDzMainBankInfo.setBankName("招商银行深圳福华路支行");
			viewDzMainBankInfo.setSupplyName("深圳市超级前台信息技术有限公司");
			viewDzMainBankInfo.setTel("400-8386-065");
			viewDzMainBankInfo.setAddress("深圳市 福田区 深南中路3024号 航空大厦32层7-11室");

			customerStatementOfAccountDetailVo.setBankInfo(viewDzMainBankInfo);
		}
	}


	private void customerStatementOfAccountDetailItemVoFillOrderEff(List<CustomerStatementOfAccountDetailItemVo> viewDzorderList) {

		log.info("{}", AnJsonUtils.toJson(viewDzorderList));

		int index = 1;
		for (CustomerStatementOfAccountDetailItemVo vo : viewDzorderList) {

			vo.setRowNum(index++);

			if (StringUtils.isBlank(vo.getPayTypeName())) {

				vo.setPayTypeName(UnifiedOrderPayTypeEnum.getDesc(vo.getPayType()));
			}
			if (StringUtils.isBlank(vo.getPayStateName())) {
				vo.setPayStateName(UnifiedOrderPayStateEnum.getDesc(vo.getPayState()));
			}


		}

		log.info("{}", AnJsonUtils.toJson(viewDzorderList));
	}

	private void customerStatementOfAccountDetailItemVoFillInvoiceInfo(List<CustomerStatementOfAccountDetailItemVo> viewDzorderList) {

		for (CustomerStatementOfAccountDetailItemVo orderItem : viewDzorderList) {

			// 临时 查找 发票信息
			Map<String, Object> invQuery = new HashMap<>();
			invQuery.put("orderSn", orderItem.getOrderSn());
			List<InvoiceApply> invoiceApplyList = invoiceApplyMapperEx.findInvoiceByOrderSn(invQuery);

			if (invoiceApplyList != null && invoiceApplyList.size() == 1) {

				orderItem.setInvoiceNumber(invoiceApplyList.get(0).getInvoiceNumber());
				orderItem.setInvoiceApplySn(invoiceApplyList.get(0).getInvoiceApplySn());
			}
		}
	}

	/****************************************** 对账单 详情   end ******************************************/

	/****************************************** 对账单 详情 填充明细 OrderJoinGoods start ******************************************/
	public List<CustomerStatementOfAccountDetailItemVo> getCustomerStatementOfAccountDetailFillItemDimOrder2Goods(Long accountingOrderId) {

		Map<String, Object> paramsOrder = new HashMap<>();
		paramsOrder.put("dzId", accountingOrderId);
		// 目前是这样拉数据 TODO 待重构
//			accounting_unified_customer_order auco
//			LEFT JOIN unified_order uo ON auco.order_sn = uo.order_sn
//			LEFT JOIN unified_order_goods uog ON uo.order_sn = uog.order_sn
		List<CustomerStatementOfAccountDetailItemVo> customerStatementOfAccountDetailItemVoList = accountingUnifiedCustomerMapperEx.getCustomerStatementOfAccountDetailFillItemDimOrder2Goods(paramsOrder);

		return customerStatementOfAccountDetailItemVoList;
	}

	public List<CustomerStatementOfAccountDetailItemVo> getCustomerStatementOfAccountDetailFillItemDimGoods2Goods(Long accountingOrderId) {

		List<CustomerStatementOfAccountDetailItemVo> customerStatementOfAccountDetailItemVoList = accountingUnifiedCustomerMapperEx.getCustomerStatementOfAccountDetailFillItemDimGoods2Goods(accountingOrderId, "");

		return customerStatementOfAccountDetailItemVoList;
	}
	/****************************************** 对账单 详情 填充明细 OrderJoinGoods   end ******************************************/


}
