<template>
  <el-scrollbar height="calc(100vh - 130px)" class="config">
    <ViewTitle :title="t('pageVariables')">
      <template #right>
        <el-button type="text" @click="addPageVariables"
          ><el-icon class="cursor-pointer"> <Plus /> </el-icon
        ></el-button>
      </template>
    </ViewTitle>
    <div class="p-10px">
      <!-- 变量表格 -->
      <el-table :data="pageVariables || []">
        <el-table-column :label="t('variableName')">
          <template #default="{ row }">
            <el-input
              spellcheck="false"
              v-model="row.name"
              placeholder="请输入"
              @input="(val) => handleVariableNameInput(row, val)"
            />
          </template>
        </el-table-column>
        <el-table-column :label="t('variableType')">
          <template #default="{ row }">
            <el-select v-model="row.type" placeholder="请选择">
              <el-option
                v-for="type in variableType"
                :key="type.value"
                :label="type.label"
                :value="type.value"
              />
            </el-select>
          </template>
        </el-table-column>
        <el-table-column :label="t('initialValue')">
          <template #default="{ row }">
            <el-input spellcheck="false" v-model="row.value" placeholder="请输入" />
          </template>
        </el-table-column>
        <el-table-column width="40">
          <template #default="{ row }">
            <el-icon
              class="cursor-pointer"
              @click="handleVariablesRemove(pageVariables || [], row, 'page')"
            >
              <Delete />
            </el-icon>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <ViewTitle :title="t('globalVariables')">
      <template #right>
        <el-button type="text" @click="addVariableGroup"
          ><el-icon class="cursor-pointer"> <Plus /> </el-icon
        ></el-button>
      </template>
    </ViewTitle>
    <el-form label-position="top">
      <el-collapse v-for="item in globalVariables" :key="item.id" v-model="activeNames">
        <el-collapse-item :name="item.id">
          <template #title>
            <div class="collapse-title">
              <el-icon class="arrow" :class="{ active: activeNames.includes(item.id) }">
                <ArrowRight />
              </el-icon>

              <span class="title-text mr-12px flex items-center">
                <el-input
                  v-model="item.name"
                  placeholder="请输入组名"
                  size="small"
                  class="mt-10px mb-10px"
                />
              </span>

              <el-icon class="mr-10px" @click.stop="addVariables(item.variables)">
                <Plus />
              </el-icon>
              <el-icon @click.stop="removeVariables(item)">
                <Delete />
              </el-icon>
            </div>
          </template>
          <div class="p-10px">
            <!-- 变量表格 -->
            <el-table :data="item.variables">
              <el-table-column :label="t('variableName')">
                <template #default="{ row }">
                  <el-input
                    spellcheck="false"
                    v-model="row.name"
                    placeholder="请输入"
                    @input="(val) => handleVariableNameInput(row, val)"
                  />
                </template>
              </el-table-column>
              <el-table-column :label="t('variableType')">
                <template #default="{ row }">
                  <el-select v-model="row.type" placeholder="请选择">
                    <el-option
                      v-for="type in variableType"
                      :key="type.value"
                      :label="type.label"
                      :value="type.value"
                    />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column :label="t('initialValue')">
                <template #default="{ row }">
                  <el-input spellcheck="false" v-model="row.value" placeholder="请输入" />
                </template>
              </el-table-column>
              <el-table-column width="40">
                <template #default="{ row }">
                  <el-icon
                    class="cursor-pointer"
                    @click="handleVariablesRemove(item.variables, row, 'global')"
                  >
                    <Delete />
                  </el-icon>
                </template>
              </el-table-column>
            </el-table>
          </div>
        </el-collapse-item>
      </el-collapse>
      <el-empty v-if="globalVariables.length === 0" description="暂无全局变量" />
    </el-form>
  </el-scrollbar>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { Variable, VariableGroup } from '@/types/variables'
import type { BaseWidget } from '@/types/baseWidget'
import { ArrowRight, Plus, Delete } from '@element-plus/icons-vue'
import { ElMessageBox } from 'element-plus'
import { variableType } from '@/constants'
import { v4 } from 'uuid'
import { useI18n } from 'vue-i18n'
import { useProjectStore } from '@/store/modules/project'
import { findVariableUsages } from '@/utils/variableBinding'

interface Emits {
  (e: 'update:variables', val: VariableGroup[]): void
  (e: 'update:pageVariables', val: VariableGroup[]): void
}
const emit = defineEmits<Emits>()
const props = defineProps<{
  variables?: VariableGroup[]
  pageVariables?: Variable[]
}>()

const { t } = useI18n()
const projectStore = useProjectStore()

const globalVariables = computed({
  get() {
    return props.variables || []
  },
  set(val: VariableGroup[]) {
    emit('update:variables', val)
  }
})

const activeNames = ref<string[]>(['page_variables'])

const normalizeCVariableName = (value: string) => {
  const validChars = value.replace(/[^a-zA-Z0-9_]/g, '')
  return validChars.replace(/^[0-9]+/, '')
}

const handleVariableNameInput = (row: Variable, value: string) => {
  row.name = normalizeCVariableName(value)
}

const addVariables = (variables) => {
  variables.push({
    id: v4(),
    name: `var_${variables.length + 1}`,
    value: '',
    type: 'char'
  })
}

const walkWidgets = (widgets: BaseWidget[] = [], callback: (widget: BaseWidget) => void) => {
  widgets.forEach((widget) => {
    callback(widget)
    walkWidgets(widget.children || [], callback)
  })
}

/**
 * 添加页面变量
 */
const addPageVariables = () => {
  // todo: 打开弹窗，列出当前页面全部控件，然后根据控件属性选择变量
  // 选择属性后会自动绑定属性的变量类型，初始值使用属性的当前值
  props.pageVariables?.push({
    id: v4(),
    name: '',
    value: '',
    type: 'char'
  })
}

/**
 * 删除变量操作
 * @variables 变量列表
 * @varItem 变量项
 * @scope 作用域（全局或页面）
 * @description 该函数用于处理变量的删除操作。根据作用域（全局或页面），它会从相应的变量列表中删除指定的变量项，并确保在
 */
const handleVariablesRemove = (
  variables: Variable[],
  varItem: Variable,
  scope: 'global' | 'page'
) => {
  const deleteVariable = () => {
    const index = variables.findIndex((item) => item.id === varItem.id)
    if (index !== -1) {
      variables.splice(index, 1)
    }
  }

  const pageChildren = projectStore.activePage?.children || []
  const usageCount = findVariableUsages(varItem.id, pageChildren).length

  if (usageCount === 0) {
    deleteVariable()
    return
  }

  ElMessageBox.confirm(
    `当前变量已被 ${usageCount} 处${scope === 'global' ? '控件属性' : '页面控件属性'}使用，删除后相关绑定将失效，是否继续删除？`,
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(() => {
    deleteVariable()
  })
}

/**
 * 删除变量组操作
 * @param variables
 */
const removeVariables = (variables) => {
  ElMessageBox.confirm('确定删除变量组？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const index = globalVariables.value.findIndex((item) => item.id === variables.id)
    if (index !== -1) {
      globalVariables.value.splice(index, 1)
    }
  })
}

/**
 * 添加变量组操作
 * @description 该函数用于添加一个新的变量组。它会生成一个唯一的ID，并将一个新的变量组对象添加到全局变量列表中。同时，它还会将新添加的变量组的ID添加到activeNames数组中，以确保新组在UI中展开。
 */
const addVariableGroup = () => {
  const id = v4()
  globalVariables.value.push({
    id,
    name: `vargroup_${globalVariables.value.length + 1}`,
    variables: []
  })
  activeNames.value.push(id)
}
</script>

<style lang="less" scoped>
:deep(.el-form-item) {
  margin-bottom: 5px;
}
:deep(.el-collapse-item__header) {
  padding-right: 0px;
}
:deep(.el-collapse-item__arrow) {
  display: none;
}
.collapse-title {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0 12px;
}

.arrow {
  margin-right: 8px;
  transition: transform 0.2s;
}

.arrow.active {
  transform: rotate(90deg);
}

.title-text {
  flex: 1;
  font-weight: 500;
}
::v-deep(.el-collapse-item__content) {
  padding-bottom: 0;
}
</style>
