package com.jianshui.invoice.service.impl;

import java.util.Arrays;
import java.util.List;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.jianshui.common.core.domain.AjaxResult;
import com.jianshui.common.utils.DateUtils;
import com.jianshui.common.utils.DictUtils;
import com.jianshui.common.utils.spring.SpringUtils;
import com.jianshui.invoice.consumer.InvoiceDeprecateCallbackConsumer;
import com.jianshui.invoice.domain.Invoice;
import com.jianshui.invoice.mapper.InvoiceMapper;
import com.jianshui.queue.consumer.RedisQueueConsumer;
import com.jianshui.queue.dto.RedisQueueMessage;
import com.jianshui.queue.utils.RedisQueueUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;

import com.jianshui.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.jianshui.invoice.domain.BillDetail;
import com.jianshui.invoice.mapper.BillInfoMapper;
import com.jianshui.invoice.domain.BillInfo;
import com.jianshui.invoice.service.IBillInfoService;

/**
 * 开票信息Service业务层处理
 *
 * @author Gong Quanlin
 * @date 2022-03-06
 */
@Service
@Slf4j
public class BillInfoServiceImpl implements IBillInfoService {
    @Autowired
    private BillInfoMapper billInfoMapper;

    @Autowired
    private InvoiceMapper invoiceMapper;

    /**
     * 查询开票信息
     *
     * @param id 开票信息主键
     * @return 开票信息
     */
    @Override
    public BillInfo selectBillInfoById(Long id) {
        return billInfoMapper.selectBillInfoById(id);
    }

    /**
     * 查询开票信息列表
     *
     * @param billInfo 开票信息
     * @return 开票信息
     */
    @Override
    public List<BillInfo> selectBillInfoList(BillInfo billInfo) {
        return billInfoMapper.selectBillInfoList(billInfo);
    }

    /**
     * 新增开票信息
     *
     * @param billInfo 开票信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertBillInfo(BillInfo billInfo) {
        billInfo.setCreateTime(DateUtils.getNowDate());
        int rows = billInfoMapper.insertBillInfo(billInfo);
        insertBillDetail(billInfo);
        return rows;
    }

    /**
     * 修改开票信息
     *
     * @param billInfo 开票信息
     * @return 结果
     */
    @Transactional
    @Override
    public int updateBillInfo(BillInfo billInfo) {
        billInfo.setUpdateTime(DateUtils.getNowDate());
        billInfoMapper.deleteBillDetailByBillInfoId(billInfo.getId());
        insertBillDetail(billInfo);
        return billInfoMapper.updateBillInfo(billInfo);
    }

    /**
     * 批量删除开票信息
     *
     * @param ids 需要删除的开票信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteBillInfoByIds(Long[] ids) {
        billInfoMapper.deleteBillDetailByBillInfoIds(ids);
        return billInfoMapper.deleteBillInfoByIds(ids);
    }

    /**
     * 删除开票信息信息
     *
     * @param id 开票信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteBillInfoById(Long id) {
        billInfoMapper.deleteBillDetailByBillInfoId(id);
        return billInfoMapper.deleteBillInfoById(id);
    }

    /**
     * 新增发票明细信息
     *
     * @param billInfo 开票信息对象
     */
    public void insertBillDetail(BillInfo billInfo) {
        List<BillDetail> billDetailList = billInfo.getBillDetailList();
        Long id = billInfo.getId();
        if (StringUtils.isNotNull(billDetailList)) {
            List<BillDetail> list = new ArrayList<BillDetail>();
            for (BillDetail billDetail : billDetailList) {
                billDetail.setBillInfoId(id);
                list.add(billDetail);
            }
            if (list.size() > 0) {
                billInfoMapper.batchBillDetail(list);
            }
        }
    }

    /**
     * 主动回调
     *
     * @param id billInfoId
     * @return
     */
    @Override
    public AjaxResult pushBillInfo(Long id) {
        BillInfo billInfo = billInfoMapper.selectBillInfoById(id);
        if (billInfo == null) {
            log.info("【BillInfo发票回调】id:{},开票信息不存在", id);
            return AjaxResult.error("订单信息不存在！");
        }

        Invoice invoice = invoiceMapper.selectInvoiceByBillInfoId(id);
        if (invoice == null) {
            log.info("【BillInfo发票回调】id:{},发票信息不存在", id);
            return AjaxResult.error("发票不存在，请检查开票或等待开票完成后进行操作");
        }

        Integer status = invoice.getState();
        if (CollectionUtil.contains(Arrays.asList(0, 20, 21, 31, 98), status)) {
            log.info("【BillInfo发票回调】订单：{}，发票状态：{}，不可推送", JSONObject.toJSONString(billInfo), status);
            String label = DictUtils.getDictLabel("invoice_status", status.toString());
            return AjaxResult.error("当前发票状态：" + label + " 不可回调");
        }

        String callbackUrl = billInfo.getCallbackUrl();
        if (StringUtils.isEmpty(callbackUrl)) {
            log.info("【BillInfo发票回调】订单：{}，回调地址为空，不可推送", JSONObject.toJSONString(billInfo));
            return AjaxResult.error("未配置回调地址");
        }

        log.info("【BillInfo发票回调】回调请求，id{},回调地址：{}", id, callbackUrl);
        return RedisQueueUtil.build().setData(invoice).onQueue("invoice_add_callback_consumer").retry(0).dispatch();
    }
}
