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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderInvoiceApplyStatusEnum;
import cn.superdesk.uniorder.common.enums.accounting.AccountingOrderTypeDimEnum;
import cn.superdesk.uniorder.common.enums.common.CommonBeRelatedEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditBackAccountStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceApplyStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderCreditInvoiceMakeStatusEnum;
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.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.dao.entity.accounting.score.customer.AccountingScoreCustomer;
import cn.superdesk.uniorder.dao.entity.accounting.unified.customer.AccountingUnifiedCustomer;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApplyXGoods;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApplyXGoodsExample;
import cn.superdesk.uniorder.dao.mapper.accounting.score.customer.AccountingScoreCustomerMapper;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.customer.AccountingUnifiedCustomerMapper;
import cn.superdesk.uniorder.dao.mapper.accounting.unified.customer.AccountingUnifiedCustomerMapperEx;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyMapperExScore;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyMapperExUnified;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyXGoodsMapper;
import cn.superdesk.uniorder.dao.mapper.invoice.customer.InvoiceApplyXGoodsMapperEx;
import cn.superdesk.uniorder.service.order.base.UnifiedOrderCreditService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyXGoodsService;
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.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * @Description: 发票申请 关联 相关 先这样放
 * @Author: linjinyu
 * @Author: linjinyu
 * @CreateDate: 7/29/20 5:38 PM
 * @UpdateUser: linjinyu
 * @UpdateDate: 7/29/20 5:38 PM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class InvoiceApplyXGoodsServiceImpl implements InvoiceApplyXGoodsService {

    @Autowired
    private InvoiceApplyXGoodsMapper   invoiceApplyXGoodsMapper;
    @Autowired
    private InvoiceApplyXGoodsMapperEx invoiceApplyXGoodsMapperEx;

    @Autowired
    private InvoiceApplyMapperExScore   invoiceApplyMapperExScore;
    @Autowired
    private InvoiceApplyMapperExUnified invoiceApplyMapperExUnified;

    @Autowired
    private AccountingScoreCustomerMapper accountingScoreCustomerMapper;

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

    @Autowired
    private UnifiedOrderCreditService unifiedOrderCreditService;

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

    @Override
    public void updateObj(InvoiceApplyXGoods entity) {
        invoiceApplyXGoodsMapper.updateByPrimaryKeySelective(entity);
    }

    @Override
    public void deleteObj(Long id) {
    }

    @Override
    public InvoiceApplyXGoods findById(Long id) {
        return invoiceApplyXGoodsMapper.selectByPrimaryKey(id);
    }

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

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

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


    public void addInvoiceApplyXGoods(InvoiceApplyXGoods entity) {
        invoiceApplyXGoodsMapper.insertSelective(entity);
    }

    public int insertBatch(List<InvoiceApplyXGoods> processList) {
        return invoiceApplyXGoodsMapperEx.insertBatch(processList);
    }

    public void updateInvoiceApplyXGoods(InvoiceApplyXGoods entity) {
        InvoiceApplyXGoods originEntity = invoiceApplyXGoodsMapper.selectByPrimaryKey(entity.getId());
//		AssertUtil.notNull(originEntity);
        AnBeanUtils.copy(entity, originEntity);
        invoiceApplyXGoodsMapper.updateByPrimaryKey(originEntity);
    }

    public void deleteInvoiceApplyXGoods(Long id) {
        invoiceApplyXGoodsMapper.deleteByPrimaryKey(id);
    }

    public int dumpXByInvoiceApplyId(Long invoiceApplyId) {

        int ret = 0;

        // op撤销开票
        // op重新开票
        // ...
        // 这些都 复位吧
        List<Long> processUnifiedOrderCreditIds = findCreditSetByInvoicApplyId(invoiceApplyId);
        unifiedOrderCreditService.updateFieldInvoiceApplyStatusByUnifiedOrderCreditIds(processUnifiedOrderCreditIds, UnifiedOrderCreditInvoiceApplyStatusEnum.待申请);
        unifiedOrderCreditService.updateFieldInvoiceMakeStatusByUnifiedOrderCreditIds(processUnifiedOrderCreditIds, UnifiedOrderCreditInvoiceMakeStatusEnum.待开票);
        unifiedOrderCreditService.updateFieldBackAccountStatusByUnifiedOrderCreditIds(processUnifiedOrderCreditIds, UnifiedOrderCreditBackAccountStatusEnum.未回款);

        // 对账单相关信息没有在 invoiceApply, 要用 invoiceApplyId 去查 invoiceApplyXGoods
        InvoiceApplyXGoodsExample invoiceOrderExample = new InvoiceApplyXGoodsExample();
        invoiceOrderExample.createCriteria()
                .andInvoiceApplyIdEqualTo(invoiceApplyId);

        ret = invoiceApplyXGoodsMapper.deleteByExample(invoiceOrderExample);

        return ret;
    }

    public InvoiceApplyXGoods findInvoiceApplyXGoodsById(Long id) {
        InvoiceApplyXGoods entity = invoiceApplyXGoodsMapper.selectByPrimaryKey(id);
//		AssertUtil.notNull(entity);
        return entity;
    }

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

        // 样例 保留
//		InvoiceApplyXGoods invoiceApplyXGoodsConditions = BeanUtils.mapToBean(conditions,InvoiceApplyXGoods.class);

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

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

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

    }

    /****************************************** 原来就有 start ******************************************/

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

        List<Long> result = null;

        InvoiceApplyXGoodsExample example = new InvoiceApplyXGoodsExample();
        example.createCriteria()
                .andInvoiceApplyIdEqualTo(invoiceApplyId);

        List<InvoiceApplyXGoods> resultEntityList = invoiceApplyXGoodsMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultEntityList)) {
            result = resultEntityList.stream().map(e -> e.getUnifiedOrderCreditId()).collect(Collectors.toList());
        }

        return result;

    }

    public List<Long> findInvoiceApplySetByAccountingOrderId(Long accountingOrderId, AccountingOrderTypeDimEnum accountingOrderTypeDimEnum) {

        List<Long> result = null;

        InvoiceApplyXGoodsExample example = new InvoiceApplyXGoodsExample();
        example.createCriteria()
                .andAccountingOrderTypeEqualTo(accountingOrderTypeDimEnum.getKey())
                .andAccountingOrderIdEqualTo(accountingOrderId);

        List<InvoiceApplyXGoods> resultEntityList = invoiceApplyXGoodsMapper.selectByExample(example);

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

        return result;

    }

    /**
     * 根据发票申请Id 获取 关联 对账单 ids 集合
     *
     * @param invoiceApplyId
     * @return
     */
    public List<Long> getAffectedAccountingOrderIdsByInvoiceApplyId(Long invoiceApplyId) {

        List<Long> affectedAccountingOrderIds = null;

        InvoiceApplyXGoodsExample example = new InvoiceApplyXGoodsExample();
        example.createCriteria()
                .andInvoiceApplyIdEqualTo(invoiceApplyId);
        List<InvoiceApplyXGoods> invoiceOrderList = invoiceApplyXGoodsMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(invoiceOrderList)) {
            // 得出受影响的对账单 ids
            affectedAccountingOrderIds = invoiceOrderList
                    .stream()
                    .filter(AnLamdaUtils.distinctByKey(o -> o.getAccountingOrderId()))
                    .map(o -> o.getAccountingOrderId())
                    .collect(Collectors.toList());
        }

        return affectedAccountingOrderIds;

    }


    public Integer checkInvoiceStatusByAccountingOrderIdFocusUnified(Long accountingOrderId) {

        Integer invoiceStatus = invoiceApplyMapperExUnified.checkInvoiceStatusByAccountingOrderId(accountingOrderId);

        return invoiceStatus;
    }

    public Integer checkInvoiceStatusByAccountingOrderIdFocusScore(Long accountingOrderId) {

        // TODO
        Integer invoiceStatus = invoiceApplyMapperExScore.checkInvoiceStatusByAccountingOrderId(accountingOrderId);

//        0 未开票
//        1 全部开票
//        2 部分开票

        return invoiceStatus;
    }

    /**
     * 用于查找是 对账单 发票申请状态 全部开票 还是 部分开票的问题 更新对账单 发票申请状
     *
     * @param accountingOrderId
     * @param loginSysUser
     */
    public void checkInvoiceStatusByAccountingOrderIdAndUpdateAccountingEntityFocusUnified(Long accountingOrderId, LoginSysUser loginSysUser) {

        // 用于查找是 全部开票 还是 部分开票的问题
        Integer invoiceStatus = checkInvoiceStatusByAccountingOrderIdFocusUnified(accountingOrderId);

        // 现在 这个是 一般订单的 对账单 结算单
        AccountingUnifiedCustomer accountingUnifiedCustomer = new AccountingUnifiedCustomer();

        accountingUnifiedCustomer.setId(accountingOrderId);
        accountingUnifiedCustomer.setInvoiceStatus(invoiceStatus);

        accountingUnifiedCustomer.setUpdateTime(DateUtil.date());
        accountingUnifiedCustomer.setUpdateUserId(loginSysUser.getSysUserId());

        accountingUnifiedCustomerMapper.updateByPrimaryKeySelective(accountingUnifiedCustomer);

    }

    /**
     * 用于查找是 对账单 发票申请状态 全部开票 还是 部分开票的问题 更新对账单 发票申请状
     *
     * @param accountingOrderId
     * @param beRelatedEnum
     * @param loginSysUser
     */
    public void checkInvoiceStatusByAccountingOrderIdAndUpdateAccountingEntityFocusScore(Long accountingOrderId, CommonBeRelatedEnum beRelatedEnum, LoginSysUser loginSysUser) {

        // 用于查找是 对账单 发票申请状态 全部开票 还是 部分开票的问题
        Integer invoiceStatus = checkInvoiceStatusByAccountingOrderIdFocusScore(accountingOrderId);

//        0 未开票
//        1 全部开票
//        2 部分开票

//        0-未开票;1-已开票;2-部分开票;

        log.info("检查与更新对账单的申请状态 结果:{} -> {} {}",
                AccountingOrderInvoiceApplyStatusEnum.get(invoiceStatus).getDesc(),
                accountingOrderId,
                JSONUtil.toJsonStr(loginSysUser));

        AccountingScoreCustomer accountingScoreCustomer = new AccountingScoreCustomer();

        accountingScoreCustomer.setId(accountingOrderId);
        accountingScoreCustomer.setInvoiceStatus(invoiceStatus);

        if (beRelatedEnum == CommonBeRelatedEnum.级联) {
            accountingScoreCustomer.setUpdateTime(DateUtil.date());
            accountingScoreCustomer.setUpdateUserId(loginSysUser.getSysUserId());
        }

        accountingScoreCustomerMapper.updateByPrimaryKeySelective(accountingScoreCustomer);

    }

    @Override
    public void deleteInvoiceApplyXGoodsByAccountingOrderId(Long id) {
        InvoiceApplyXGoodsExample invoiceApplyXGoodsExample = new InvoiceApplyXGoodsExample();
        invoiceApplyXGoodsExample.createCriteria().andAccountingOrderIdEqualTo(id);
        invoiceApplyXGoodsMapper.deleteByExample(invoiceApplyXGoodsExample);
    }
}
