<template>
  <div class="gl-page-content">
    <div class="header">
      <div class="form">
        <el-form>
          <el-form-item :label="$t('数据预测.降阶模型')">
            <el-select v-model="selectedModel" placeholder="请选择降阶模型" filterable @change="onModelChangeFun">
              <el-option v-for="item in modelOptions" :label="item.label" :value="item" :key="item.id" />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <div class="button">
        <el-popover
          class="box-item"
          :title="selectedModel?.modelName"
          :content="selectedModel?.description"
        >
          <template #reference>
            <el-button>{{ $t('数据预测.功能说明') }}</el-button>
          </template>
        </el-popover>
      </div>
    </div>
    <div class="content" v-loading="forecastLoading">
      <div class="left">
        <BaseTable ref="inputTableRef" :tableName="TABLE_NAME.DATA_FORECAST_INPUT" showIndex :actionsWidth="200" hidePagination>
          <template #type>
            {{ $t('数据预测.输入') }}
          </template>
          <template #value="{ row }">
            <el-input-number
              v-model="row.value"
              placeholder="请输入内容"
            />
          </template>
        </BaseTable>
      </div>
      <div class="center">
        <el-popconfirm :title="$t('数据预测.确定开始预测吗')" @confirm="beginForecastFun">
          <template #reference>
            <el-button :disabled="selectedModel?.predStatus==='预测中'" type="primary" :loading="forecastLoading" >{{ $t('数据预测.开始预测') }}</el-button>
          </template>
        </el-popconfirm>
      </div>
      <div class="right">
        <BaseTable ref="outputTableRef" :tableName="TABLE_NAME.DATA_FORECAST_OUTPUT" showIndex :actionsWidth="200" hidePagination>
          <template #type>
           {{ $t('数据预测.输出') }}
          </template>
        </BaseTable>
      </div>
    </div>
  </div>

</template>
<script setup lang="ts">
import { getModelTrainingListApi, startPredictApi, getModelPredictResultApi, getHandleLoadDataResultApi } from '@/api/data/dataForecast';
import BaseTable from '@/components/common/table/baseTable.vue';
import { ref, onMounted } from 'vue';
import type { Model } from './type';
import { TABLE_NAME } from '@/utils/enum/tableName';

const inputTableRef = ref();
const outputTableRef = ref();

const selectedModel = ref({} as Model);
const modelOptions: any = ref([]);

const queryModelListFun = async () => {
  const req = {
    current: 1,
    size: 9999,
  };
  const res: any = await getModelTrainingListApi(req);
  if (res.code === 200 && res.data && res.data?.data?.length > 0) {
    modelOptions.value = res.data?.data?.map((item: any) => ({
      ...item,
      label: item.modelName,
      value: item.id,
    }));
  } else {
    modelOptions.value = [];
  }
  if (modelOptions.value.length > 0) {
    onModelChangeFun(modelOptions.value[0]);
  };
};

const onModelChangeFun = async (val: Model) => {
  selectedModel.value = val;
  const sourceTitleMap = await getTitleMapFun();
  if (selectedModel.value.inputLabel) {
    const inputData = JSON.parse(selectedModel.value.inputLabel);
    const inputTableData = inputData.map((item: any) => {
      return {
        name: item,
        label: sourceTitleMap[item] || item,
      };
    });
    const outputData = JSON.parse(selectedModel.value.outputLabel || '[]');
    const outputTableData = outputData.map((item: any) => {
      return {
        name: item,
        label: sourceTitleMap[item] || item,
      };
    });
    inputTableRef.value?.setDataFun(inputTableData);
    outputTableRef.value?.setDataFun(outputTableData);
  } else {
    inputTableRef.value?.setDataFun([]);
    outputTableRef.value?.setDataFun([]);

  }
  getModelPredictResultFun();
};

const forecastLoading = ref(false);
const beginForecastFun = async () => {
  const inputTableData = inputTableRef.value?.tableData;
  const inputDataFormatted = inputTableData.map((item: any) => {
    return {
      name: item.name,
      value: Number(item.value),
    };
  });
  forecastLoading.value = true;
  const req = {
    modelId: selectedModel.value.id,
    jsonData: JSON.stringify(inputDataFormatted),
  };
  const res: any = await startPredictApi(req);
  forecastLoading.value = false;
  if (res.code === 200) {
    getModelPredictResultFun();
  } else {
    clearResultFun();
  }
};
const getTitleMapFun = async () => {
  const req = {
    modelId: selectedModel.value.id,
  };
  const res: any = await getHandleLoadDataResultApi(req);
  if (res.code === 200 && res.data) {
    if (Array.isArray(res.data?.source_title)) {
      const titleMap: Record<string, string> = {};
      res.data?.source_title.forEach((item: Record<string, string>) => {
        Object.keys(item).forEach((key:string) => {
          titleMap[key] = item[key];
        });
      });
      return titleMap;
    } else {
      return {};
    }
  } else {
    return {};
  }
};
const clearResultFun = () => {
  const inputData = inputTableRef.value?.tableData;
  const outputData = outputTableRef.value?.tableData;
  const inputDataFormatted = inputData.map((item: any) => {
    return {
      ...item,
      value: '',
    };
  });
  const outputDataFormatted = outputData.map((item: any ) => {
    return {
      ...item,
      value: '',
    };
  });
  inputTableRef.value?.setDataFun(inputDataFormatted);
  outputTableRef.value?.setDataFun(outputDataFormatted);
};
const getModelPredictResultFun = async () => {
  forecastLoading.value = true;
  const res: any = await getModelPredictResultApi({ modelId: selectedModel.value.id });
  forecastLoading.value = false;
  if (res.code === 200 && res.data) {
    // 处理预测结果
    const inputData = inputTableRef.value?.tableData;
    const outputData = outputTableRef.value?.tableData;
    const inputPredLabelValue = res.data?.inputPredLabelValue || [];
    const forecastValue = res.data?.outputPredLabelValue;
    const inputDataFormatted = inputData.map((item: any) => {
      const inputValue = inputPredLabelValue.find((inputItem: any) => inputItem.name === item.name);
      return {
        ...item,
        value: inputValue.value || '',
      };
    });
    const outputDataFormatted = outputData.map((item: any ) => {
      return {
        ...item,
        value: forecastValue ? forecastValue[item.name] : '',
      };
    });
    inputTableRef.value?.setDataFun(inputDataFormatted);
    outputTableRef.value?.setDataFun(outputDataFormatted);
  } else {
    clearResultFun();
  }
};

onMounted(() => {
  queryModelListFun();
});

</script>
<style lang="scss" scoped>
.forecast {
  width: 100%;
  height: 100%;

}

.header {
  width: 100%;
  height: 60px;
  display: flex;

  .form {
    width: 300px;
    margin-right: 20px;
  }
}

.content {
  display: flex;
  width: 100%;
  height: calc(100% - 60px);

  .left {
    width: 50%;
    height: 100%;
  }

  .center {
    width: 150px;
    height: 100%;
    text-align: center;
    padding-top: 100px;
  }

  .right {
    width: calc(50% - 150px);
    height: 100%;
  }
}
</style>
