<template>
  <div class="graphite_home component-page overflow-auto" id="heatArea">
    <div class="heat_area">
      <div v-for="(item, index) in heatList" :key="item.id">
        <HeatPosition
          :heatInfo="{ ...item, index }"
          :tubeIndex="index + 1"
          @onSelectedTray="onSelectedTray"
		  @onSetHeatAreaTemp = "onSetHeatAreaTemp"
        ></HeatPosition>
      </div>
      <!--执行中状态的遮罩层-->
    </div>
    <!--拍照区-->
    <div class="picture_area">
      <!--加液区和拍照区可切换-->
      <div style="display: flex; justify-content: center; align-items: center">
		<div style="font-size: 1rem; margin-left: 0.3rem">加液区</div>
        <van-switch
          v-model="switchModule"
          size="1rem"
          active-color="#ee0a24"
          inactive-color="green"
        />
        <div style="font-size: 1rem; margin-left: 0.3rem">拍照区</div>
      </div>

      <TakePickture v-if="switchModule"></TakePickture>
      <div v-else class="home_tube">
        <div
          class="inner-circle"
          v-for="(tubeItem, index) in tubeList"
          :key="index"
          :style="{ background: tubeItem.color }"
          @click="onChooseTube(tubeItem, index)"
        ></div>
      </div>
      <!--操作区-->
      <div class="graphite_btn_container">
        <van-button size="large" class="btn_size op_open_door" @click="onOPen"
          >开门</van-button
        >
        <van-button size="large" class="btn_size op_start_task"
          >开始实验</van-button
        >
        <van-button size="large" class="btn_size op_stop_task"
          >结束实验</van-button
        >
        <van-button
          size="large"
          class="btn_size op_select_craft"
          @click="onChooseCaft"
          >选择工艺</van-button
        >
        <van-button size="large" class="btn_size op_exec_craft"
          >执行工艺</van-button
        >
        <van-button
          size="large"
          class="btn_size op_add_liquid"
          @click="onAddLiquid"
          >添加溶液</van-button
        >
        <van-button size="large" class="btn_size op_shake_up">摇匀</van-button>
        <van-button
          size="large"
          class="btn_size op_move_heat"
          @click="onMoveToHeat"
          >移至加热</van-button
        >
        <van-button size="large" class="btn_size op_move_act" @click="onMoveToOperationArea"
          >移至加液</van-button
        >
        <van-button size="large" class="btn_size op_move_exception"
          >移至特殊</van-button
        >
        <van-button size="large" class="btn_size op_start_heat" @click="onStartHeat"
          >开始加热</van-button
        >
        <van-button size="large" class="btn_size op_up_tray"
          >抬起托盘</van-button
        >
      </div>
    </div>
    <van-overlay :show="liquidVisible" style="z-index: 9999">
      <div class="liquid">
        <div class="addLiquid">
          <AddLiquid
            @cancel="liquidVisible = false"
            @onAddSolution="onAddSolution"
          ></AddLiquid>
        </div>
      </div>
    </van-overlay>
    <!--选择工艺-->
    <OverlayModal :visible="craftVisible">
      <CraftList @changeVisible="changeVisible"></CraftList>
    </OverlayModal>
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted, onUnmounted, watch } from "vue";
//@ts-ignore
import { ElMessage } from "element-plus";
import { createWebSocket, sharedWsUrl } from "@/services/socket";
import { HeatPosition, TakePickture, AddLiquid } from "./components";
import OverlayModal from "@/components/OverlayModal.vue";
import CraftList from "@/views/graphite/components/CraftList.vue";
import { graphiteMock } from "./components/mock";
import { useStatusStore } from "@/stores/status";
import {
  CmdDescMap,
  taskCmd,
  type OperationCmd,
} from "@/services/globalCmd/globalCmd";
import { getTxnRecord } from "@/services/txn";
import { useSettingStore } from "@/stores/setting";

const settingStore = useSettingStore();

//设备的全局状态
const statusStore = useStatusStore();
const heatList: any = ref([]);
const craftVisible = ref(false);
const switchModule = ref(false);
let tubeList = reactive<any>([]);
const selectedColor = "#4F85FB";
const emptyColor = "#FFFFFF";
const defaultColor = "#189952";
onMounted(() => {
  //6个加热区数据
  heatList.value = settingStore.heatAreaConfig;
  //设备16个试管的基础数据
  tubeBaseConfig();
  //连接socket
  const wsClient = createWebSocket(sharedWsUrl);
  const subscription = wsClient.dataOb.subscribe((data) => {
    if (data.type === "cmd") {
      const cmdInfo = getTxnRecord(data.data.commandId, "task");
      if (cmdInfo) {
        const cmdName = CmdDescMap[cmdInfo.command];
        const result = data.data.success
          ? "执行完毕"
          : `执行失败 ${data.data.message}`;
        ElMessage({
          message: `${cmdName} ${result}`,
          type: data.data.success ? "success" : "error",
        });
      }
    } else if (data.type === "status") {
      statusStore.setStatus(data.data);
    } else if (data.type === "warn") {
      ElMessage({
        message: data.data.message,
        type: "warning",
      });
    }
  });
  wsClient.connect();

  onUnmounted(() => {
    subscription.unsubscribe();
  });
});

//选择的托盘
const selectedTrayList = ref<any>([]);
const selectedTrayObj: any = {};
const onSelectedTray = (data: any) => {
	console.log("data==操作加热区：=", data);
	if (!data.isSelect) {
		delete selectedTrayObj[data.id];
	} else {
		selectedTrayObj[data.id] = data;
	}
	selectedTrayList.value = Object.values(selectedTrayObj);
  
};

//设置加热区温度
const onSetHeatAreaTemp = (dataInfo:any) => {
	selectedTrayObj[dataInfo.id] = dataInfo;
	selectedTrayList.value = Object.values(selectedTrayObj);
}

const tubeBaseConfig = () => {
  //默认为16个
  for (let i = 0; i < 16; i++) {
    tubeList.push({
      id: i + 1,
      color: "rgb(212, 212, 212)",
    });
  }
};

//添加溶液
const liquidVisible = ref(false);
const onAddLiquid = () => {
  //检查加液区是否有试管。但是现在没有这个状态，暂时不考虑。
  liquidVisible.value = true;
};

const onAddSolution = (data: any) => {
  let ids = data.map((item: any) => item.id);
  tubeList.forEach((item: any) => {
    if (ids.includes(item.id)) {
      item.default = defaultColor;
      item.color = defaultColor;
      item.isSelected = true;
    }
  });
};

const changeVisible = () => {
  craftVisible.value = false;
};

//选择工艺
const onChooseCaft = () => {
  craftVisible.value = true;
};

const onChooseTube = (tubeItem: any, index: any) => {
  if (!tubeItem.id) return;
  //@ts-ignore
  let list = [...tubeList];
  for (let i = 0; i < list.length; i++) {
    let item = list[i];
    if (index == i) {
      item.color = selectedColor;
      item.isSelected = true;
    } else {
      item.color = item.default ? item.default : emptyColor;
      item.isSelected = false;
    }
  }
  tubeList = [...list];
};

//移至加热
const onMoveToHeat = () => {
  //1、是否选择了加热区
  if (!selectedTrayList.value.length) {
    ElMessage.error("请选择目标加热区");
	return;
  }
  //2、只能选择一个加热区
  if (selectedTrayList.value.length != 1) {
    ElMessage.error("只能选择一个加热区");
    return;
  }
 
  let selectedDataItem = selectedTrayList.value[0];
  //2、判断选择的加热区是否已经有了试管架
  let heatAearStatus: any = statusStore.status?.trayStatus || graphiteMock.heatAreaStatus;
  if (!heatAearStatus[selectedDataItem.index]) {
    ElMessage.error("选择的加热区已有试管架，重新选择加热区");
    return;
  }

  //调用移至加热接口
  const params = {
    areaId: selectedDataItem.id,
  };
  const command: OperationCmd = "moveToHeatArea";
  taskCmd({ command, params }).then((res) => {
    if (res.success) {
      ElMessage.success("指令已发送，请稍等");
    } else {
      ElMessage.error(res.msg);
    }
  });

  //指令完成成更新UI
  let list = [...heatList.value];
  list.forEach((item: any) => {
    if (item.id == selectedDataItem.id) {
      item.tubeList = JSON.parse(JSON.stringify(tubeList));
	  
	  selectedTrayObj[item.id] = item;
	  selectedTrayList.value = Object.values(selectedTrayObj);
    }
  });
  tubeList.forEach((item:any) => {
	item.color = '';
	item.default = ''
  });
  heatList.value = [...list];
};

//移至加液区(操作区)
const onMoveToOperationArea = () => {
	//1、判断加液区是否有试管架(暂时获取不到这个状态)
	//1、是否选择了试管架/加热区
	if (!selectedTrayList.value.length) {
		ElMessage.error("请选择试管架");
		return;
	}
	//2、只能选择一个试管架/加热区
	if (selectedTrayList.value.length != 1) {
		ElMessage.error("只能选择一个试管架");
		return;
	}
	let selectedDataItem = selectedTrayList.value[0];
	selectedDataItem.isSelect = false
	//3、选择的加热区有没有试管架
	if(!selectedDataItem.tubeList || !selectedDataItem.tubeList.length){
		ElMessage.error("选择的加热区没有试管架");
		return;
	}

	//4、发送移至加液区指令
	const params = {
		areaId: selectedDataItem.id
	}
	onSendCmd('moveToActionArea', params)
	//更新UI
	heatList.value.forEach((item:any) => {
		if(item.id == selectedDataItem.id){
			tubeList  = [...item.tubeList]
			item.tubeList = null;
			
		}
	})
	onSelectedTray(selectedDataItem)
}


//开门
const onOPen = () => {
  const params = {};
  const command: OperationCmd = "openDoor";
  taskCmd({ command, params }).then((res) => {
    if (res.success) {
      ElMessage.success("指令已发送，请稍等");
    } else {
      ElMessage.error(res.msg);
    }
  });
};

//开始加热
const onStartHeat = () => {
	//选择的加热区
	if (!selectedTrayList.value.length) {
		ElMessage.error("请选择目标加热区");
		return;
	}
	//判断选中的加热区是否有试管架
	let existTubeRack = true;
	//加热区是否设置了加热温度
	let hasSetTemp = true;
	selectedTrayList.value.forEach((item:any) => {
		let tubeList = item.tubeList;
		if(!tubeList || !tubeList.length){
			
			existTubeRack = false;
		}
		if(!item.temperature){
			hasSetTemp = false;
		}
	})

	if(!existTubeRack){
		ElMessage.error("选择的加热区未放置试管架，请重新选择")
		return;
	}
	if(!hasSetTemp){
		ElMessage.error("选择的加热区未设置温度，请设置温度")
		return;
	}

	//后台批量发送指令

	const cmdList:any = []
	selectedTrayList.value.forEach((heatArea:any) => {
		cmdList.push({
			command:'startHeat',
			params:{
				areaId : heatArea.id
			}
		})
	})
	console.log('cmdList---', cmdList)
	onSendCmd("startHeat", cmdList)
}

const onSendCmd = (command:OperationCmd,params:any)=> {
	//发送加热指令
	taskCmd({ command, params }).then((res) => {
		if (res.success) {
			ElMessage.success("指令已发送，请稍等");
		} else {
			ElMessage.error(res.msg);
		}
	});
}
</script>
<style lang="scss" scoped>
@use "@/assets/style/mixin.scss" as *;

.graphite_home {
  background: #f6f6f6;
  display: flex;
  gap: 1rem;
  // @media (min-width: $md) {
  flex-direction: column;
  align-items: stretch;
  // }
  .picture_area {
    display: flex;
    flex-direction: column-reverse;
  }
  @media (min-width: $lg) {
    flex-direction: row;
    align-items: start;
    .picture_area {
      display: flex;
      flex-direction: column;
      height: 47.5rem;
    }
  }
}
.heat_area {
  margin: 5px 0;

  background: #ffffff;
  border-radius: 20px;

  column-gap: 8px;
  row-gap: 10px;
  padding: 1.5rem 0.5rem;
  min-width: 600px;
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  > * {
    justify-self: center;
    align-self: center;
  }

  @media (min-width: $md) {
    column-gap: 12px;
    row-gap: 20px;
    height: 47.5rem;
  }

  @media (min-width: $xl) {
    padding: 4.5rem 1rem;
  }

  .craft_executing_modal {
    position: absolute;
    width: 10.5rem;
    height: 18rem;
    background: rgb(230, 230, 230);
    opacity: 0.5;
    z-index: 9999;
  }
}

.picture_area {
  display: flex;
  flex-direction: column;
  margin: 5px;
  // margin-left: 1.25rem;
  background: #ffffff;
  border-radius: 20px;
  padding: 0 1.5rem;
  @media (min-width: $lg) {
    flex: 1 1 180px;
  }
  @media (min-width: $xl) {
    flex: 0 0 auto;
    width: 27rem;
  }

  .graphite_btn_container {
    margin: 2rem 0;
    gap: 0.625rem;
    display: grid;
    @media (max-width: calc($md - 0.1px)) {
      grid-template-columns: repeat(2, 1fr);
      .op_open_door {
        grid-column: 1/-1;
      }
      .op_up_tray {
        grid-column: 1/-1;
      }
    }
    @media (min-width: $md) and (max-width: calc($lg - 0.1px)) {
      grid-template-columns: repeat(6, 1fr);
      > * {
        grid-column: span 3;
      }
      .op_open_door {
        grid-column: 1/-1;
      }
      .op_move_heat {
        grid-column: span 2;
      }
      .op_move_act {
        grid-column: span 2;
      }
      .op_move_exception {
        grid-column: span 2;
      }
    }
    @media (min-width: $lg) and (max-width: calc($xl - 0.1px)) {
      grid-template-columns: repeat(2, 1fr);
      .op_open_door {
        grid-column: 1/-1;
      }
      .op_up_tray {
        grid-column: 1/-1;
      }
    }
    @media (min-width: $xl) {
      grid-template-columns: repeat(6, 1fr);
      > * {
        grid-column: span 3;
      }
      .op_open_door {
        grid-column: 1/-1;
      }
      .op_move_heat {
        grid-column: span 2;
      }
      .op_move_act {
        grid-column: span 2;
      }
      .op_move_exception {
        grid-column: span 2;
      }
    }
  }
}

.btn_size {
  height: 2.75rem;
  color: #1989fa;
  border: 1px solid #1989fa;
  font-size: 1.25rem;
}

.liquid {
  display: flex;
  justify-content: center;
  width: 100%;
  height: 100%;
  align-items: center;
  .addLiquid {
    width: 70.375rem;
    height: 52rem;
    background: #ffffff;
  }
}

.home_tube {
  height: 12rem;
  background: #384d5d;
  opacity: 1;
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-left: 0.4rem;
  padding-top: 0.2rem;
  border-radius: 1.5rem;
  .inner-circle {
    border-radius: 50%;
    width: 2.5rem;
    height: 2.5rem;
    background-color: rgb(212, 212, 212);
  }
}
</style>
