package cn.superdesk.uniorder.service.invoice.supplier.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.enums.invoice.supplier.InvoiceApplySupplierInvoiceProgressingStatusEnum;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnBeanUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplier;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplierExample;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplier;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplierXGoods;
import cn.superdesk.uniorder.dao.entity.invoice.supplier.InvoiceApplySupplierXGoodsExample;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.supplier.AccountingUnifiedSupplierMapper;
import cn.superdesk.uniorder.dao.mapper.invoice.supplier.InvoiceApplySupplierMapper;
import cn.superdesk.uniorder.dao.mapper.invoice.supplier.InvoiceApplySupplierMapperEx;
import cn.superdesk.uniorder.dao.mapper.invoice.supplier.InvoiceApplySupplierXGoodsMapper;
import cn.superdesk.uniorder.dao.mapper.invoice.supplier.InvoiceApplySupplierXGoodsMapperEx;
import cn.superdesk.uniorder.dto.param.invoice.supplier.InvoiceApplySupplierOpDetailInnerGoodsListQueryCriteria;
import cn.superdesk.uniorder.dto.param.invoice.supplier.InvoiceApplySupplierXGoodsQueryCriteria;
import cn.superdesk.uniorder.dto.vo.invoice.supplier.InvoiceApplySupplierDetailDimGoodsItemVo;
import cn.superdesk.uniorder.dto.vo.invoice.supplier.InvoiceApplySupplierXUnifiedOrderGoodsEdVo;
import cn.superdesk.uniorder.service.invoice.supplier.InvoiceApplySupplierXGoodsService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 供应商 开票申请 X 订单 X 商品
 * @Author: linjinyu
 * @CreateDate: 2020/11/4 下午2:39
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/11/4 下午2:39
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class InvoiceApplySupplierXGoodsServiceImpl implements InvoiceApplySupplierXGoodsService {

	@Autowired
	private InvoiceApplySupplierMapper   invoiceApplySupplierMapper;
	@Autowired
	private InvoiceApplySupplierMapperEx invoiceApplySupplierMapperEx;

	@Autowired
	private InvoiceApplySupplierXGoodsMapper   invoiceApplySupplierXGoodsMapper;
	@Autowired
	private InvoiceApplySupplierXGoodsMapperEx invoiceApplySupplierXGoodsMapperEx;

	@Autowired
	private AccountingUnifiedSupplierMapper accountingUnifiedSupplierMapper;


	/****************************************** extends BaseService 部分 start ******************************************/
	@Override
	public void addObj(InvoiceApplySupplierXGoods entity) {
		invoiceApplySupplierXGoodsMapper.insert(entity);
	}


	@Override
	public void updateObj(InvoiceApplySupplierXGoods entity) {
		invoiceApplySupplierXGoodsMapper.updateByPrimaryKeySelective(entity);
	}


	@Override
	public void deleteObj(Long id) {

		invoiceApplySupplierXGoodsMapper.deleteByPrimaryKey(id);
	}

	@Override
	public InvoiceApplySupplierXGoods findById(Long id) {
		return invoiceApplySupplierXGoodsMapper.selectByPrimaryKey(id);
	}


	@Override
	public PageInfo<InvoiceApplySupplierXGoods> findByPaging(Map<String, Object> conditions, Integer pageNun, Integer pageSize) {
		return null;
	}

	@Override
	public List<InvoiceApplySupplierXGoods> findAll(Map<String, Object> queryMap) {
		return null;
	}

	/****************************************** extends BaseService 部分   end ******************************************/


	public void addInvoiceApplySupplierXGoods(InvoiceApplySupplierXGoods entity) {
		invoiceApplySupplierXGoodsMapper.insertSelective(entity);
	}

	public void updateInvoiceApplySupplierXGoods(InvoiceApplySupplierXGoods entity) {
		InvoiceApplySupplierXGoods originEntity = invoiceApplySupplierXGoodsMapper.selectByPrimaryKey(entity.getId());
//		AssertUtil.notNull(originEntity);
		AnBeanUtils.copy(entity, originEntity);
		invoiceApplySupplierXGoodsMapper.updateByPrimaryKey(originEntity);
	}

	public void deleteInvoiceApplySupplierXGoods(Long id) {
		invoiceApplySupplierXGoodsMapper.deleteByPrimaryKey(id);
	}

	public InvoiceApplySupplierXGoods findInvoiceApplySupplierXGoodsById(Long id) {
		InvoiceApplySupplierXGoods entity = invoiceApplySupplierXGoodsMapper.selectByPrimaryKey(id);
//		AssertUtil.notNull(entity);
		return entity;
	}

	public R<List<InvoiceApplySupplierXGoods>> pageQuery(Map<String, Object> conditions, int pageNun, int pageSize) {

		InvoiceApplySupplierXGoodsExample          example  = new InvoiceApplySupplierXGoodsExample();
		InvoiceApplySupplierXGoodsExample.Criteria criteria = example.createCriteria();

		// TODO 喜欢用Map 还是 Bean 自己喜欢... 后期添加 转 InvoiceApplySupplierXGoodsExample.Criteria
		// InvoiceApplySupplierXGoods invoiceApplySupplierXGoodsConditions = BeanUtils.mapToBean(conditions,InvoiceApplySupplierXGoods.class);

		PageHelper.startPage(pageNun, pageSize);
		List<InvoiceApplySupplierXGoods>     resultList = invoiceApplySupplierXGoodsMapper.selectByExample(example);
		PageInfo<InvoiceApplySupplierXGoods> page       = new PageInfo<InvoiceApplySupplierXGoods>(resultList);
		PageHelper.clearPage();

		return new R<List<InvoiceApplySupplierXGoods>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

	}

	public R<List<InvoiceApplySupplierXGoods>> pageQueryGenericParam(InvoiceApplySupplierXGoodsQueryCriteria queryCriteria) {

		InvoiceApplySupplierXGoodsExample          example  = new InvoiceApplySupplierXGoodsExample();
		InvoiceApplySupplierXGoodsExample.Criteria criteria = example.createCriteria();

		// TODO 添加条件... 后期添加 queryCriteria 转 InvoiceApplySupplierXGoodsExample.Criteria

		PageHelper.startPage(queryCriteria.getPageNumber(), queryCriteria.getPageSize());
		List<InvoiceApplySupplierXGoods>     resultList = invoiceApplySupplierXGoodsMapper.selectByExample(example);
		PageInfo<InvoiceApplySupplierXGoods> page       = new PageInfo<InvoiceApplySupplierXGoods>(resultList);
		PageHelper.clearPage();

		return new R<List<InvoiceApplySupplierXGoods>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

	}


	/****************************************** 重构前存在 start ******************************************/


	@Override
	public List<InvoiceApplySupplierDetailDimGoodsItemVo> getInvoiceApplySupplierDetailInnerGoodsList(
			InvoiceApplySupplierOpDetailInnerGoodsListQueryCriteria queryCriteria) {

		return invoiceApplySupplierXGoodsMapperEx.getInvoiceApplySupplierDetailInnerGoodsList(queryCriteria);
	}

	/****************************************** 工具方法 start ******************************************/

	/**
	 * 用于 开票申请 排除已开票的商品
	 * * 装的是 基于 某对账单Sn 查出这个对账单 商品 已申请开票
	 *
	 * @param accountingOrderSn
	 * @return
	 */
	@Override
	public List<InvoiceApplySupplierXUnifiedOrderGoodsEdVo> getInvoiceApplyXUnifiedOrderGoodsEd(String accountingOrderSn) {
		return invoiceApplySupplierXGoodsMapperEx.getInvoiceApplyXUnifiedOrderGoodsEd(accountingOrderSn);
	}

	/**
	 * 根据 开票申请Id 获取 关联 积分流水 ids 集合
	 *
	 * @param invoiceApplyId
	 * @return
	 */
	@Override
	public List<Long> findGoodsSetByInvoicApplyId(Long invoiceApplyId) {

		List<Long> result = new ArrayList<>();

		InvoiceApplySupplier invoiceApplySupplier = invoiceApplySupplierMapper.selectByPrimaryKey(invoiceApplyId);

		if (null != invoiceApplySupplier) {
			result = findGoodsSetByInvoicApplySn(invoiceApplySupplier.getInvoiceApplySn());
		}

		return result;

	}

	@Override
	public List<Long> findGoodsSetByInvoicApplySn(String invoiceApplySn) {

		List<Long> result = new ArrayList<>();

		InvoiceApplySupplierXGoodsExample example = new InvoiceApplySupplierXGoodsExample();
		example.createCriteria()
				.andInvoiceApplySnEqualTo(invoiceApplySn);

		List<InvoiceApplySupplierXGoods> invoiceApplyXGoodsList = invoiceApplySupplierXGoodsMapper.selectByExample(example);

		if (CollUtil.isNotEmpty(invoiceApplyXGoodsList)) {
			result = invoiceApplyXGoodsList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getGoodsId())).map(o -> o.getGoodsId()).collect(Collectors.toList());
		}

		return result;
	}

	/**
	 * 根据开票申请Id 获取 关联 对账单 ids 集合
	 * <p>
	 * 由于 这个 开票申请 X 对账单 X 订单 X 商品 表是没有记录 invoiceApplyId and accountingOrderid
	 * <p>
	 * 所以不实际
	 *
	 * @param invoiceApplyIds
	 * @return
	 */
	@Override
	public List<Long> getAffectedAccountingOrderIdsByInvoiceApplyIds(List<Long> invoiceApplyIds) {

		List<Long> affectedAccountingOrderIds = new ArrayList<>();

		InvoiceApplySupplierXGoodsExample example = new InvoiceApplySupplierXGoodsExample();
		example.createCriteria()
				.andInvoiceApplyIdIn(invoiceApplyIds);

		List<InvoiceApplySupplierXGoods> invoiceApplyXGoodsList = invoiceApplySupplierXGoodsMapper.selectByExample(example);

		if (CollUtil.isNotEmpty(invoiceApplyXGoodsList)) {
			affectedAccountingOrderIds = invoiceApplyXGoodsList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderId())).map(o -> o.getAccountingOrderId()).collect(Collectors.toList());
		}

		log.info("根据开票申请Id 获取 关联 对账单 ids 集合 \ninvoiceApplyIds {}\naffectedAccountingOrderIds {}", JSONUtil.toJsonStr(invoiceApplyIds), JSONUtil.toJsonStr(affectedAccountingOrderIds));

		return affectedAccountingOrderIds;

	}

	@Override
	public List<String> getAffectedAccountingOrderSnsByInvoiceApplySn(String invoiceApplySn) {

		List<String> result = new ArrayList<>();

		InvoiceApplySupplierXGoodsExample example = new InvoiceApplySupplierXGoodsExample();
		example.createCriteria()
				.andInvoiceApplySnEqualTo(invoiceApplySn);

		List<InvoiceApplySupplierXGoods> invoiceApplyXGoodsList = invoiceApplySupplierXGoodsMapper.selectByExample(example);

		if (CollUtil.isNotEmpty(invoiceApplyXGoodsList)) {
			result = invoiceApplyXGoodsList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderSn())).map(o -> o.getAccountingOrderSn()).collect(Collectors.toList());
		}

		return result;
	}

	@Override
	public List<String> getAffectedAccountingOrderSnsByInvoiceApplySns(List<String> invoiceApplySns) {

		List<String> result = new ArrayList<>();

		InvoiceApplySupplierXGoodsExample example = new InvoiceApplySupplierXGoodsExample();
		example.createCriteria()
				.andInvoiceApplySnIn(invoiceApplySns);

		List<InvoiceApplySupplierXGoods> invoiceApplyXGoodsList = invoiceApplySupplierXGoodsMapper.selectByExample(example);

		if (CollUtil.isNotEmpty(invoiceApplyXGoodsList)) {
			result = invoiceApplyXGoodsList.stream().filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderSn())).map(o -> o.getAccountingOrderSn()).collect(Collectors.toList());
		}

		return result;
	}


	/****************************************** 工具方法   end ******************************************/

	/****************************************** 基于对账单Id 检测 开票状态 start ******************************************/
	/**
	 * 是否全部开票的问题 0 未开票 1 全部开票 2 部分开票
	 *
	 * @param accountingOrderId
	 * @return
	 */
	@Override
	public Integer checkInvoiceApplyStatusByAccountingOrderIdFocusSupplier(Long accountingOrderId) {

		// 对账单表   基于对账单Id 来查出 关联的 商品
		// 开票申请表  基于对账单Id 来查出 关联的 商品
		return 0;
	}

	/**
	 * 是否全部开票的问题 0-未开票;1-全部开票;2-部分开票;
	 *
	 * @param accountingOrderSn
	 * @return
	 */
	@Override
	public Integer checkInvoiceApplyStatusByAccountingOrderSnFocusSupplier(String accountingOrderSn) {

		Integer invoiceStatus = invoiceApplySupplierXGoodsMapperEx.checkInvoiceApplyStatusByAccountingOrderSn(accountingOrderSn);

		return invoiceStatus;
	}

	/****************************************** 基于对账单Id 检测 开票状态   end ******************************************/

	/****************************************** 基于对账单Sn检测 开票状态 并 更新 对账单 开票申请状态 start ******************************************/
	@Override
	public void checkInvoiceApplyStatusByAccountingOrderIdAndUpdateAccountingEntityFocusSupplier(Long accountingOrderId) {

	}

	@Override
	public void checkInvoiceApplyStatusByAccountingOrderSnAndUpdateAccountingEntityFocusSupplier(String accountingOrderSn) {

		// 用于查找是 全部开票 还是 部分开票的问题
		Integer invoiceApplyStatus = checkInvoiceApplyStatusByAccountingOrderSnFocusSupplier(accountingOrderSn);

		// 对账单 结算单
		AccountingUnifiedSupplierExample example4Update = new AccountingUnifiedSupplierExample();
		example4Update.createCriteria()
				.andAccountingOrderSnEqualTo(accountingOrderSn);

		AccountingUnifiedSupplier accountingUnifiedSupplier = new AccountingUnifiedSupplier();

		/****************************************** 开票申请 start ******************************************/

		accountingUnifiedSupplier.setInvoiceApplyStatus(invoiceApplyStatus);

		/****************************************** 开票申请进度 进展 start ******************************************/

		accountingUnifiedSupplier.setInvoiceStatus(InvoiceApplySupplierInvoiceProgressingStatusEnum.待开票.getKey());

		accountingUnifiedSupplierMapper.updateByExampleSelective(accountingUnifiedSupplier, example4Update);
	}

    @Override
    public void deleteInvoiceApplySupplierXGoodsBatchByAccountingOrderSn(String accountingOrderSn) {
		InvoiceApplySupplierXGoodsExample example = new InvoiceApplySupplierXGoodsExample();
		example.createCriteria().andAccountingOrderSnEqualTo(accountingOrderSn);
		invoiceApplySupplierXGoodsMapper.deleteByExample(example);
	}

    /****************************************** 基于对账单Sn检测 开票状态 并 更新 对账单 开票申请状态   end ******************************************/

}
