<template>
  <el-row :gutter="12" align="middle">
    <el-col :span="10">
      <el-select-v2
        placeholder="模块"
        :options="partOptions"
        v-model="part"
        @change="handleChangePart"
      />
    </el-col>
    <el-col :span="14">
      <div class="flex items-center gap-12px">
        <el-select-v2 placeholder="状态" :options="stateOptions || []" v-model="state" />
        <div class="flex flex-col items-center mr-8px gap-4px">
          <el-tooltip ref="openTooltipRef" content="启用此样式">
            <el-checkbox
              :model-value="openAllStyle"
              style="height: 20px"
              @change="onChangeOpen"
            ></el-checkbox>
          </el-tooltip>
          <el-tooltip ref="expandTooltipRef" content="折叠/展开">
            <span class="flex" @click="onChangeExpand">
              <lu-chevrons-down v-if="!expandStyle" size="12px" class="cursor-pointer" />
              <lu-chevrons-up v-else size="12px" class="cursor-pointer" />
            </span>
          </el-tooltip>
        </div>
      </div>
    </el-col>
  </el-row>
</template>

<script setup lang="ts">
import type { Ref } from 'vue'
import { computed, inject, ref } from 'vue'
import { has } from 'lodash-es'

import type { ComponentSchema, PartItem } from '@/lvgl-widgets/type'
import { LuChevronsDown, LuChevronsUp } from 'vue-icons-plus/lu'
import type { TooltipInstance } from 'element-plus'

const parts = inject<Ref<PartItem[]>>('parts')
const openTooltipRef = ref<TooltipInstance>()
const expandTooltipRef = ref<TooltipInstance>()

const modelValue = defineModel<{
  name: string
  state: string
  expandStyle: boolean
}>('modelValue')

const props = defineProps<{
  formData?: Record<string, any>
  widgetData?: Record<string, any>
  formItemsSchema?: ComponentSchema[]
  componentProps?: {
    // 处理part选项方法
    filterPartOptions?: (item: PartItem, widgetData?: Record<string, any>) => any
    [key: string]: any
  }
}>()

const emit = defineEmits<{
  (e: 'change', val: 'add' | 'delete'): void
}>()

// 部件列表
const partOptions = computed(() => {
  const fn = props.componentProps?.filterPartOptions
  return (
    parts?.value?.map((item) => {
      return typeof fn === 'function'
        ? fn(item, props.widgetData)
        : { label: item.name, value: item.name }
    })?.filter(Boolean) || []
  )
})

const part = computed({
  get() {
    return modelValue.value?.name
  },
  set(val: string) {
    if (modelValue.value) {
      modelValue.value.name = val
    }
  }
})

const state = computed({
  get() {
    return modelValue.value?.state
  },
  set(val: string) {
    if (modelValue.value) {
      modelValue.value.state = val
    }
  }
})

// 展开/折叠全部样式
const expandStyle = computed({
  get() {
    return modelValue.value?.expandStyle
  },
  set(val: boolean) {
    if (modelValue.value) {
      modelValue.value.expandStyle = val
    }
  }
})

const onChangeOpen = (val) => {
  openTooltipRef.value?.hide()
  emit('change', val ? 'add' : 'delete')
}

const onChangeExpand = () => {
  expandTooltipRef.value?.hide()
  expandStyle.value = !expandStyle.value
}

const getFields = (arr: ComponentSchema[]) => {
  const keys = (arr || []).map((config) => {
    if (config.valueType === 'dependency') {
      return getFields(config.dependency({ part: modelValue.value }))
    } else {
      return config.field
    }
  })
  return keys
}

// 开启/关闭全部样式
const openAllStyle = computed({
  get() {
    const formData = props.formData || {}
    const valueLength = Object.keys(formData).length
    const fields = getFields(props.formItemsSchema || []).flat(Infinity)

    let hasNotValue = false
    fields.forEach((field) => {
      if (!has(formData, field) && field !== 'part') {
        hasNotValue = true
      }
    })

    // 所有样式都开启
    return !!valueLength && !hasNotValue
  },
  set(val: boolean) {
    emit('change', val ? 'add' : 'delete')
  }
})

const stateOptions = computed(() => {
  return parts?.value
    ?.find?.((item) => item.name === part.value)
    ?.stateList?.map((state) => ({ label: state, value: state }))
})

const handleChangePart = () => {
  state.value = stateOptions.value?.[0]?.value || ''
}
</script>

<style scoped></style>
