package cn.superdesk.uniorder.service.accounting.unified.supplier.Impl;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.common.CommonNeedReviseMarkEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderDimCreateByEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderInvoiceApplyStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderIsSendEmailEnum;
import cn.superdesk.uniorder.common.enums.accounting.supplier.AccountingOrderSupplierAccountingStatusEnum;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnStringUtils;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplier;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplierXGoods;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrder;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoods;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.supplier.*;
import cn.superdesk.uniorder.dao.mapper.base.*;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.UnifiedSupplierCreateDimOrderParam;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierServiceOpCreateDimOrder;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierServiceOpStatistics;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierXGoodsService;
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.setting.UnifiedSnConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 供应商结算 创建对账单 (订单维度)
 * @Author: linjinyu
 * @CreateDate: 2021/10/25 下午7:54
 * @UpdateUser: linjinyu
 * @UpdateDate: 2021/10/25 下午7:54
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class AccountingUnifiedSupplierServiceOpCreateDimOrderImpl implements AccountingUnifiedSupplierServiceOpCreateDimOrder {

	@Autowired
	private UnifiedOrderMapper                   unifiedOrderMapper;
	@Autowired
	private UnifiedOrderMapperEx                 unifiedOrderMapperEx;
	@Autowired
	private UnifiedOrderMapperExSupplierDimOrder unifiedOrderMapperExSupplierDimOrder;
	@Autowired
	private UnifiedOrderService                  unifiedOrderService;

	@Autowired
	private UnifiedOrderGoodsMapper   unifiedOrderGoodsMapper;
	@Autowired
	private UnifiedOrderGoodsMapperEx unifiedOrderGoodsMapperEx;
	@Autowired
	private UnifiedOrderGoodsService  unifiedOrderGoodsService;

	@Autowired
	private UnifiedOrderCreditMapper  unifiedOrderCreditMapper;
	@Autowired
	private UnifiedOrderCreditService unifiedOrderCreditService;

	@Autowired
	private AccountingUnifiedSupplierMapper   accountingUnifiedSupplierMapper;
	@Autowired
	private AccountingUnifiedSupplierMapperEx accountingUnifiedSupplierMapperEx;

	@Autowired
	private AccountingUnifiedSupplierOrderMapper    accountingUnifiedSupplierOrderMapper;
	@Autowired
	private AccountingUnifiedSupplierXOrderMapperEx accountingUnifiedSupplierXOrderMapperEx;

	@Autowired
	private AccountingUnifiedSupplierXGoodsMapper   accountingUnifiedSupplierXGoodsMapper;
	@Autowired
	private AccountingUnifiedSupplierXGoodsMapperEx accountingUnifiedSupplierXGoodsMapperEx;

	@Autowired
	private AccountingUnifiedSupplierXGoodsService accountingUnifiedSupplierXGoodsService;

	@Autowired
	private AccountingUnifiedSupplierServiceOpStatistics accountingUnifiedSupplierServiceOpStatistics;

	@Autowired
	private UnifiedSnConfigService unifiedSnConfigService;

	@Override
	public AccountingUnifiedSupplier opCreateAccountingDimOrderPreProcess(UnifiedSupplierCreateDimOrderParam unifiedSupplierCreateDimOrderParam, LoginSysUser loginSysUser) {

		AccountingUnifiedSupplier accountingUnifiedSupplier = new AccountingUnifiedSupplier();

		if (StringUtils.isNotEmpty(unifiedSupplierCreateDimOrderParam.getStartTime())
				&& StringUtils.isNotEmpty(unifiedSupplierCreateDimOrderParam.getEndTime())) {

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

			try {

				accountingUnifiedSupplier.setStartTime(sdf.parse(unifiedSupplierCreateDimOrderParam.getStartTime()));
				accountingUnifiedSupplier.setEndTime(sdf.parse(unifiedSupplierCreateDimOrderParam.getEndTime()));

			} catch (ParseException e) {

				e.printStackTrace();
				return null;
			}
		}


		/****************************************** 前端没有传 start ******************************************/

		accountingUnifiedSupplier.setAddress(unifiedSupplierCreateDimOrderParam.getAddress());

		if (StringUtils.isNotEmpty(unifiedSupplierCreateDimOrderParam.getIsEmail())) {
			accountingUnifiedSupplier.setIsSendEmail(Integer.valueOf(unifiedSupplierCreateDimOrderParam.getIsEmail()));
		} else {
			// TODO 写死 0
			accountingUnifiedSupplier.setIsSendEmail(AccountingOrderIsSendEmailEnum.未发送.getKey());
		}

		accountingUnifiedSupplier.setInvoiceTitle(unifiedSupplierCreateDimOrderParam.getInvTitle());

		if (StringUtils.isNotEmpty(unifiedSupplierCreateDimOrderParam.getInvType())) {
			accountingUnifiedSupplier.setInvoiceType(Integer.valueOf(unifiedSupplierCreateDimOrderParam.getInvType()));
		} else {
			// TODO 写死
			accountingUnifiedSupplier.setInvoiceType(1);
		}
		accountingUnifiedSupplier.setTaxCode(unifiedSupplierCreateDimOrderParam.getTaxCode());

		/****************************************** 前端没有传   end ******************************************/

		accountingUnifiedSupplier.setAccountingStatus(AccountingOrderSupplierAccountingStatusEnum.待提交.getKey());

		accountingUnifiedSupplier.setInvoiceStatus(AccountingOrderInvoiceApplyStatusEnum.未申请.getKey());

		// 0-未申请;1-全部申请;2-部分申请;
		accountingUnifiedSupplier.setInvoiceApplyStatus(AccountingOrderInvoiceApplyStatusEnum.未申请.getKey());
		accountingUnifiedSupplier.setInvoiceApplyModeRecord(0);
		accountingUnifiedSupplier.setInvoiceApplyTime(DateUtil.date());
		accountingUnifiedSupplier.setInvoiceApplyUserId(loginSysUser.getSysUserId());

		accountingUnifiedSupplier.setBackAccountStatus(AccountingOrderBackAccountStatusEnum.未回款.getKey());

		accountingUnifiedSupplier.setCreateTime(DateUtil.date());
		accountingUnifiedSupplier.setCreateUserId(loginSysUser.getSysUserId());

		accountingUnifiedSupplier.setNeedReviseMark(CommonNeedReviseMarkEnum.正常.getKey());


		/****************************************** 差异部分 Dim Order start ******************************************/

		// 对账单 关联的 订单
		UnifiedOrder order = unifiedOrderService.findById(Long.parseLong(unifiedSupplierCreateDimOrderParam.getIds().split(",")[0]));

		// 取 供应商 商户 信息
		if (StringUtils.isNotEmpty(unifiedSupplierCreateDimOrderParam.getSaleId())) {
			accountingUnifiedSupplier.setSaleId(Long.parseLong(unifiedSupplierCreateDimOrderParam.getSaleId()));
			accountingUnifiedSupplier.setSaleName(unifiedSupplierCreateDimOrderParam.getSaleName());
		} else {
			accountingUnifiedSupplier.setSaleId(order.getSaleId());
			accountingUnifiedSupplier.setSaleName(order.getSaleName());
		}

		String accountingOrderSn = unifiedSnConfigService.getSupplierStatementOfAccountSnBySnowflake(order.getServiceNo());

		/****************************************** 差异部分 Dim Order  end ******************************************/

		if (StringUtils.isEmpty(accountingOrderSn)) {
			return null;
		}
//		if (StringUtils.isEmpty(accountingOrderSn)) {
//			return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setErrorMsg(500, "创建对账单操作-失败-生成对账单编号失败-有可能是服务号未配置-请联系管理员");
//		}

		accountingUnifiedSupplier.setAccountingOrderSn(accountingOrderSn);

		return opCreateAccountingDimOrder(accountingUnifiedSupplier, unifiedSupplierCreateDimOrderParam.getIds());
	}

	/**
	 * 平台工作人员-为供应商-创建对帐单()
	 *
	 * @param statementOfAccount
	 * @param ids
	 * @return
	 */
	@Transactional
	@Override
	public AccountingUnifiedSupplier opCreateAccountingDimOrder(AccountingUnifiedSupplier statementOfAccount, /* uo.id */String ids) {

		statementOfAccount.setDimCreateBy(AccountingOrderDimCreateByEnum.订单.getKey());

		// 对账单 信息在上一步已经好了
		accountingUnifiedSupplierMapper.insert(statementOfAccount);

		List<Long>        processSysUnifiedOrderIds    = AnStringUtils.stringArrayConvertToLongList(ids, ",");
		Map<String, Long> mapOrderSn2SysUnifiedOrderId = unifiedOrderService.convertSysUnifiedOrderIds2MapOrderSn2SysUnifiedOrderId(processSysUnifiedOrderIds);
		List<String>      processOrderSn               = unifiedOrderService.convertSysUnifiedOrderIds2OrderSn(processSysUnifiedOrderIds);


		Map<String, Object> params = new HashMap<>();
		params.put("dimCreateBy", AccountingOrderDimCreateByEnum.订单.getKey());
		params.put("accountingOrderSn", statementOfAccount.getAccountingOrderSn());
		params.put("ids", processSysUnifiedOrderIds); // 这个是 uo.id ids.split(",")
		// 对账单 X 订单
		accountingUnifiedSupplierXOrderMapperEx.createRelation(params);

		// 批量插入
		List<AccountingUnifiedSupplierXGoods> processAccountingUnifiedSupplierXGoodsList = new ArrayList<>();

		// 对账单 X [订单] X 商品 TODO mark by linjinyu 20201029 由于时间赶 先这样弄 一条条没效率 | 已优化 mark by linjinyu at 20211203
		List<UnifiedOrderGoods> processUnifiedOrderGoodsList = unifiedOrderGoodsService.findByOrderSns(processOrderSn);

		List<Long> processSysUnifiedOrderGoodsIds = processUnifiedOrderGoodsList.stream().filter(o -> null != o.getId()).filter(AnLamdaUtils.distinctByKey(o -> o.getId())).map(UnifiedOrderGoods::getId).collect(Collectors.toList());

		for (UnifiedOrderGoods processUnifiedOrderGoods : processUnifiedOrderGoodsList) {

			AccountingUnifiedSupplierXGoods xGoods = new AccountingUnifiedSupplierXGoods();

			xGoods.setDimCreateBy(AccountingOrderDimCreateByEnum.订单.getKey());

			xGoods.setAccountingOrderId(statementOfAccount.getId());
			xGoods.setAccountingOrderSn(statementOfAccount.getAccountingOrderSn());

			xGoods.setUnifiedOrderId(mapOrderSn2SysUnifiedOrderId.get(processUnifiedOrderGoods.getOrderSn()));
			xGoods.setOrderSn(processUnifiedOrderGoods.getOrderSn());

			xGoods.setUnifiedOrderGoodsId(processUnifiedOrderGoods.getId());
			xGoods.setGoodsId(processUnifiedOrderGoods.getGoodsId());
			xGoods.setOutSnapshotOrderGoodsId(processUnifiedOrderGoods.getOutSnapshotOrderGoodsId());

			xGoods.setCreateUserId(1L);
			xGoods.setCreateTime(DateUtil.date());
			xGoods.setUpdateUserId(1L);
			xGoods.setCreateTime(DateUtil.date());

			processAccountingUnifiedSupplierXGoodsList.add(xGoods);

		}

		accountingUnifiedSupplierXGoodsService.insertBatch(processAccountingUnifiedSupplierXGoodsList);

		// 更新 订单 供应商对账状态
		unifiedOrderService.updateAccountingStateSupplierByOrderSns(processOrderSn, CommonAccountingStateEnum.已对账);

		// 更新 商品 供应商对账状态
		unifiedOrderGoodsService.updateAccountingStateSupplierByOrderSn(processOrderSn, CommonAccountingStateEnum.已对账);

		// 更新 流水 供应商对账状态 20200925 供应商结算 创建对账单 如果 积分流水 有的话 关联 更新状态 为 已对账状态
		unifiedOrderCreditService.updateFieldAccountingStateSupplierByOrderSn(processOrderSn, CommonAccountingStateEnum.已对账);

		// 统计
//		accountingUnifiedSupplierServiceOpStatistics.statistics(statementOfAccount, processSysUnifiedOrderIds, processSysUnifiedOrderGoodsIds);

		// 待整改
		return statementOfAccount;

//		return new ResponseResultInnerUtils<AccountingUnifiedSupplier>().setData(statementOfAccount, "创建对账单操作-成功");
	}
}
