<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"
          @onSelectCraft="(craftData)=>{onSelectCraft(item, craftData)}"
        ></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 }"
          
        ></div><!--@click="onChooseTube(tubeItem, index)"-->
      </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" @click="taskNameVisible = true"
          >开始实验</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" @click="onCraftStart"
          >执行工艺</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" @click="onMoveToSpecial"
          >移至特殊</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" v-if="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" @selectedCraft="onHandleSelectedCraft"></CraftList>
    </OverlayModal>

	<!--实验名称-->
	<OverlayModal :visible="taskNameVisible">
		<div class="task_name">
			<div class="task_title">
				开始新实验
			</div>
			<div class="task_name_content">
				实验名称：<input v-model="taskName" class="task_input">
			</div>

			<br/>
			<footer class="task_button">
				<button class="btn-dark px-2 py-1 min-w-20" @click="onSave">保存</button>
				<button class="px-4 py-1 min-w-20" @click="onCancel">取消</button>
			</footer>
		</div>
	</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 { saveTaskName } from '@/services/task/task';
import {
  CmdDescMap,
  taskCmd,
  type OperationCmd,
} from "@/services/globalCmd/globalCmd";
import { craftStart } from "@/services/ore/oreManage";
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";
const taskName = ref('')
onMounted(() => {
  //6个加热区数据
  heatList.value = settingStore.heatAreaConfig.map((item:any) => {
    //添加一个字段，默认为未选中
    item.isSelect = false;
    return item;
  });
  //设备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",
        });
      }
    }
  });
  wsClient.connect();

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

//选中的托盘
const selectedTrayList = ref<any>([]);
const selectedTrayObj: any = {};
const onSelectedTray = (heatAreaItem: any, type:string) => {
  heatList.value[heatAreaItem.index] = heatAreaItem;
	//取消选中，已经存在selectedTrayList中
  let ids = selectedTrayList.value.map((tube:any) =>tube.id)
  if(type == 'isClick'){//点击加热区
    if(ids.includes(heatAreaItem.id)){
      heatAreaItem.isSelect = false;
      selectedTrayList.value = selectedTrayList.value.filter((selectedItem:any) => selectedItem.id != heatAreaItem.id)
    }else{
      heatAreaItem.isSelect = true;
      selectedTrayList.value.push(heatAreaItem)
    }
  }else{
    heatAreaItem.isSelect = true;
  }
  heatList.value.forEach((item:any) => {
    if(item.id == heatAreaItem.id){
      item = heatAreaItem
    }
  })
 
	// selectedTrayList.value = Object.values(selectedTrayObj);
  
};

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

//加热区选择的工艺
const onSelectCraft = (item:any, craftInfo:any) => {
  item.isSelect = true;
  item.craftInfo = craftInfo
  onSelectedTray(item,'isMove')
  console.log('加热区选择的工艺===', item,craftInfo)
}
//开始执行工艺
const onCraftStart = () => {
  if (!selectedTrayList.value.length) {
    ElMessage.error("请选择目标加热区");
	  return;
  }
  //判断是否选择了工艺
  
  //可能会选择多个加热区执行工艺， 批量发送指令
  selectedTrayList.value.forEach((item:any) => {
    const params = {
      craftId: item.craftInfo.id,
      heatId: item.id
    }
    craftStart(params).then(res => {
      ElMessage.success('执行工艺的指令已发送')
    })
  })

}

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 onHandleSelectedCraft = (craftData:any) => {
	changeVisible();	
}

const onAddSolution = (data: any) => {
  let ids = data.map((item: any) => item.id);
  //批量发送加液指令
  data.forEach((item:any) => {
    onSendCmd('injectFluid', item)
  });
  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、判断选择的加热区是否已经有了试管架, 加热区是否有试管是通过设备上报的数据获取的。此处为mock的数据。 TODO
  let heatAearStatus: any = statusStore.status?.heater ? statusStore.status?.heater[selectedDataItem.index].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));
      selectedDataItem.tubeList = JSON.parse(JSON.stringify(tubeList));
      //标注该加热区是选中状态
      item.isSelect = true;
    }
  });
  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];
	//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, 'isMove')
}

//移至特殊区域
const onMoveToSpecial = () => {
	//检查是否设置了异常区域
	const systemSetting = settingStore.systemSetting
	let specialArea:any = {}
	if(systemSetting && systemSetting.length){
		systemSetting.forEach(item => {
			if(item.code == "sys_setting_abnormal_area"){
				specialArea = item;
			}
		})

		if(!specialArea.id){
			ElMessage.error('未设置异常区域，请在系统配置中设置')
			return;
		}

		//是否选择了加热区的试管架
		if (!selectedTrayList.value.length) {
			ElMessage.error("请选择试管架");
			return;
		}
		//2、只能选择一个试管架/加热区
		if (selectedTrayList.value.length != 1) {
			ElMessage.error("只能选择一个试管架");
			return;
		}
		let selectedDataItem = selectedTrayList.value[0];
		selectedDataItem.isSelect = false
		onSelectedTray(selectedDataItem, 'isMove')

		const params = {
			areaId:selectedDataItem.id
		}
		onSendCmd('moveToActionArea', params)
	}
}

//开始实验
const taskNameVisible = ref(false)
const onSave = ()=> {
	const params = {
		name: taskName.value
	}
	saveTaskName(params).then(res => {
		if(res.success){
			ElMessage.success('保存成功')
			onCancel()
		}else{
			ElMessage.error(res.msg)
		}
	})
}


const onCancel = ()=> {
	taskNameVisible.value = false;
}

//开门
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
			}
		})
	})
	// 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: 13rem;
  background: #384d5d;
  opacity: 1;
  margin-top: 0.5rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
  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);
  }
}

.task_name{
	height:17.25rem;
	width: 27.5rem;
	background: #ffffff;

	.task_title{
		font-size: 1.25rem;
		color: #40474E;
		margin-left: 1.25rem;
		margin-top: 1.875rem
	}

	.task_name_content{
		margin-top:1.875rem;
		margin-left: 1.5rem;
		font-size: 1.25rem;
		color: #40474E;
		.task_input{
			border: 1px solid #dcdcdc;
			border-radius: 8px;
			height: 3rem;
		}
	}

	.task_button{
		display: flex;
		justify-content: center;
	}
}
</style>
