<template>
  <el-card class="box-card">
    <template #header>
      <div class="card-header">
        <span>降酸模型</span>
      </div>
    </template>

    <el-form
      :model="form"
      ref="predictForm"
      label-width="240px"
      label-position="left"
    >
      <el-form-item
        label="土壤初始 pH"
        prop="init_pH"
        :error="errorMessages.init_pH"
        required
      >
        <el-input
          v-model="form.init_pH"
          size="large"
          placeholder="请输入土壤初始 3~6 pH"
          ref="inputRefs.init_pH"
          @input="handleInput('init_pH', $event, 3, 6)"
        >
        </el-input>
      </el-form-item>

      <el-form-item
        label="土壤目标 pH"
        prop="target_pH"
        :error="errorMessages.target_pH"
        required
      >
        <el-input
          v-model="form.target_pH"
          size="large"
          placeholder="请输入土壤目标 5~7 pH"
          ref="inputRefs.target_pH"
          @input="handleInput('target_pH', $event, 5, 7)"
        >
        </el-input>
      </el-form-item>

      <el-form-item
        label="土壤有机质(g/kg)"
        prop="OM"
        :error="errorMessages.OM"
        required
      >
        <el-input
          v-model="form.OM"
          size="large"
          placeholder="请输入土壤有机质 10~30 (g/kg)"
          ref="inputRefs.OM"
          @input="handleInput('OM', $event, 10, 30)"
        >
        </el-input>
      </el-form-item>

      <el-form-item
        label="土壤粘粒(g/kg)"
        prop="CL"
        :error="errorMessages.CL"
        required
      >
        <el-input
          v-model="form.CL"
          size="large"
          placeholder="请输入土壤粘粒 50~600 (g/kg)"
          ref="inputRefs.CL"
          @input="handleInput('CL', $event, 50, 600)"
        >
        </el-input>
      </el-form-item>

      <el-form-item
        label="交换性氢(cmol/kg)"
        prop="H"
        :error="errorMessages.H"
        required
      >
        <el-input
          v-model="form.H"
          size="large"
          placeholder="请输入交换性氢 0~4 (cmol/kg)"
          ref="inputRefs.H"
          @input="handleInput('H', $event, 0, 4)"
        >
        </el-input>
      </el-form-item>

      <el-form-item
        label="交换性铝(cmol/kg)"
        prop="Al"
        :error="errorMessages.Al"
        required
      >
        <el-input
          v-model="form.Al"
          size="large"
          placeholder="请输入交换性铝 0~4 (cmol/kg)"
          ref="inputRefs.Al"
          @input="handleInput('Al', $event, 0, 4)"
        >
        </el-input>
      </el-form-item>

      <el-button type="primary" @click="onSubmit" class="onSubmit"
        >计算</el-button
      >

      <el-dialog
        v-model="dialogVisible"
        @close="onDialogClose"
        :close-on-click-modal="false"
        width="500px"
        align-center
        class="dialog-class"
        title="计算结果"
      >
        <span class="dialog-class"
          >每亩地土壤表层(20cm)撒 {{ result }}吨生石灰</span
        ><br />
        <span class="dialog-class">{{ result }}吨</span>
        <template #footer>
          <el-button @click="dialogVisible = false">关闭</el-button>
        </template>
      </el-dialog>
    </el-form>
  </el-card>
</template>

<script setup lang="ts">
import { reactive, ref, nextTick } from "vue";
import { ElMessage } from 'element-plus';
import axios from 'axios';
import request from '../../utils/request';

const form = reactive<{
  init_pH: number | null,
  target_pH: number | null,
  OM: number | null,
  CL: number | null,
  H: number | null,
  Al: number | null,
}>({
  init_pH: null,
  target_pH: null,
  OM: null,
  CL: null,
  H: null,
  Al: null,
});

const result = ref<number | null>(null);
const dialogVisible = ref(false);
const predictForm = ref<any>(null);
const errorMessages = reactive({
  init_pH: '',
  target_pH: '',
  OM: '',
  CL: '',
  H: '',
  Al: '',
});

// 使用 ref 来存储输入框元素
const inputRefs = reactive<{
  [key in keyof typeof form]: any;
}>({
  init_pH: ref<HTMLInputElement | null>(null),
  target_pH: ref<HTMLInputElement | null>(null),
  OM: ref<HTMLInputElement | null>(null),
  CL: ref<HTMLInputElement | null>(null),
  H: ref<HTMLInputElement | null>(null),
  Al: ref<HTMLInputElement | null>(null),
});

// 限制输入为数字并校验范围
const handleInput = (field: keyof typeof form, event: Event, min: number, max: number) => {
  try {
    const inputElement = inputRefs[field].value;
    if (!inputElement) {
      console.error('未找到输入框元素');
      return;
    }

    // 过滤非数字和小数点字符
    const rawValue = (event.target as HTMLInputElement).value;
    const filteredValue = rawValue.replace(/[^0-9.]/g, '');
    inputElement.value = filteredValue;

    if (filteredValue === '') {
      form[field] = null; // 当输入为空时设置为 null
      errorMessages[field] = '';
      return;
    }

    const numValue = parseFloat(filteredValue);
    if (isNaN(numValue) || numValue < min || numValue > max) {
      form[field] = null; // 如果值无效，则设为 null
      errorMessages[field] = `输入值应在 ${min} 到 ${max} 之间且为有效数字`;
    } else {
      form[field] = numValue; // 如果值有效，则设为解析后的数值
      errorMessages[field] = '';
    }
  } catch (error) {
    console.error(`处理输入时出错:`, error);
    errorMessages[field] = '输入处理出错，请检查输入';
  }
};

const validateInput = (value: string | number, min: number, max: number): boolean => {
  const numValue = parseFloat(value as string);
  if (isNaN(numValue)) {
    return false;
  }
  return numValue >= min && numValue <= max;
};

// 计算方法
const onSubmit = async () => {
  const inputConfigs = [
    { field: 'init_pH' as keyof typeof form, min: 3, max: 6 },
    { field: 'target_pH' as keyof typeof form, min: 5, max: 7 },
    { field: 'OM' as keyof typeof form, min: 10, max: 30 },
    { field: 'CL' as keyof typeof form, min: 50, max: 600 },
    { field: 'H' as keyof typeof form, min: 0, max: 4 },
    { field: 'Al' as keyof typeof form, min: 0, max: 4 },
  ];

  let isValid = true;
  inputConfigs.forEach((config) => {
    const { field, min, max } = config;
    const value = form[field];
    
    // 检查是否为 null
    if (value === null) {
      isValid = false;
      errorMessages[field] = `输入值应在 ${min} 到 ${max} 之间且为有效数字`;
      return;
    }

    if (!validateInput(value, min, max)) {
      isValid = false;
      errorMessages[field] = `输入值应在 ${min} 到 ${max} 之间且为有效数字`;
    } else {
      errorMessages[field] = '';
    }
  });

  if (!isValid) {
    ElMessage.error('输入值不符合要求，请检查输入');
    return;
  }

  console.log('开始计算...');
  const data = {
    model_id: 6,
    parameters: {
      init_pH: form.init_pH,
      target_pH: form.target_pH,
      OM: form.OM,
      CL: form.CL,
      H: form.H,
      Al: form.Al,
    }
  };
  console.log('提交的数据:', data);
  try {
    const response = await request.post('/predict', data, {
      headers: {
        'Content-Type': 'application/json'
      }
    });
    console.log('预测结果:', response.data);
    if (response.data && typeof response.data.result === 'number') {
      result.value = parseFloat(response.data.result.toFixed(2));
    } else {
      console.error('未获取到有效的预测结果');
      ElMessage.error('未获取到有效的预测结果');
    }
    dialogVisible.value = true;
  } catch (error: unknown) {
    console.error('请求失败:', error);
    if (axios.isAxiosError(error)) {
      if (error.response) {
        ElMessage.error(`请求失败，状态码: ${error.response.status}`);
      } else if (error.request) {
        ElMessage.error('请求发送成功，但没有收到响应');
      } else {
        ElMessage.error('请求过程中发生错误: ' + error.message);
      }
    } else {
      ElMessage.error('请求过程中发生错误: ' + (error as Error).message);
    }
  }
};

// 监听弹窗关闭事件，关闭后初始化值
const onDialogClose = () => {
  dialogVisible.value = false;

  // 初始化 form 中的所有字段
  Object.keys(form).forEach((key) => {
    const typedKey = key as keyof typeof form;
    form[typedKey] = null;
  });

  // 清除所有的错误信息
  Object.keys(errorMessages).forEach((key) => {
    const typedKey = key as keyof typeof errorMessages;
    errorMessages[typedKey] = '';
  });

  nextTick(() => {
    if (predictForm.value) {
      predictForm.value.resetFields();
    }
  });
};
</script>

<style scoped>
.box-card {
  max-width: 850px;
  margin: 0 auto;
  padding: 20px;
  background-color: #f0f5ff;
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.card-header {
  font-size: 25px;
  text-align: center;
  color: #333;
  margin-bottom: 30px;
}

.el-form-item {
  margin-bottom: 20px;
}

:deep(.el-form-item__label) {
  font-size: 18px;
  color: #666;
}

.el-input {
  width: 80%;
}

.onSubmit {
  display: block;
  margin: 0 auto;
  background-color: #007bff;
  color: white;
  padding: 10px 20px;
  border-radius: 5px;
  font-size: 16px;
  transition: background-color 0.3s ease;
}

.onSubmit:hover {
  background-color: #0056b3;
}

.dialog-class {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%; /* 确保容器占满对话框内容区域 */
  font-size: 22px;
}

@media (max-width: 576px) {
  .el-form {
    --el-form-label-width: 100px;
  }
}
</style>
