package com.ruoyi.system.service.impl.Conversion;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ruoyi.system.domain.ActReadHistoryModel;
import com.ruoyi.system.domain.ActReadHistoryRuleModel;
import com.ruoyi.system.domain.ActSuppliesImportCleaningAcc;
import com.ruoyi.system.mapper.ActReadDataMapper;
import com.ruoyi.system.service.impl.ActReadDataServiceImpl;
import com.ruoyi.system.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 2024/3/27
 */
@Service
public class LkSpecialMethod implements MineConversion {
    private final ActReadDataMapper actReadDataMapper;

    public LkSpecialMethod(ActReadDataMapper actReadDataMapper) {
        this.actReadDataMapper = actReadDataMapper;
    }

    @Override
    @Transactional
    public void conversion(ActReadHistoryModel actReadHistoryModel, Object obj) {
        String sskId = actReadHistoryModel.getSskId();
        String hdate = actReadHistoryModel.getHdate();
        String hId = actReadHistoryModel.gethId();
        String yyUuid = actReadHistoryModel.getYyUuid();
        List<ActSuppliesImportCleaningAcc> accList = new ArrayList<>();
        Gson gson = new Gson();
        JSONArray jsonArray1 = gson.fromJson(actReadHistoryModel.getHistoryRole(), JSONArray.class);
        ActReadHistoryRuleModel[] ruleJson = gson.fromJson(actReadHistoryModel.getRule(), ActReadHistoryRuleModel[].class);
        ActReadHistoryRuleModel rule = ruleJson[0];
        int headerRow;
        int dateColumn;
        int departmentColumn;
        int unit;
        int model;
        int nameColumn;
        int codeColumn;
        headerRow = rule.getHeaderRow() != null && !"".equals(rule.getHeaderRow()) ? Integer.parseInt(rule.getHeaderRow()) - 1 : -1;
        dateColumn = rule.getDateColumn() != null && !"".equals(rule.getDateColumn()) ? Integer.parseInt(rule.getDateColumn()) - 1 : -1;
        departmentColumn = rule.getDepartmentColumn() != null && !"".equals(rule.getDepartmentColumn()) ? Integer.parseInt(rule.getDepartmentColumn()) - 1 : -1;
        unit = rule.getUnit() != null && !"".equals(rule.getUnit()) ? Integer.parseInt(rule.getUnit()) - 1 : -1;
        model = rule.getModel() != null && !"".equals(rule.getModel()) ? Integer.parseInt(rule.getModel()) - 1 : -1;
        nameColumn = rule.getNameColumn() != null && !"".equals(rule.getNameColumn()) ? Integer.parseInt(rule.getNameColumn()) - 1 : -1;
        codeColumn = rule.getCodeColumn() != null && !"".equals(rule.getCodeColumn()) ? Integer.parseInt(rule.getCodeColumn()) - 1 : -1;
        JSONArray jsonArray = gson.fromJson(actReadHistoryModel.getData(), JSONArray.class);
        JSONArray cellData = jsonArray.getJSONObject(0).getJSONArray("celldata");
        List<Integer> cList = Arrays.asList(dateColumn, departmentColumn, unit, model, codeColumn, nameColumn);
        Optional<Integer> max = cList.parallelStream().max(Comparator.comparingInt(a -> a));
        String dateValue = null;
        String departmentValue = null;
        String unitValue = null;
        String modelValue = null;
        String codeColumnValue = null;
        String nameColumnValue = null;
        for (int i = 0; i < cellData.size(); i++) {
            JSONObject object = cellData.getJSONObject(i);
            int c = object.getInteger("c");
            if (cList.contains(c)) {
                int row = object.getInteger("r");
                if (row < headerRow && headerRow != -1) {
                    continue;
                }
                if (row >= headerRow && object.getJSONObject("v") != null
                        && object.getJSONObject("v").getString("v") != null) {
                    String string = object.getJSONObject("v").getString("v");
                    if (c == dateColumn) {
                        dateValue = string;
                    } else if (c == departmentColumn) {
                        departmentValue = string;
                    } else if (c == unit) {
                        unitValue = string;
                    } else if (c == model) {
                        modelValue = string;
                    } else if (c == codeColumn) {
                        codeColumnValue = string;
                    } else if (c == nameColumn) {
                        nameColumnValue = string;
                    }
                }
                if (max.isPresent() && max.get() == c) {
                    List<JSONObject> first = IntStream.range(0, jsonArray1.size())
                            .mapToObj(jsonArray1::getJSONObject)
                            .filter(v -> row == v.getInteger("key"))
                            .collect(Collectors.toList());
                    Map<String, String> map = new HashMap<>();
                    LinkedHashSet<String> set = new LinkedHashSet<>();
                    if (first.size() != 0) {
                        for (JSONObject jsonObject : first) {
                            map.putIfAbsent(jsonObject.getString("coloumn"), jsonObject.getString("value"));
                            set.add(jsonObject.getString("coloumn"));
                        }
                    }
                    if (map.size() == 0) {
                        ActSuppliesImportCleaningAcc acc = set(obj, nameColumnValue, codeColumnValue, sskId, hdate, hId, yyUuid, dateValue, departmentValue, unitValue, modelValue);
                        accList.add(acc);
                    } else {
                        for (int j = 0; j < map.size(); j++) {
                            ActSuppliesImportCleaningAcc acc = set(obj, nameColumnValue, codeColumnValue, sskId, hdate, hId, yyUuid, dateValue, departmentValue, unitValue, modelValue);
                            List<String> collect = new ArrayList<>(set);
                            String[] s = map.get(collect.get(j)).split(",");
                            acc.setKmCode(s[0]);
                            acc.setsOfExpenses(s[1]);
                            String num = collect.get(j);
                            Integer moneyColumn = Integer.parseInt(num) - 1;
                            Integer numberColumn = Integer.parseInt(num) - 2;
                            Integer moneys = Integer.parseInt(num);
                            IntStream.range(0, cellData.size())
                                    .mapToObj(cellData::getJSONObject)
                                    .filter(v -> v.getInteger("r") == row)
                                    .forEach(v -> {
                                        Integer columnIndex = v.getInteger("c");
                                        JSONObject columnValue = v.getJSONObject("v");
                                        if (columnValue != null && columnValue.getString("v") != null) {
                                            if (columnIndex.equals(moneyColumn)) {
                                                acc.setMoneyColumn(columnValue.getString("v"));
                                            } else if (columnIndex.equals(numberColumn)) {
                                                acc.setNumberColumn(columnValue.getString("v"));
                                            } else if (columnIndex.equals(moneys)) {
                                                acc.setMoney(columnValue.getString("v"));
                                            }
                                        }
                                    });
                            if (acc.getNumberColumn() != null && !"".equals(acc.getNumberColumn()) && acc.getMoneyColumn() != null && !"".equals(acc.getMoneyColumn())) {
                                BigDecimal num1 = new BigDecimal(acc.getNumberColumn());
                                BigDecimal money1 = new BigDecimal(acc.getMoneyColumn());
                                acc.setMoneyColumns(num1.multiply(money1) + "");
                            }
                            accList.add(acc);
                        }
                    }
                    dateValue = null;
                    departmentValue = null;
                    unitValue = null;
                    modelValue = null;
                    codeColumnValue = null;
                    nameColumnValue = null;
                }
            }
        }
        if (accList.size() != 0) {
            actReadDataMapper.insertDateToAnalysisAfter(accList);
            actReadDataMapper.updateState(accList.get(0).getYyUuid());
            System.err.println("共处理了：" + accList.size() + "条数据");
        }
    }

    private ActSuppliesImportCleaningAcc set(Object obj, String nameColumnValue, String codeColumnValue, String sskId, String hdate, String hId, String yyUuid, String dateValue, String departmentValue, String unitValue, String modelValue) {
        ActSuppliesImportCleaningAcc acc = new ActSuppliesImportCleaningAcc();
        acc.setSskId(sskId);
        acc.setHdate(hdate);
        acc.sethId(Long.valueOf(hId));
        acc.setYyUuid(yyUuid);
        acc.setNameColumn(nameColumnValue);
        acc.setCodeColumn(codeColumnValue);
        if (dateValue != null && ActReadDataServiceImpl.PATTERN.matcher(dateValue).matches()) {
            acc.setDateColumn(DateUtil.excelDateConversion(dateValue));
        } else {
            acc.setDateColumn(dateValue);
        }
        acc.setDepartmentColumn(departmentValue);
        acc.setUnit(unitValue);
        acc.setModel(modelValue);
        Map<String, String> map1 = (Map<String, String>) obj;
        String kmCode = StringUtils.substring(acc.getCodeColumn(), 0, 6);
        if (map1.containsKey(kmCode)) {
            acc.setCategories(map1.get(kmCode));
        } else {
            kmCode = StringUtils.substring(kmCode, 0, 4);
            if (map1.containsKey(kmCode)) {
                acc.setCategories(map1.get(kmCode));
            } else {
                kmCode = StringUtils.substring(kmCode, 0, 2);
                acc.setCategories(map1.getOrDefault(kmCode, "10"));
            }
        }
        acc.setId(StringUtils.remove(String.valueOf(UUID.randomUUID()), "-"));
        return acc;
    }
}
