<script setup lang="ts">
import { getContainerList } from 'apis/container'
import { createCraft, updateCraft } from 'apis/crafts'
import { getSolsList } from 'apis/solution'
import emptyIcon from 'assets/images/empty.svg'
import { FtMessage } from 'libs/message'
import { allPropertiesDefined } from 'libs/utils'
import { cloneDeep } from 'lodash'
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

const props = defineProps({
  sourceData: {
    type: Object,
    default: () => ({}),
  },
})

const emits = defineEmits(['ok', 'cancel'])

const route = useRoute()
const oresId: number = route.query.oreId as unknown as number

const containerList = ref<Container.ContainerItem[]>([])
const solutionList = ref<Solution.SolutionItem[]>([])

const loading = ref(true)
onMounted(async () => {
  containerList.value = (await getContainerList())?.filter(item => item.type === 0)
  solutionList.value = (await getSolsList()).list
  if (props.sourceData) {
    form.value = { ...props.sourceData, stepList: JSON.parse(props.sourceData.steps || '[]') }
    form.value.stepList?.forEach((step: CraftTypes.StepItem) => {
      if (step.params.second) {
        step.params.minutes = Math.floor(step.params.second / 60)
        step.params.seconds = step.params.second % 60
      }
      if (step.params.coolingSecond) {
        step.params.coolingMinutes = Math.floor(step.params.coolingSecond / 60)
        step.params.coolingSeconds = step.params.coolingSecond % 60
      }
    })
  }
  loading.value = false
})

const form = ref<{
  name?: string
  stepList?: CraftTypes.StepItem[]
  steps?: string
  oresId?: number
  id?: number
}>({
  stepList: [],
})
const formRef = ref()

const rules = {
  name: [
    { required: true, trigger: 'blur', message: '请输入工艺名称' },
  ],
}

const okHandle = async () => {
  try {
    const valid = await formRef.value.validate()
    if (!valid) {
      return
    }
    // 找到第一个参数不完整的步骤
    const invalidStepIndex = form.value.stepList?.findIndex(
      (step: any, index) => {
        if (['startHeating', 'shaking'].includes(step.method)) {
          if (step.params.minutes || step.params.seconds) {
            step.params.second = (step.params.minutes || 0) * 60 + (step.params.seconds || 0) || undefined
          }
          if (step.params.coolingMinutes || step.params.coolingSeconds) {
            step.params.coolingSecond = (step.params.coolingMinutes || 0) * 60 + (step.params.coolingSeconds || 0) || undefined
          }
        }
        step.params.description = `${index + 1}.`
        switch (step.method) {
          case 'addLiquid':
            step.params.description = step.params.list.map(item => `试管[${item.tubeNums.length === 16 ? '全部' : item.tubeNums.join(',')}]: ${
              item.solutionList.map(s => `添加${solutionList.value.find(ss => ss.id === s.solutionId)?.name}- ${s.volume}ml-偏移量${s.offset}ml`).join(';')
            }`).join(';')
            break
          case 'startHeating':
            step.params.description = `加热: ${step.params.temperature}度, 保持${step.params.minutes || 0}分${step.params.seconds || 0}秒`
            break
          case 'shaking':
            step.params.description = `摇匀: ${step.params.second}秒`
            break
          case 'takePhoto':
            step.params.description = `拍照`
            break
        }
        return !allPropertiesDefined(step.params, ['minutes', 'seconds', 'description'])
      },

    )
    console.log(form.value)

    if (invalidStepIndex !== -1) {
      FtMessage.error(`步骤${(invalidStepIndex || 0) + 1}: 请填写完整参数`)
      return
    }

    form.value.steps = JSON.stringify(form.value.stepList)
    form.value.oresId = oresId
    if (form.value.id) {
      await updateCraft(form.value)
    }
    else {
      await createCraft(form.value)
    }
    FtMessage.success('保存成功')
    emits('ok')
  }
  catch (error) {
    console.log(error)
  }
}
const cancel = () => {
  emits('cancel')
}

const stepMap: Record<string, CraftTypes.StepItem> = {
  // addLiquid: { name: '加液', method: 'addLiquid', params: { addLiquidList: [{ containerId: undefined, volume: undefined }], description: undefined } },
  startHeating: { name: '加热', method: 'startHeating', params: { temperature: undefined, second: undefined, description: undefined, minutes: undefined, seconds: undefined } },
  shaking: { name: '摇匀', method: 'shaking', params: { second: undefined } },
  takePhoto: { name: '拍照', method: 'takePhoto', params: { } },
}

const addStep = (data: CraftTypes.StepItem) => {
  form.value.stepList?.push(data)
}

const addLiquidForm = ref<any>({
  tubeNums: [],
  solutionList: [
    {
      solutionId: undefined,
      volume: undefined,
      offset: undefined,
    },
  ],
})
const addLiquidRules = {
  tubeNums: [
    { required: true, message: '请选择试管', trigger: 'change' },
  ],
}

const addLiquidFormRef = ref()

const activeTube = ref(Array.from({ length: 16 }).fill(false))

const selectVisible = ref(false)
const checkChange = () => {
  activeTube.value = Array.from({ length: 16 }).fill(selectVisible.value)
  addLiquidForm.value.tubeNums = activeTube.value.map((item, index) => index + 1).filter(item => activeTube.value[item - 1])
  addLiquidFormRef.value.validateField('tubeNums')
}

const mousedownHandle = async (e: Event) => {
  let event
  if ('touches' in e) {
    event = (e.touches as TouchList)[0]
  }
  else {
    event = e
  }
  if (event.target!.classList!.contains('tube-inner')) {
    const num = event.target!.getAttribute('index')
    activeTube.value[Number(num) - 1] = !activeTube.value[Number(num) - 1]
    addLiquidForm.value.tubeNums = activeTube.value.map((item, index) => index + 1).filter(item => activeTube.value[item - 1])
  }
}

const addHandle = async () => {
  try {
    const valid = await addLiquidFormRef.value.validate()
    if (!valid) {
      return
    }
    console.log(addLiquidForm.value)
    // addList.value!.push(addLiquidForm)
    const index = form.value.stepList?.findIndex(item => item.method === 'addLiquid')
    if (index !== -1) {
      form.value.stepList?.[index || 0].params?.list?.push(cloneDeep(addLiquidForm.value))
    }
    else {
      form.value.stepList?.push({
        name: '加液',
        method: 'addLiquid',
        params: { list: [cloneDeep(addLiquidForm.value)] },
      } as CraftTypes.StepItem)
    }
    addLiquidForm.value = {
      tubeNums: [],
      solutionList: [
        {
          solutionId: undefined,
          volume: undefined,
          offset: undefined,
        },
      ],
    }
    activeTube.value = Array.from({ length: 16 }).fill(false)
    selectVisible.value = false
    addLiquidFormRef.value.resetFields()
  }
  catch (error) {
    console.log(error)
  }
}
</script>

<template>
  <FtDialog visible :loading :title="form.id ? '编辑工艺' : '新增工艺'" width="90%" :ok-handle="okHandle" @cancel="cancel">
    <el-form ref="formRef" label-width="auto" :model="form" :rules="rules" class="form-box">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="工艺名称" prop="name">
            <el-input v-model="form.name" placeholder="请输入工艺名称" />
          </el-form-item>
          <el-form-item label="步骤列表">
            <div class="button-content">
              <el-tag v-for="item in stepMap" :key="item" size="large" @click="() => addStep(item)">
                <div style="display: flex;align-items: center;justify-content: space-around;width: 100%;">
                  <el-icon><Plus /></el-icon>
                  <span>  {{ item.name }}</span>
                </div>
              </el-tag>
            </div>
            <el-form ref="addLiquidFormRef" :model="addLiquidForm" :rules="addLiquidRules" label-width="auto" class="liquid-box">
              <p>加液</p>
              <el-form-item label="" prop="tubeNums">
                <el-checkbox v-model="selectVisible" style="margin-right: 10px" @change="checkChange">
                  全选
                </el-checkbox>
                <div class="tube-item" @click.prevent="mousedownHandle" @touch.prevent="mousedownHandle">
                  <span v-for="item in 16" :key="item" class="tube-inner" :class="{ 'tube-inner-active': activeTube[item - 1] }" :index="item" />
                </div>
              </el-form-item>
              <el-row>
                <el-col :span="7" style="text-align: center">
                  溶液
                </el-col>
                <el-col :span="7" style="text-align: center">
                  容量
                </el-col>
                <el-col :span="7" style="text-align: center">
                  偏移量
                </el-col>
              </el-row>
              <div class="solution-list">
                <el-row v-for="(s, index) in addLiquidForm.solutionList" :key="index" :gutter="5" class="solution-item">
                  <el-col :span="7">
                    <el-form-item
                      label=""
                      :prop="`solutionList.${index}.solutionId`"
                      :rules="{
                        required: true,
                        message: '请选择溶液',
                        trigger: 'change',
                      }"
                    >
                      <el-select v-model="s.solutionId" size="small" style="width: 100%" placeholder="溶液">
                        <el-option v-for="item in solutionList" :key="item.id" :label="item.name" :value="item.id" />
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="7">
                    <el-form-item
                      label="" :prop="`solutionList.${index}.volume`" :rules="{
                        required: true,
                        message: '请输入容量',
                        trigger: 'blur',
                      }"
                    >
                      <el-input v-model.number="s.volume" size="small" type="number" style="width: 100%" placeholder="容量">
                        <template #append>
                          ml
                        </template>
                      </el-input>
                    </el-form-item>
                  </el-col>
                  <el-col :span="7">
                    <el-form-item
                      label="" :prop="`solutionList.${index}.offset`" :rules="{
                        required: true,
                        message: '请输入偏移量',
                        trigger: 'blur',
                      }"
                    >
                      <el-input v-model.number="s.offset" size="small" type="number" style="width: 100%" placeholder="偏移量">
                        <template #append>
                          ml
                        </template>
                      </el-input>
                    </el-form-item>
                  </el-col>
                  <el-col :span="3" class="icon-box">
                    <el-icon v-if="addLiquidForm.solutionList.length > 1" color="red" @click="addLiquidForm.solutionList.splice(index, 1)">
                      <RemoveFilled />
                    </el-icon>
                    <el-icon
                      v-if="index === addLiquidForm.solutionList.length - 1" color="green" @click="addLiquidForm.solutionList.push({ solutionId: undefined,
                                                                                                                                     volume: undefined,
                                                                                                                                     offset: undefined })"
                    >
                      <CirclePlusFilled />
                    </el-icon>
                  </el-col>
                </el-row>
              </div>

              <el-form-item>
                <div style="width: 100%;display: flex;justify-content: center">
                  <ft-button type="primary" @click="addHandle">
                    添加
                  </ft-button>
                </div>
              </el-form-item>
            </el-form>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <div v-if="form.stepList?.length" class="step-box">
            <div v-for="(item, index) in form.stepList" :key="index" class="step-item">
              <el-form-item :label="`${index + 1}: ${item.name}`">
                <div v-if="item.method === 'addLiquid'" class="list-box">
                  <div v-for="(liquid, liquidIndex) in item.params?.list || []" :key="liquidIndex">
                    <span>试管: {{ liquid.tubeNums.length === 16 ? '全部' : liquid.tubeNums.join(',') }} </span>
                    <div v-for="(s, sIndex) in liquid.solutionList" :key="sIndex">
                      <span>添加</span>
                      <span>{{ solutionList.find(solution => solution.id === s.solutionId)?.name }}</span>
                      <span>{{ s.volume }}</span>
                      <span>ml-</span>
                      <span>偏移量</span>
                      <span>{{ s.offset }}</span>
                      <span>ml</span>
                    </div>
                  </div>
                </div>
                <div v-else-if="['startHeating'].includes(item.method)">
                  <el-input v-model.number="item.params.temperature" type="number" size="small" placeholder="加热温度">
                    <template #append>
                      ℃
                    </template>
                  </el-input>
                  <br>
                  <div>
                    <span>保持时间</span>
                    <el-select v-model="item.params.minutes" style="width: 70px" clearable size="small" placeholder="分钟">
                      <el-option v-for="i in 60" :key="i" :label="i" :value="i" />
                    </el-select>
                    <span class="unit-text">分</span>
                    <el-select v-model="item.params.seconds" style="width: 70px" clearable size="small" placeholder="秒">
                      <el-option v-for="i in 60" :key="i" :label="i" :value="i" />
                    </el-select>
                    <span class="unit-text">秒</span>
                  </div>
                  <div>
                    <span>冷却时间</span>
                    <el-select v-model="item.params.coolingMinutes" style="width: 70px" clearable size="small" placeholder="分钟">
                      <el-option v-for="i in 60" :key="i" :label="i" :value="i" />
                    </el-select>
                    <span class="unit-text">分</span>
                    <el-select v-model="item.params.coolingSeconds" style="width: 70px" clearable size="small" placeholder="秒">
                      <el-option v-for="i in 60" :key="i" :label="i" :value="i" />
                    </el-select>
                    <span class="unit-text">秒</span>
                  </div>
                </div>
                <template v-else-if="['shaking'].includes(item.method)">
                  <el-select v-model="item.params.minutes" style="width: 70px" clearable size="small" placeholder="请选择">
                    <el-option v-for="i in 60" :key="i" :label="i" :value="i" />
                  </el-select>
                  <span class="unit-text">分</span>
                  <el-select v-model="item.params.seconds" style="width: 70px" clearable size="small" placeholder="请选择">
                    <el-option v-for="i in 60" :key="i" :label="i" :value="i" />
                  </el-select>
                  <span class="unit-text">秒</span>
                </template>
                <el-icon style="margin-left: auto;" @click="() => form.stepList?.splice(index, 1)">
                  <Close />
                </el-icon>
              </el-form-item>
            </div>
          </div>
          <div v-else class="empty-box">
            <img :src="emptyIcon" alt="">
            <span>暂无步骤</span>
          </div>
        </el-col>
      </el-row>
    </el-form>
  </FtDialog>
</template>

<style scoped lang="scss">
.form-box {
  height: 70vh;
  .el-row {
    height: 100%;
    .el-col:first-child {
      border-right: 1px solid #eee;
    }
    .el-col {
      height: 100%;
      .step-box {
        height: 100%;
        overflow: auto;
      }
    }
  }
}
.button-content {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(2, 1fr); /* 创建3列等宽轨道 */
  grid-template-rows: repeat(2, auto);   /* 创建2行自动高度 */
  gap: 10px;
  margin-bottom: 10px;
}
:deep(.el-tag__content) {
  width: 100%;
}
.empty-box {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #ccc;
  img {
    margin-bottom: 10px;
  }
}
.step-item {
  .el-form-item {
    background: rgba(82, 148, 215, 0.06);
    padding: 5px;
    margin-bottom: 10px;
    :deep(.el-form-item__label) {
      height: 25px;
      line-height: 25px;
    }
    :deep(.el-form-item__content)  {
      width: 100%;
      display: flex;
      align-items: center;

      .el-input, .el-select {
        width: 120px;
        margin: 0 5px;
      }
      .list-box {
        width: 90%;
        height: 100%;
        .list-item {
          display: flex;
          align-items: center;
          padding-bottom: 10px;
          .el-icon {
            cursor: pointer;
            font-size: 20px;
            margin-left: 10px;
          }
        }
      }
    }
  }
}
.unit-text {
  font-size: 12px;
  line-height: 25px;
}

.tube-item {
  padding: 5px;
  background: #384D5D;
  border-radius: 10px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  grid-gap: 5px;
  position: relative;
  .tube-disable {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background: rgba(255,255,255,0.9);
    border-radius: 9px;
  }
  .tube-inner {
    display: inline-block;
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: #fff;
    margin: 2px;
    transition: background 0.5s;
  }
  .tube-inner-active {
    background: #26D574;
  }
}

.liquid-box {
  background: #ecf5ff;
  padding: 0 10px;
  p {
    text-align: center;
    color: #1989fa;
  }
}
.solution-list {
  max-height: 100px;
  overflow: hidden;
  overflow-y: auto;
}
.solution-item {
  margin-bottom: 10px;

}
.el-form-item .el-form-item {
  margin-bottom: 10px;
}
.icon-box {
  display: flex;
  margin-top: 4px;
  justify-content: space-between;
  .el-icon {
    font-size: 18px;
    line-height: 100%;
  }
}
</style>
