<template>
  <div class="engineering-config h-full flex flex-col bg-white">
    <div class="border-gray-200">
      <div class="px-6 py-4">
        <el-page-header @back="goBack" title="返回">
          <template #content>
            <div class="flex flex-col gap-1">
              <div class="flex items-center gap-3">
                <span class="text-xl font-bold text-gray-900">{{
                  projectName || '未命名工程'
                }}</span>
              </div>
              <span class="text-xs text-gray-500">工程配置</span>
            </div>
          </template>
        </el-page-header>
      </div>

      <div class="px-6 pb-4">
        <div class="w-full">
          <el-steps :active="activeStep" finish-status="success" simple align-center>
            <el-step
              title="1.通道管理"
              :icon="Connection"
              @click="handleStepClick('channel')"
              class="cursor-pointer"
            />
            <el-step
              title="2.设备类别"
              :icon="Collection"
              @click="handleStepClick('category')"
              class="cursor-pointer"
            />
            <el-step
              title="3.设备管理"
              :icon="Monitor"
              @click="handleStepClick('device')"
              class="cursor-pointer"
            />
          </el-steps>
        </div>
        <div class="flex justify-end gap-4 p-t-16">
          <el-button v-if="activeStep > 0" @click="prevStep" :icon="ArrowLeft"
            >上一步</el-button
          >
          <el-button
            v-if="activeStep < 2"
            type="primary"
            @click="nextStep"
            :loading="nextStepLoading"
          >
            下一步<el-icon class="el-icon--right"><ArrowRight /></el-icon>
          </el-button>
          <el-button
            v-if="activeStep === 2"
            type="success"
            @click="handleFinish"
            :icon="Check"
            :loading="loading"
            >保存配置</el-button
          >
        </div>
      </div>
    </div>

    <div class="flex-1 overflow-hidden flex flex-col">
      <div
        class="flex-1 overflow-hidden p-6"
        v-loading="pageLoading"
        loading-text="加载中..."
      >
        <transition name="fade" mode="out-in">
          <keep-alive>
            <component
              :is="currentStepComponent"
              ref="currentComponentRef"
              v-model="currentModel as any"
              v-bind="currentProps"
              @on-load-device-categoty="loadCategoryList"
            />
          </keep-alive>
        </transition>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import {
  Connection,
  Collection,
  Monitor,
  ArrowLeft,
  ArrowRight,
  Check,
} from '@element-plus/icons-vue'
import StepChannel from './components/StepChannel.vue'
import StepDeviceCategory from './components/StepDeviceCategory.vue'
import StepDevice from './components/StepDevice.vue'
import type { IChannelOV } from '@/api/module/channel/index.d'
import type { IDeviceCategoryList, IDeviceOV } from '@/api/module/device/index.d'
import { getChannelList, saveChannel } from '@/api/module/channel'
import { getDeviceList, saveDevice } from '@/api/module/device/index.ts'
import { getDeviceTypeList } from '@/api/module/device/category.ts'
import { isObject } from '@/utils/is.ts'
import { createEngineering } from '@/api/module/engineering'

const router = useRouter()
const route = useRoute()

const projectName = computed(() => route.query.name as string)
const isCreate = computed(() => route.query.type === 'create')

type Step = 'channel' | 'category' | 'device'
const steps: Step[] = ['channel', 'category', 'device']
const currentStep = ref<Step>('channel')
const activeStep = computed(() => steps.indexOf(currentStep.value))
const channels = ref<IChannelOV>({})
const categories = ref<IDeviceCategoryList>({})
const devices = ref<IDeviceOV>({})
const currentComponentRef = ref<any>(null)
const loading = ref(false)

const currentStepComponent = computed(() => {
  switch (currentStep.value) {
    case 'channel':
      return StepChannel
    case 'category':
      return StepDeviceCategory
    case 'device':
      return StepDevice
    default:
      return null
  }
})

const currentModel = computed({
  get: () => {
    switch (currentStep.value) {
      case 'channel':
        return channels.value
      case 'category':
        return categories.value
      case 'device':
        return devices.value
      default:
        return {}
    }
  },
  set: (val: any) => {
    switch (currentStep.value) {
      case 'channel':
        channels.value = val
        break
      case 'category':
        categories.value = val
        break
      case 'device':
        devices.value = val
        break
    }
  },
})

const currentProps = computed(() => {
  if (currentStep.value === 'device') {
    return {
      channels: channels.value,
      categories: categories.value,
    }
  } else if (currentStep.value === 'category') {
    return {
      channels: channels.value,
    }
  }
  return {}
})

const handleStepClick = async (step: Step) => {
  if (currentStep.value === step) return

  if (currentComponentRef.value?.checkBeforeLeave) {
    const canLeave = await currentComponentRef.value.checkBeforeLeave()
    if (!canLeave) return
  }

  currentStep.value = step
}

const goBack = () => {
  router.push('/engineering')
}

const prevStep = async () => {
  const index = steps.indexOf(currentStep.value)
  if (currentStep.value === 'channel') {
    await loadChannelList()
  }
  if (currentComponentRef.value?.checkBeforeLeave) {
    const canLeave = await currentComponentRef.value.checkBeforeLeave()
    if (!canLeave) return
  }
  if (index > 0) {
    currentStep.value = steps[index - 1]
  }
}

const nextStepLoading = ref(false)

const nextStep = async () => {
  nextStepLoading.value = true
  const index = steps.indexOf(currentStep.value)
  if (currentStep.value === 'channel') {
    await saveChannelList()
  }

  if (currentComponentRef.value?.checkBeforeLeave) {
    const canLeave = await currentComponentRef.value.checkBeforeLeave()
    if (!canLeave) {
      nextStepLoading.value = false
      return
    }
  }

  if (index < steps.length - 1) {
    currentStep.value = steps[index + 1]
  }
  nextStepLoading.value = false
}

/*

const nextStep = async () => {
  if (currentComponentRef.value?.checkBeforeLeave) {
    const canLeave = await currentComponentRef.value.checkBeforeLeave()
    if (!canLeave) return
  }

  if (currentStep.value === 'channel') {
    currentStep.value = 'category'
  } else if (currentStep.value === 'category') {
    currentStep.value = 'device'
  }
}
*/

const handleFinish = async () => {
  loading.value = true
  try {
    const resDevice = await saveDeviceList()
    if (resDevice.code !== 0) {
      ElMessage.error('保存设备失败')
      return
    }
    const res = await createEngineering({
      name: projectName.value,
      isCreate: false,
    })
    if (res.code !== 0) {
      ElMessage.error('配置工程失败')
      return
    }
    ElMessage.success('配置完成')
    goBack()
  } finally {
    loading.value = false
  }
}

async function saveDeviceList() {
  const res = await saveDevice({
    projectName: projectName.value,
    ...devices.value,
  })
  if (res.code === 0) {
    // ElMessage.success('保存成功')
  }
  return Promise.resolve(res)
}

async function saveChannelList() {
  const res = await saveChannel({
    projectName: projectName.value,
    ...channels.value,
  })
  if (res.code === 0) {
    ElMessage.success('保存成功')
  }
}

async function loadChannelList() {
  const res = await getChannelList({ projectName: projectName.value })
  if (isObject(res.data)) channels.value = res.data
}
async function loadCategoryList() {
  const res = await getDeviceTypeList({ projectName: projectName.value })
  if (isObject(res.data)) categories.value = res.data
}
async function loadDeviceList() {
  const res = await getDeviceList({ projectName: projectName.value })
  if (isObject(res.data)) devices.value = res.data
}

const pageLoading = ref(true)
onMounted(async () => {
  if (!isCreate.value) {
    await loadChannelList()
    await loadDeviceList()
    await loadCategoryList()
    pageLoading.value = false
  }
})
</script>

<style scoped>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

:deep(.el-page-header__back) {
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  transition: all 0.2s;
}

:deep(.el-page-header__back:hover) {
  background-color: rgba(64, 158, 255, 0.1);
  color: var(--el-color-primary);
}

:deep(.el-page-header__back:active) {
  background-color: rgba(64, 158, 255, 0.2);
  transform: scale(0.95);
}
:deep(.el-steps--simple) {
  padding-left: 16%;
}
</style>
