<!--
     智能井位推荐参数设置
     author: RYG
     date: 2025年6月25日09:37:38
-->
<template>
  <div class="scrollable-form">
    <el-form v-model="propertyParam.wellParamSettings" label-position="right" label-width="100px">
      <!-- 标题设置 -->
      <div name="wellParamSettings" class="well-param">
        <el-divider content-position="left">井平台参数设置</el-divider>
        <el-form-item label="断裂图件" label-position="right" class="well-param-item">
          <el-select v-model="propertyParam.wellParamSettings.selectedOption" placeholder="请选择断裂文件"
            class="well-param-input">
            <el-option v-for="item in fractureFileData" :key="item.MapID" :label="item.MapName" :value="item.MapID"
              @click="handleOptionClick(item)"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="边界图层" label-position="right" class="well-param-item">
          <el-input v-model="propertyParam.wellParamSettings.boundaryLayer" placeholder="选择边界图层"
            class="well-param-input" @click="showBoundaryLayerData"></el-input>
        </el-form-item>
        <el-form-item label="断层图层" label-position="right" class="well-param-item">
          <el-input v-model="propertyParam.wellParamSettings.faultLayer" placeholder="选择断层图层" class="well-param-input"
            @click="showFractureLayerData"></el-input>
        </el-form-item>
        <el-form-item label="井名" label-position="right" class="well-param-item">
          <el-input v-model="propertyParam.wellParamSettings.WellNamePrefix" placeholder="输入井名"
            class="well-param-input"></el-input>
        </el-form-item>
        <el-form-item label="井支数" class="well-param-item">
          <el-input-number v-model="propertyParam.wellParamSettings.BranchCount" placeholder="井支数"
            class="well-param-input"></el-input-number>
        </el-form-item>
        <el-form-item label="靶前距" class="well-param-item">
          <el-input-number v-model="propertyParam.wellParamSettings.BranchOffset" placeholder="靶前距"
            class="well-param-input"></el-input-number>
        </el-form-item>
        <el-form-item label="水平段长度" class="well-param-item">
          <el-input-number v-model="propertyParam.wellParamSettings.BranchLength" placeholder="水平段长度"
            class="well-param-input"></el-input-number>
        </el-form-item>
        <el-form-item label="井支间距" class="well-param-item">
          <el-input-number v-model="propertyParam.wellParamSettings.BranchSpace" placeholder="井支间距"
            class="well-param-input"></el-input-number>
        </el-form-item>

        <div class="other-form-item-nolabel">
          <el-checkbox v-model="propertyParam.wellParamSettings.DeploySide2">双侧布井</el-checkbox><el-checkbox
            v-model="propertyParam.wellParamSettings.DeploySide1">单侧布井</el-checkbox>
        </div>
        <div class="other-form-item-nolabel">
          <el-checkbox v-model="propertyParam.wellParamSettings.DeployAgain">二次布井</el-checkbox>
        </div>
      </div>
    </el-form>
    <el-form label-width="100px" :model="propertyParam.calcParamSettings">
      <!-- 坐标轴设置 -->
      <div name="calcParamSettings" class="well-param">
        <el-divider content-position="left">计算参数设置</el-divider>
        <el-form-item label="井平台间距" class="well-param-item">
          <el-input-number v-model="propertyParam.calcParamSettings.WellsSpace" placeholder="井平台间距"
            class="well-param-input"></el-input-number>
        </el-form-item>
        <el-form-item label="突变率" class="well-param-item">
          <el-input-number v-model="propertyParam.calcParamSettings.MutationRate" placeholder="突变率" :min="0.1"
            :max="0.9" class="well-param-input" :step="0.1"></el-input-number>
        </el-form-item>
        <el-form-item label="旋转次数" class="well-param-item">
          <el-input-number v-model="propertyParam.calcParamSettings.Rotations" placeholder="旋转次数"
            class="well-param-input"></el-input-number>
        </el-form-item>
        <el-form-item label="角度范围" class="well-param-item">
          <el-input v-model="propertyParam.calcParamSettings.AngleStart" placeholder="角度范围最小值" class="well-param-input"
            style="width: 60px"></el-input>
          &nbsp; ~ &nbsp;
          <el-input v-model="propertyParam.calcParamSettings.AngleEnd" placeholder="角度范围最大值" class="well-param-input"
            style="width: 60px"></el-input>
        </el-form-item>
        <el-form-item label="指定角度" class="well-param-item">
          <div class="other-form-item">
            <el-checkbox v-model="propertyParam.calcParamSettings.SpecifyAngles" placeholder="指定角度"></el-checkbox>
            <el-input v-model="propertyParam.calcParamSettings.SpeciaAngles" placeholder="指定角度范围"
              :disabled="!propertyParam.calcParamSettings.SpecifyAngles" class="well-param-input"></el-input>
          </div>
        </el-form-item>

        <el-form-item label="忽略小断裂" class="well-param-item">
          <div class="other-form-item">
            <el-checkbox class="left-label" v-model="propertyParam.calcParamSettings.IgnoreMiniFault"
              placeholder="忽略小断裂"></el-checkbox>
            <el-input v-model="propertyParam.calcParamSettings.MiniFaultLength" placeholder="断裂值"
              :disabled="!propertyParam.calcParamSettings.IgnoreMiniFault" class="well-param-input"
              style="width: 80px"></el-input>
          </div>
        </el-form-item>
      </div>
    </el-form>
    <div class="button-container">
      <el-button type="primary" @click="handleStartCalc" :disabled="smartWellButton">计算</el-button>
      <el-button type="primary" @click="handleStopCalc(true)" :disabled="smartWellButtonStop">停止</el-button>
    </div>
    <el-dialog v-model="showLayer" title="请选择层位数据" style="width: 270px; height: 600px; z-index: 30" @close="handleClose"
      :close-on-click-modal="false">
      <div class="img-layer">
        <ClientOnly>
          <LayerTree :isPopup="true" class="popup-tree" :show-oper="true" :token-key="currentTokenKey" />
        </ClientOnly>
      </div>
    </el-dialog>
    <ProgressTracker ref="progressRef" v-model="progressVisible" title="计算进度" :initialProgress="currentProgress"
      :message="progressMessage" @complete="onComplete" @manual-close="onManualClose" />
  </div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, defineEmits } from "vue";
import {
  fractureFileList,
  startSmartWellCalc,
  stopSmartWellCalc,
  getWellRecommend
} from "@/services/wellRecommandService";
import { emitter } from "~/utils/eventBus";
import { checkEmpty } from "@/utils/objHelper";
import { EMIT_COMMAND } from '~/utils/commandTypes';
import { useSignalR } from "~/composables/useSignalR";
import { STORAGE_KEYS } from "~/utils/storageKeys"
// 当前页图件token的 key
// const currentTokenKey = STORAGE_KEYS.WELL_RECOMMAND_TOKEN;

// 消息提示（自动隐藏）
const { $toastMessage } = useNuxtApp();

const { connect, connectionId, sigMsg, sendMessage, on } = useSignalR();

// 进度条显示状态
const progressVisible = ref(false);
const progressRef = ref(null);

const currentToken = computed(() => localStorage.getItem(currentTokenKey));

// 当前进度
const currentProgress = ref(0);

// 当前进度的消息
const progressMessage = ref('');

// 任务是否已经开始，用于按钮状态控制、任务状态监听
const taskStarted = ref(false);
// 任务ID
const taskId = ref("");

const emit = defineEmits(['openFile'])

// 配置参数
const propertyParam = reactive({
  // 井平台参数设置
  wellParamSettings: {
    selectedOption: "",
    fractureFile: "",
    boundaryLayer: "",
    faultLayer: "",
    WellNamePrefix: "井",
    BranchCount: 6,
    BranchOffset: 500,
    BranchLength: 1800,
    BranchSpace: 300,
    DeploySide2: true,
    DeploySide1: true,
    DeployAgain: false,
  },
  // 计算参数设置
  calcParamSettings: {
    WellsSpace: 500,
    MutationRate: 0.5, // 0.1-0.9之间
    Rotations: 8,
    AngleStart: 30,
    AngleEnd: 90,
    SpecifyAngles: false,
    SpeciaAngles: ["0", "0", "90", "0", "0", "270", "180", "180", "180"],
    IgnoreMiniFault: true,
    MiniFaultLength: 1000,
  },
});

// 图层顶层
const boundaryLayerData = reactive([
  {
    id: 0,
    parentId: 0,
    name: "图层",
    status: 0,
    children: [],
  },
]);

// 计算按钮状态
const smartWellButton = computed(() => taskStarted.value);
// 停止按钮状态
const smartWellButtonStop = computed(() => !taskStarted.value);

// 二次布井时用到的数据Id
const DeployAgainId = ref('');

const fractureFileData = ref([]);

/** 标识选择的是边界还是断层，0边界，1断层 */
const inputType = ref(-1);

// 图层显示切换属性
const showLayer = ref(false);

watchEffect(() => {
  if (!sigMsg.value) {
    return;
  }

  const msg = JSON.parse(sigMsg.value);
  const prog = msg.progress;
  const smsg = msg.msg;

  currentProgress.value = prog;
  progressMessage.value = smsg;
  updateCalcInfo(prog, smsg, true);
  emitMsg({
    type: "calcRedraw",
    cmdID: currentTokenKey,
    data: JSON.stringify({ msg: '重新绘制' }),
  });
  emitRefresh();
});

// 处理选择断裂图件
const handleOptionClick = (item) => {
  emitter.emit(EMIT_COMMAND.SOURCE_CHANGED);
  // emitMsg({
  //   type: EMIT_COMMAND.OPEN_FILE,
  //   cmdID: currentTokenKey,
  //   data: JSON.stringify({ fileName: item.MapName }),
  // });
  // doOpenFile(item.MapName, currentTokenKey);
  console.log("打开图件:handleOptionClick=", item.MapName)
  emit('openFile', item.MapName);
  // 如果选择了断裂图件就表示要计算新的
  // if (DeployAgainId.value === 0) {
  propertyParam.wellParamSettings.fractureFile = item.MapName;

  // 清空之前选择的图层数据
  boundaryLayerData[0].children = [];
  propertyParam.wellParamSettings.boundaryLayer = "";
  propertyParam.wellParamSettings.faultLayer = "";
  // }
};



// 显示边界图层数据的逻辑
const showBoundaryLayerData = () => {

  if (!propertyParam.wellParamSettings.selectedOption) {
    $toastMessage.warning("您还没有选择断裂分布图！");
    return;
  }

  // 检查boundaryLayerData是否正确定义
  if (!boundaryLayerData || !boundaryLayerData[0] || !boundaryLayerData[0].children) {
    console.error("boundaryLayerData结构不正确");
    $toastMessage.error("图层数据结构初始化失败！");
    return;
  }

  inputType.value = 0;

  // 显示选择框
  showLayer.value = true;
};

// 显示断层图层数据的逻辑
const showFractureLayerData = () => {
  if (!propertyParam.wellParamSettings.selectedOption) {
    $toastMessage.warning("您还没有选择断裂分布图！");
    return;
  }

  inputType.value = 1;

  // 显示选择框
  showLayer.value = true;
};

// 发送计算命令
const handleStartCalc = async () => {
  try {
    // 检查断裂分布图选择
    let selectedChunk = null;
    if (propertyParam.wellParamSettings.DeployAgain) {
      // 是二次布井
      selectedChunk = propertyParam.wellParamSettings.selectedOption;
    } else {
      let selectedValue = fractureFileData.value.find(
        (chunk) => chunk.MapID === propertyParam.wellParamSettings.selectedOption
      );
      selectedChunk = selectedValue?.MapName;
      if (checkEmpty(selectedChunk)) {
        $toastMessage.warning("您还没有选择断裂分布图！");
        return;
      }
    }

    if (!selectedChunk) {
      $toastMessage.warning("您还没有选择断裂分布图！");
      return;
    }

    if (!connectionId.value) {
      $toastMessage.warning("实时消息连接未建立，请刷新页面重试！");
      return;
    }

    // 检查必要参数
    if (checkEmpty(propertyParam.wellParamSettings.boundaryLayer)) {
      $toastMessage.warning("请选择边界图层！");
      return;
    }

    if (checkEmpty(propertyParam.wellParamSettings.faultLayer)) {
      $toastMessage.warning("请选择断层图层！");
      return;
    }

    // 修改按钮状态
    taskStarted.value = true;

    // 组装计算参数
    const smartWellParam = {
      DeployAgainId: DeployAgainId.value,
      clientId: currentToken.value,
      drawerId: currentToken.value,
      connectionId: connectionId.value,
      wellParamSettings: {
        fractureFile: selectedChunk || propertyParam.wellParamSettings.selectedOption,
        boundaryLayer: propertyParam.wellParamSettings.boundaryLayer,
        faultLayer: propertyParam.wellParamSettings.faultLayer,
        WellNamePrefix: propertyParam.wellParamSettings.WellNamePrefix,
        BranchCount: parseInt(propertyParam.wellParamSettings.BranchCount) || 6,
        BranchOffset: parseInt(propertyParam.wellParamSettings.BranchOffset) || 500,
        BranchLength: parseInt(propertyParam.wellParamSettings.BranchLength) || 1800,
        BranchSpace: parseInt(propertyParam.wellParamSettings.BranchSpace) || 300,
        DeploySide2: propertyParam.wellParamSettings.DeploySide2,
        DeploySide1: propertyParam.wellParamSettings.DeploySide1,
        DeployAgain: propertyParam.wellParamSettings.DeployAgain,
      },
      calcParamSettings: {
        WellsSpace: parseInt(propertyParam.calcParamSettings.WellsSpace) || 500,
        MutationRate: parseFloat(propertyParam.calcParamSettings.MutationRate) || 0.5,
        Rotations: parseInt(propertyParam.calcParamSettings.Rotations) || 8,
        AngleStart: parseInt(propertyParam.calcParamSettings.AngleStart) || 30,
        AngleEnd: parseInt(propertyParam.calcParamSettings.AngleEnd) || 90,
        SpecifyAngles: propertyParam.calcParamSettings.SpecifyAngles,
        SpeciaAngles: propertyParam.calcParamSettings.SpecifyAngles ? (propertyParam.calcParamSettings.SpeciaAngles ? [propertyParam.calcParamSettings.SpeciaAngles] : []) : [],
        IgnoreMiniFault: propertyParam.calcParamSettings.IgnoreMiniFault,
        MiniFaultLength:
          parseInt(propertyParam.calcParamSettings.MiniFaultLength) || 1000,
      },
    };

    progressVisible.value = true;
    const response = await startSmartWellCalc(smartWellParam);

    if (!response) {
      taskStarted.value = false;
      taskId.value = "";
      $toastMessage.error("智能布井失败: 服务器未返回任务ID");
      progressVisible.value = false;
      return;
    }

    taskId.value = response;

    updateCalcInfo(0, "正在初始化", true);
  } catch (error) {
    console.error("智能布井出错：", error);
    taskId.value = null;
    $toastMessage.error(
      `智能布井失败: ${error.response?.data?.message || error.message || "未知错误"}`
    );
    localStorage.removeItem("currentTaskId");
    progressVisible.value = false;
    progressMessage.value = '';
  }
};

const updateCalcInfo = (progress, msg, isRunning) => {
  localStorage.setItem(
    "currentTaskId",
    JSON.stringify({
      taskId: taskId.value,
      progress: progress,
      message: msg,
      isRunning: isRunning,
    })
  );
}

// 手动关闭进度条
const onManualClose = async () => {
  await handleStopCalc(false);
}

// 停止任务处理
const handleStopCalc = async (closeProgress = true) => {
  // 停止计算的逻辑
  try {

    if (taskId.value && taskStarted.value) {
      const response = await stopSmartWellCalc(taskId.value);
      if (response) {
        $toastMessage.info("成功停止计算任务");
        // emitRefresh();
        // localStorage.removeItem("currentTaskId");
      } else {
        $toastMessage.warning("停止任务失败");
      }
    }
  } catch (error) {
    console.error("停止错误：", error);
  } finally {
    taskId.value = null;
    // 更新本地存储
    updateCalcInfo(0, "任务已停止", false);
    // 加载断裂图件
    await getFractureFileList();
    if (closeProgress && progressRef.value) {
      progressRef.value.close();
    }
    // progressVisible.value = false;
    taskStarted.value = false;
    emitRefresh();
    emitMsg({
      type: "calcRedraw",
      cmdID: currentTokenKey,
      data: JSON.stringify({ msg: '重新绘制' }),
    });
  }
};

const emitRefresh = () => {
  emitter.emit(EMIT_COMMAND.REFRESH_RESULT);
};

const emitMsg = (data) => {
  // console.log("emitMsg", data);
  emitter.emit(EMIT_COMMAND.EVT_TYPE, data);
};

onMounted(async () => {
  // 加载断裂图件
  await getFractureFileList();

  listenEmitter();
});

// 监听图层选择
const listenEmitter = () => {
  emitter.on(EMIT_COMMAND.SELECTED_LAYER, (data) => {

    handleClose();

    if (checkEmpty(data)) {
      $toastMessage.warning("请选择图层！");
      return;
    }

    switch (inputType.value) {
      case 0:
        propertyParam.wellParamSettings.boundaryLayer = data;
        break;
      case 1:
        propertyParam.wellParamSettings.faultLayer = data;
        break;
    }
  });

  // // 二次布井事件
  // emitter.on("reCalc", async (data) => {
  //   try {
  //     const response = await getWellRecommend(data.Id);
  //     if (!response) {
  //       $toastMessage.error("获取井推荐参数失败！");
  //       return;
  //     }
  //     DeployAgainId.value = data.Id;

  //     propertyParam.wellParamSettings.selectedOption = response.OutGraphicFile;
  //     nextTick();

  //     propertyParam.wellParamSettings.boundaryLayer = response.Boundary_Layer;
  //     propertyParam.wellParamSettings.faultLayer = response.Fault_Layer;
  //     propertyParam.wellParamSettings.WellNamePrefix = response.Well_Name;
  //     propertyParam.wellParamSettings.BranchCount = response.Well_Nums;
  //     propertyParam.wellParamSettings.BranchOffset = response.Target_Space;
  //     propertyParam.wellParamSettings.BranchLength = response.Horizon_Length;
  //     propertyParam.wellParamSettings.BranchSpace = response.WellBranchSpace;
  //     propertyParam.wellParamSettings.DeploySide2 = response.DoubleWell;
  //     propertyParam.wellParamSettings.DeploySide1 = response.SingleWell;

  //     propertyParam.wellParamSettings.DeployAgain = true; // 标记二次布井

  //     propertyParam.calcParamSettings.WellsSpace = response.WellSpace;
  //     propertyParam.calcParamSettings.MutationRate = response.MutationRate;
  //     propertyParam.calcParamSettings.Rotations = response.RotationTimes;
  //     propertyParam.calcParamSettings.AngleStart = response.AngularRangeMin;
  //     propertyParam.calcParamSettings.AngleEnd = response.AngularRangeMax;
  //     propertyParam.calcParamSettings.SpecifyAngles = response.IsAngleRange;
  //     // this.calcParamSettings.SpeciaAngles = response.AngleRangeValue; // 角度范围值
  //     propertyParam.calcParamSettings.IgnoreMiniFault = response.IsSmallFracture;
  //     propertyParam.calcParamSettings.MiniFaultLength = response.SmallFractureValue;

  //     // 调用二次布井方法
  //     await handleStartCalc();
  //   } catch (error) {
  //     console.error("获取智能布井计算参数时出错:", error);
  //     $toastMessage.error("获取智能布井计算参数出错了");
  //   }
  // });

  // 计算参数
  emitter.on(EMIT_COMMAND.CALC_PROPERTY, async (data) => {
    const response = await getWellRecommend(data.Id);
    if (!response) {
      $toastMessage.error("获取井推荐参数失败！");
      return;
    }

    DeployAgainId.value = data.Id;

    propertyParam.wellParamSettings.selectedOption = response.Fracture_FileName;
    propertyParam.wellParamSettings.boundaryLayer = data.Boundary_Layer;
    propertyParam.wellParamSettings.faultLayer = data.Fault_Layer;
    propertyParam.wellParamSettings.WellNamePrefix = data.Well_Name;
    propertyParam.wellParamSettings.BranchCount = data.Well_Nums;
    propertyParam.wellParamSettings.BranchOffset = data.Target_Space;
    propertyParam.wellParamSettings.BranchLength = data.Horizon_Length;
    propertyParam.wellParamSettings.BranchSpace = data.WellBranchSpace;
    propertyParam.wellParamSettings.DeploySide2 = data.DoubleWell;
    propertyParam.wellParamSettings.DeploySide1 = data.SingleWell;

    propertyParam.wellParamSettings.DeployAgain = false; // 标记二次布井

    propertyParam.calcParamSettings.WellsSpace = data.WellSpace;
    propertyParam.calcParamSettings.MutationRate = data.MutationRate;
    propertyParam.calcParamSettings.Rotations = data.RotationTimes;
    propertyParam.calcParamSettings.AngleStart = data.AngularRangeMin;
    propertyParam.calcParamSettings.AngleEnd = data.AngularRangeMax;
    propertyParam.calcParamSettings.SpecifyAngles = data.IsAngleRange;
    propertyParam.calcParamSettings.SpeciaAngles = data.AngleRangeValue; // 角度范围值
    propertyParam.calcParamSettings.IgnoreMiniFault = data.IsSmallFracture;
    propertyParam.calcParamSettings.MiniFaultLength = data.SmallFractureValue;
  });
};

onBeforeUnmount(() => {
  emitter.off(EMIT_COMMAND.SELECTED_LAYER);
  emitter.off(EMIT_COMMAND.CALC_PROPERTY);
  handleStopCalc(true);
});

const handleClose = () => {
  showLayer.value = false;
};

// 获取断裂图件
const getFractureFileList = async () => {
  let response = await fractureFileList();

  if (response) {
    fractureFileData.value = response;
  }
};

const onComplete = () => {

};
</script>

<style scoped>
.scrollable-form {
  /* max-height: 900px; */
  min-height: 500px;
  width: 290px;
  height: 100%;
}

.well-param-item {
  height: 25px;
}

.well-param-input {
  width: 140px;
  height: 25px;
}

.button-container {
  display: flex;
  justify-content: flex-end;
  margin-right: 30px;
  margin-bottom: 20px;
}

.other-form-item {
  display: inline-flex;
  flex-direction: row;
  justify-content: flex-start;
  gap: 10px;
}

.other-form-item-nolabel {
  display: inline-flex;
  flex-direction: row;
  padding-left: 65px;
  justify-content: flex-start;
}

.img-layer {
  height: 500px;
  background: #ccc;
  border: 1px solid #333;
  overflow: hidden;
}

.popup-tree {
  height: 500px;
  width: 100%;
}
</style>
