package com.yonge.cooleshow.biz.dal.execl.analysis;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.Sheet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.microsvc.toolkit.middleware.excel.analysis.AnalysisContext;
import com.microsvc.toolkit.middleware.excel.analysis.DataAnalysis;
import com.microsvc.toolkit.middleware.excel.util.DownloadManager;
import com.yonge.cooleshow.biz.dal.entity.TenantAccountRecord;
import com.yonge.cooleshow.biz.dal.execl.entity.TenantAccountRecordImport;
import com.yonge.cooleshow.biz.dal.execl.listener.TenantAccountRecordImportListener;
import com.yonge.cooleshow.biz.dal.service.EasyExcelService;
import com.yonge.cooleshow.common.enums.PostStatusEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;


@Slf4j
@Getter
@Setter
public class TenantAccountRecordImportAnalysis extends DataAnalysis<TenantAccountRecordImportAnalysis> {


    private List<TenantAccountRecordImport> tenantAccountRecordImports;

    // Excel解析服务
    private EasyExcelService easyExcelService;

    private final Map<String, TenantAccountRecord> recordMap = Maps.newHashMap();
    public TenantAccountRecordImportAnalysis(AnalysisContext context) {
        super(context);
    }

    public static TenantAccountRecordImportAnalysis build(EasyExcelService easyExcelService) {
        TenantAccountRecordImportAnalysis analysis = new TenantAccountRecordImportAnalysis(AnalysisContext.builder().build());
        analysis.setEasyExcelService(easyExcelService);
        analysis.setTenantAccountRecordImports(Lists.newArrayList());
        return analysis;

    }


    /**
     * 读取文件数据到内存
     *
     * @param path 本地文件地址
     */
    @Override
    public void read(String path) {

        File file = new File(path);
        List<Sheet> sheets = EasyExcel.read(file).build().getSheets();
        if (CollectionUtils.isNotEmpty(sheets)) {

            sheets.forEach(item -> {
                // 读取数据
                EasyExcel.read(file, TenantAccountRecordImport.class, new TenantAccountRecordImportListener(getTenantAccountRecordImports(), item.getSheetName()))
                        .extraRead(CellExtraTypeEnum.MERGE).sheet(item.getSheetName()).doRead();
            });

        }

        // 删除本地缓存文件
        DownloadManager.getInstance().deleteOnExit(path);
    }

    /**
     * 校验数据合法
     *
     * @return Map<Integer, String>
     */
    @Override
    public Map<Integer, String> verify() {

        // 加载校验数据参数
        if (Objects.nonNull(getTenantAccountRecordImports())) {
            loadVerifyParamData();
        }

        Map<Integer, String> verifyDataMap = Maps.newLinkedHashMap();

        TenantAccountRecord tenantAccountRecord;
        // 校验每条入库记录数据合法性
        String ret = "";
        for (TenantAccountRecordImport item : getTenantAccountRecordImports()) {

            // 课件信息校验
            tenantAccountRecord = recordMap.get(item.getId());
            if (Objects.isNull(tenantAccountRecord)) {
                ret += "流水记录编号无效:" + (StringUtils.isBlank(item.getId())?"不能为空":item.getId());
                if (StringUtils.isNotEmpty(ret)) {
                    verifyDataMap.put(item.getRowIndex(), ret);
                    ret = ""; // 重置数据状态
                }
                continue;
            }

            // 检测机构编号，金额，订单号，结算状态
            if (StringUtils.isBlank(item.getTenantId()) || !tenantAccountRecord.getTenantId().toString().equals(item.getTenantId())) {
                ret += "机构编号无效:" + (StringUtils.isBlank(item.getTenantId())?"不能为空":item.getTenantId());
            }

            if (StringUtils.isBlank(item.getTransAmount()) || tenantAccountRecord.getTransAmount().compareTo(new BigDecimal(item.getTransAmount())) != 0) {
                ret += "交易金额错误:" + (StringUtils.isBlank(item.getTransAmount())?"不能为空":item.getTransAmount());
            }
            if (StringUtils.isBlank(item.getOrderNo()) || !tenantAccountRecord.getOrderNo().equals(item.getOrderNo())) {
                ret += "订单号无效:" + (StringUtils.isBlank(item.getOrderNo())?"不能为空":item.getOrderNo());
            }
            if (StringUtils.isBlank(item.getSettlement()) || !Lists.newArrayList("是","否").contains(item.getSettlement())) {
                ret += "是否完成结算无效:" + (StringUtils.isBlank(item.getSettlement())?"不能为空":item.getSettlement());
            }
            if (StringUtils.isNotEmpty(ret)) {
                verifyDataMap.put(item.getRowIndex(), ret);
                ret = ""; // 重置数据状态
            }
        }

        // 数据校验记录信息
        getContext().total(getTenantAccountRecordImports().size()).failure(verifyDataMap.size())
                .setSuccess(getContext().getTotal() - getContext().getFailure());

        return verifyDataMap;
    }

    /**
     * 数据转换
     */
    @Override
    public void convert() {
        for (TenantAccountRecordImport tenantAccountRecordImport : getTenantAccountRecordImports()) {
            tenantAccountRecordImport.setPostStatus("是".equals(tenantAccountRecordImport.getSettlement())?
            PostStatusEnum.RECORDED:PostStatusEnum.FROZEN);
        }

    }

    /**
     * 加载校验数据参数
     */
    private void loadVerifyParamData() {
        List<TenantAccountRecordImport> importList = getTenantAccountRecordImports();

        // 记录ID集合
        List<String> ids = importList.stream().map(TenantAccountRecordImport::getId).collect(Collectors.toList());


        if (CollectionUtils.isNotEmpty(ids)) {
            // 记录集合
            {

                Map<String, TenantAccountRecord> collect = easyExcelService.getRecordById(ids).stream()
                        .collect(Collectors.toMap(x -> String.valueOf(x.getId()), Function.identity(), (o, n) -> n));
                if (MapUtils.isNotEmpty(collect)) {
                    recordMap.putAll(collect);
                }
            }
        }

    }


    /**
     * 数据对象
     * @return RoomInfoAnalysis
     */
    @Override
    public TenantAccountRecordImportAnalysis get() {
        return this;
    }

}
