package com.dayou.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.dayou.common.BaseEntity;
import com.dayou.dto.ItemAddFinanceInvoiceDTO;
import com.dayou.dto.MajorProductionSimpleDTO;
import com.dayou.entity.FinanceInvoice;
import com.dayou.entity.Item;
import com.dayou.entity.MajorProduction;
import com.dayou.entity.OrderFund;
import com.dayou.enums.FinanceInvoiceState;
import com.dayou.enums.ReportStatus;
import com.dayou.exception.ErrorCode;
import com.dayou.mapper.FinanceInvoiceMapper;
import com.dayou.mapper.MajorProductionMapper;
import com.dayou.service.IFinanceInvoiceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.service.IItemService;
import com.dayou.service.IOrderFundService;
import com.dayou.utils.LoginContext;
import com.dayou.vo.FinanceInvoiceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dayou.utils.ExcelUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

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

import org.springframework.transaction.annotation.Transactional;
import com.dayou.enums.BatchTaskTypeEnum;

import static com.dayou.enums.MainBusinessEnum.ITEM_BUSINESS;

/**
 * <p>
 * 财务开票 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2023-12-08
 */
@DS("mbs")
@Service
public class FinanceInvoiceServiceImpl extends ServiceImpl<FinanceInvoiceMapper, FinanceInvoice> implements IFinanceInvoiceService {

    @Autowired
    private FinanceInvoiceMapper financeInvoiceMapper;

    @Autowired
    private MajorProductionMapper majorProductionMapper;

    @Autowired
    private IItemService iItemService;

    @Autowired
    private IOrderFundService orderFundService;

    @Override
    @SuppressWarnings("unchecked")
    public Page<FinanceInvoiceVo> selectPage(Page page,FinanceInvoice financeInvoice,String keyword){
        Page<FinanceInvoiceVo> ret = financeInvoiceMapper.getPage(page,financeInvoice,keyword);
        return ret;
    }

    /**
     * 开票信息导出
     * @param financeInvoice 查询条件
     * @param keyword 关键
     * @return List<FinanceInvoiceVo>
     */
    @Override
    public List<FinanceInvoiceVo> exportPage(FinanceInvoice financeInvoice, String keyword) {
        return financeInvoiceMapper.exportPage(financeInvoice, keyword);
    }


    @Override
    public FinanceInvoice detail(Long id){
        return this.getById(id);
    }

    @Override
    public Boolean add(FinanceInvoice financeInvoice){
        financeInvoice.setApplyId(LoginContext.getCurrentUserId());
        return  this.save(financeInvoice);
    }

    /**
     * 新增土规项目开票申请
     * @param dto 开票信息
     * @return orderFundId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long itemAdd(ItemAddFinanceInvoiceDTO dto) {
        //检查是否有订单收款记录
        Item item = iItemService.getById(dto.getItemId());

        // orderFundId为null的话就新增一条
        if (ObjectUtil.isNull(dto.getOrderFundId())) {
            //创建订单收款记录
            OrderFund orderFund = new OrderFund();
            orderFund.setShouldAmount(item.getAmount());
            orderFund.setOrderName(item.getName());
            orderFund.setOrderId(item.getBusinessNo());
            orderFund.setBusinessId(item.getId());
            orderFund.setBusinessType(ITEM_BUSINESS.name());
            orderFundService.add(orderFund);
            dto.setOrderFundId(orderFund.getId());
        }

        // 新增开票记录
        FinanceInvoice financeInvoice = BeanUtil.toBean(dto, FinanceInvoice.class);
        financeInvoice.setOrderFundId(dto.getOrderFundId());
        add(financeInvoice);
        return dto.getOrderFundId();
    }

    @Override
    public Boolean update(FinanceInvoice financeInvoice){
//        financeInvoice.setCheckerId(LoginContext.getCurrentUserId());
//        financeInvoice.setMakerId(LoginContext.getCurrentUserId());
//        financeInvoice.setState(FinanceInvoiceState.已开票.name());
        return this.updateById(financeInvoice);
    }

    @Override
    public Boolean invoiceCheck(FinanceInvoice financeInvoice) {
        financeInvoice.setCheckerId(LoginContext.getCurrentUserId());
        financeInvoice.setMakerId(LoginContext.getCurrentUserId());
//        financeInvoice.setState(FinanceInvoiceState.已开票.name());
        return this.updateById(financeInvoice);
    }

    @Override
    public Boolean delete(Long id){
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public List<FinanceInvoice> getList(Long id, Long productionFundId) {
        List<FinanceInvoice> list = this.list(new LambdaQueryWrapper<FinanceInvoice>()
                .eq(FinanceInvoice::getOrderFundId, id)
                .eq(productionFundId!=null,FinanceInvoice::getProductionFundId, productionFundId)
                .orderByDesc(BaseEntity::getCreated));
        return list;
    }

    @Override
    public Boolean cancellation(FinanceInvoice financeInvoice) {
        Long id = financeInvoice.getId();
        FinanceInvoice invoice = this.getById(id);
        if (!invoice.getState().equals(FinanceInvoiceState.已开票.name())){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"此发票还未开具，无法申请作废。");
        }
        return this.update(new LambdaUpdateWrapper<FinanceInvoice>().set(FinanceInvoice::getState, FinanceInvoiceState.申请作废)
                        .set(FinanceInvoice::getReason,financeInvoice.getReason())
                .eq(BaseEntity::getId,id));
    }

    @Override
    public List<FinanceInvoiceVo> getInvoiceAmountInfo(MajorProductionSimpleDTO simpleDTO) {
        if (CollectionUtil.isEmpty(simpleDTO.getProductionNos())){
            List<String> productionNos = majorProductionMapper.getProductionNosByMajorId(simpleDTO.getMajorId());
            if (CollectionUtil.isEmpty(productionNos)){
                return financeInvoiceMapper.getInvoiceAmountInfoEmptyProduction(simpleDTO);
            }
            simpleDTO.setProductionNos(productionNos);
        }
        return financeInvoiceMapper.getInvoiceAmountInfo(simpleDTO);
    }

    @Override
    public Boolean cancelling(Long id) {
        FinanceInvoice invoice = this.getById(id);
        if (!invoice.getState().equals(FinanceInvoiceState.申请作废.name())){
            ErrorCode.throwBusinessException(ErrorCode.CUSTOM_ERROR,"发票状态错误，无法作废。");
        }

        return this.update(new LambdaUpdateWrapper<FinanceInvoice>().set(FinanceInvoice::getState, FinanceInvoiceState.已作废).eq(BaseEntity::getId,id));

    }
}
