package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import com.yeejoin.amos.boot.module.jg.api.dto.*;
import com.yeejoin.amos.boot.module.jg.biz.context.DataProcessStrategyContext;
import com.yeejoin.amos.boot.module.jg.biz.event.ChangeDataEvent;
import com.yeejoin.amos.boot.module.jg.biz.event.publisher.EventPublisher;
import com.yeejoin.amos.boot.module.jg.biz.factory.ChangeItemFactory;
import com.yeejoin.amos.boot.module.jg.biz.service.IBizDataChangeHandleStrategy;
import com.yeejoin.amos.boot.module.jg.biz.service.IChangeDataProcessStrategy;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import java.lang.reflect.Field;
import java.util.*;

@Service
public class UseRegisterDataChangeHandleImpl implements IBizDataChangeHandleStrategy {

    private final EventPublisher publisher;

    private final EquipChangeDataUpdateService equipChangeDataUpdateService;

    private final UseRegisterUpdateService useRegisterUpdateService;


    public UseRegisterDataChangeHandleImpl(EventPublisher publisher, EquipChangeDataUpdateService equipChangeDataUpdateService, UseRegisterUpdateService useRegisterUpdateService) {
        this.publisher = publisher;
        this.equipChangeDataUpdateService = equipChangeDataUpdateService;
        this.useRegisterUpdateService = useRegisterUpdateService;
    }


    @Override
    public String canHandleBizType() {
        return "useRegister";
    }

    @Override
    public Map<String, List<Map<String, Object>>> getChangeDetail(String applyNo, ModelType model) {
        return Collections.emptyMap();
    }

    /**
     * 保存
     *
     * @param applyNo    单据编号
     * @param model      single, batch
     * @param changeData 变更数据 key为不同的分组：如使用信息、设计信息、制造信息、技术参数
     */
    @Override
    public void doSave(String applyNo, ModelType model, Map<String, List<Map<String, Object>>> changeData) {
        List<ChangeDataDto> allChangeColumns = new ArrayList<>();
        // 选择是台套、还是单位办理的方式，进行数据的解析
        IChangeDataProcessStrategy dataProcessor = DataProcessStrategyContext.getStrategy(model);
        changeData.forEach((k, v) -> {
            Map<String, List<ChangeDataDto>> columnsMap = new HashMap<>();
            if (k.startsWith("biz")) {
                // 单据信息变化
                columnsMap = dataProcessor.handle(v, applyNo);
                // 将前端json数据，格式化解析为java对象格式及数据比对去掉未变化的数据，key为record, value为字段数组
                columnsMap.forEach((a, columns) -> {
                    if (!columns.isEmpty()) {
                        // 将json列转为java-bean
                        BaseChangeDataDto changeDataDto = castColum2Bean(k, columns);
                        // 业务处理
                        this.dealBizDataForDoc(applyNo, changeDataDto);
                        // 日志数据构建
                        this.buildLogData(allChangeColumns, columns, a, k);
                    }
                });
            } else if (k.startsWith("equip")) {
                // 设备信息变化
                columnsMap = dataProcessor.handle(v, null);
                // 将前端json数据，格式化解析为java对象格式及数据比对去掉未变化的数据，key为record, value为字段数组
                columnsMap.forEach((record, columns) -> {
                    if (!columns.isEmpty()) {
                        // 将json列转为java-bean
                        BaseChangeDataDto changeDataDto = castColum2Bean(k, columns);
                        // 业务处理
                        this.dealBizDataForEquip(record, changeDataDto);
                        // 日志数据构建
                        this.buildLogData(allChangeColumns, columns, record, k);
                    }
                });
            }
        });
        // 更新历史的JSON的数据
        this.updateHistoryJson(applyNo);
        // 记录日志
        if (!allChangeColumns.isEmpty()) {
            publisher.publish(new ChangeDataEvent(this, allChangeColumns, RequestContext.cloneRequestContext()));
        }
    }

    private void updateHistoryJson(String applyNo) {
        useRegisterUpdateService.updateHisData(applyNo);
    }

    private void dealBizDataForDoc(String record, BaseChangeDataDto changeDataDto) {
        if (changeDataDto instanceof UseRegisterChangeDataDto) {
            // todo 字段待定- 暂无需变更数据
            UseRegisterChangeDataDto useRegisterChangeDataDto = (UseRegisterChangeDataDto) changeDataDto;
        }
    }

    private void buildLogData(List<ChangeDataDto> allChangeColumns, List<ChangeDataDto> columns, String changeId, String groupKey) {
        columns.forEach(column -> {
            column.setChangeId(changeId);
            column.setColumnFamily(groupKey);
            column.setBizType("使用登记");
        });
        allChangeColumns.addAll(columns);
    }


    /**
     * 业务处理-业务对象
     *
     * @param record        设备主键
     * @param changeDataDto 变更后数据
     */
    private void dealBizDataForEquip(String record, BaseChangeDataDto changeDataDto) {
        // 制造信息
        if (changeDataDto instanceof EquipFactoryChangeDataDto) {
            EquipFactoryChangeDataDto equipFactoryChangeDataDto = (EquipFactoryChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateFactoryChangeData(record, equipFactoryChangeDataDto);
        }
        // 设计信息
        if (changeDataDto instanceof EquipDesignChangeDataDto) {
            EquipDesignChangeDataDto equipDesignChangeDataDto = (EquipDesignChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateDesignChangeData(record, equipDesignChangeDataDto);
        }
        // 注册信息
        if (changeDataDto instanceof EquipRegisterChangeDataDto) {
            EquipRegisterChangeDataDto registerChangeDataDto = (EquipRegisterChangeDataDto) changeDataDto;
            equipChangeDataUpdateService.updateRegisterChangeData(record, registerChangeDataDto);
        }
        // 新定义-不同的技术参数要单独处理表
        if (changeDataDto instanceof EquipTechParamChangeDataDto) {
            EquipTechParamChangeDataDto techParamChangeDataDto = (EquipTechParamChangeDataDto) changeDataDto;
        }
    }


    private BaseChangeDataDto castColum2Bean(String group, List<ChangeDataDto> columns) {
        Class<? extends BaseChangeDataDto> t = ChangeItemFactory.getItemGroupClass(group);
        BaseChangeDataDto changeDataDto;
        try {
            changeDataDto = t.newInstance();
            for (Field field : changeDataDto.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                // 设置默认值，用来控制default时，数据未变化，不进行此字段的更新
                field.set(changeDataDto, IBizDataChangeHandleStrategy.DEFAULT_VALUE);
                // 匹配赋值
                for (ChangeDataDto colum : columns) {
                    if (colum.getColumnKey().equals(field.getName())) {
                        field.set(changeDataDto, colum.getColumnNewValue());
                        break;
                    }
                }
            }

        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return changeDataDto;
    }

}
