<template>
  <el-scrollbar height="calc(100vh - 130px)">
    <el-form label-position="top" class="h-full">
      <SplitterCollapse>
        <SplitterCollapseItem title="组件属性" class="flex-none">
          <el-collapse v-model="activeNames" class="p-10px">
            <el-scrollbar
              :height="
                data.type && LvglWidgets[data.type].config.props && data.type != 'page'
                  ? 'calc(100vh - 280px)'
                  : ''
              "
            >
              <template
                v-for="prop in data.type && LvglWidgets[data.type].config.props"
                :key="prop.field"
              >
                <!-- 判断是否为 group 类型 -->
                <template v-if="prop.valueType === 'group'">
                  <el-collapse-item :title="prop.label" :name="prop.label">
                    <div
                      v-for="child in prop.children"
                      :key="child.field"
                      style="flex: 0 0 calc(50% - 5px)"
                    >
                      <el-form-item :label="child.label" class="flex w-full">
                        <input-number
                          v-if="child.valueType === 'number'"
                          v-model="data.props[child.field]"
                          :min="0"
                          :placeholder="child.componentProps.placeholder"
                          :readonly="child.componentProps.readOnly"
                          :disabled="child.componentProps.disabled"
                          style="width: 100%"
                          :step="0.1"
                        />
                        <el-input
                          v-if="child.valueType === 'text' && child.field === 'name'"
                          v-model="data[child.field]"
                          :placeholder="child.componentProps.placeholder"
                          :readonly="child.componentProps.readOnly"
                          :disabled="child.componentProps.disabled"
                        />
                        <el-input
                          v-if="child.valueType === 'text' && child.field !== 'name'"
                          v-model="data.props[child.field]"
                          :placeholder="child.componentProps.placeholder"
                          :readonly="child.componentProps.readOnly"
                          :disabled="child.componentProps.disabled"
                        />
                        <el-select
                          v-if="child.valueType === 'select'"
                          v-model="data.props[child.field]"
                          :placeholder="child.componentProps.placeholder"
                          :readonly="child.componentProps.readOnly"
                          :disabled="child.componentProps.disabled"
                        >
                          <el-option
                            v-for="select in child.componentProps.options"
                            :key="select.value"
                            :label="select.label"
                            :value="select.value"
                          />
                        </el-select>
                        <!-- <div class="chart-container">
                        <div class="chart-placeholder">xxx</div>
                      </div> -->
                      </el-form-item>
                    </div>
                  </el-collapse-item>
                </template>

                <!-- 多选平铺 -->
                <template
                  v-else-if="
                    prop.valueType === 'checkbox' &&
                    ['addFlags', 'removeFlags'].includes(prop.field)
                  "
                >
                  <el-collapse-item :title="prop.label" :name="prop.label">
                    <div class="flex flex-wrap gap-10px mb-10px">
                      <div
                        v-for="addFlags in prop.componentProps?.options"
                        :key="addFlags.value"
                        :class="[
                          'bg-#333333',
                          'h-[30px]',
                          'rounded-[5px]',
                          'line-height-[30px]',
                          'text-center',
                          'cursor-pointer',
                          { 'bg-[var(--accent-blue)]': isActive(prop, addFlags) }
                        ]"
                        style="flex: 0 0 calc(50% - 5px)"
                        @click="handleClick(prop, addFlags)"
                      >
                        {{ addFlags.label }}
                      </div>
                    </div>
                  </el-collapse-item>
                </template>

                <!-- 非 group 类型的字段 -->
                <template v-else>
                  <el-form-item :label="prop.label">
                    <!-- 文本类型字段 -->
                    <el-input
                      v-if="prop.valueType === 'text' && prop.field === 'name'"
                      v-model="data[prop.field]"
                      :placeholder="prop.componentProps?.placeholder"
                    />
                    <el-input
                      v-if="prop.valueType === 'text' && prop.field !== 'name'"
                      v-model="data.props[prop.field]"
                      :placeholder="prop.componentProps?.placeholder"
                    />
                    <!-- 数字类型字段 -->
                    <input-number
                      v-if="prop.valueType === 'number'"
                      v-model="data.props[prop.field]"
                      style="width: 100%"
                      :min="0"
                      :step="0.1"
                    />
                    <!-- 下拉类型字段 -->
                    <el-select
                      v-if="prop.valueType === 'select'"
                      v-model="data.props[prop.field]"
                      :placeholder="prop.componentProps?.placeholder"
                      :readonly="prop.componentProps?.readOnly"
                      :disabled="prop.componentProps?.disabled"
                    >
                      <el-option
                        v-for="select in prop.componentProps?.options"
                        :key="select.value"
                        :label="select.label"
                        :value="select.value"
                      />
                    </el-select>
                    <!-- <div class="chart-container">
                    <div class="chart-placeholder"></div>
                  </div> -->
                  </el-form-item>
                </template>
              </template>
            </el-scrollbar>
          </el-collapse>
        </SplitterCollapseItem>

        <!--  -->

        <SplitterCollapseItem title="样式配置" class="flex-none">
          <el-collapse v-model="activeNames" class="p-10px">
            <el-scrollbar
              :height="
                data.type && LvglWidgets[data.type].config.styles && data.type != 'page'
                  ? 'calc(100vh - 280px)'
                  : ''
              "
            >
              <template
                v-for="prop in data.type && LvglWidgets[data.type].config.styles"
                :key="prop.field"
              >
                <el-form-item v-if="prop.field === 'part'" :label="prop.label" class="flex w-full">
                  <div class="flex flex-1 justify-between items-center gap-10px">
                    <!-- 模块 -->
                    <el-select v-model="moduleValue" @change="handlePartChange">
                      <el-option
                        v-for="part in LvglWidgets[data.type].parts"
                        :key="part.name"
                        :label="part.name"
                        :value="part.name"
                      />
                    </el-select>

                    <!-- 状态 -->
                    <el-select v-model="stateValue" @change="handleStateChange">
                      <el-option
                        v-for="state in getStateList(moduleValue)"
                        :key="state"
                        :label="state"
                        :value="state"
                      />
                    </el-select>
                    <!-- 控制区域 -->
                    <el-icon style="width: 60px" class="cursor-pointer" @click="handleVisibleStyle"
                      ><View
                    /></el-icon>
                  </div>
                </el-form-item>
              </template>
              <!-- 样式配置区域 -->
              <template v-if="visibleStyle">
                <template
                  v-for="prop in data.type && LvglWidgets[data.type].config.styles"
                  :key="prop.field"
                >
                  <!-- 固定依赖 -->
                  <el-form-item
                    v-if="prop.field !== 'part'"
                    :label="prop.label"
                    class="flex w-full"
                  >
                    <!-- 背景颜色 -->
                    <template v-if="prop.field === 'background'">
                      <template
                        v-if="data.style?.[styleIndex]?.[prop.field]?.hasOwnProperty('color')"
                      >
                        <div class="flex [flex-direction:column] flex-1">
                          <div class="flex flex-1">
                            <el-color-picker
                              v-model="data.style[styleIndex][prop.field].color"
                              :show-alpha="true"
                              :predefine="predefineColors"
                            />
                            <div class="ml-10px">
                              {{ data.style[styleIndex][prop.field].color }}
                            </div>
                          </div>

                          <template
                            v-if="data.style?.[styleIndex]?.[prop.field]?.hasOwnProperty('image')"
                          >
                            <div class="flex flex-1 mt-10px">
                              <div class="w-32px h-32px bg-#cccc mr-10px"></div>
                              <el-color-picker
                                v-model="data.style[styleIndex][prop.field].image.color"
                                :show-alpha="true"
                                :predefine="predefineColors"
                              />
                              <div class="ml-10px">
                                {{ data.style[styleIndex][prop.field].image.color }}
                              </div>
                            </div>
                          </template>
                        </div>
                      </template>
                    </template>

                    <!-- 字体 -->
                    <div v-if="prop.field === 'text'" class="w-full">
                      <div class="flex flex-1 gap-10px mb-10px">
                        <el-color-picker
                          v-model="data.style[styleIndex][prop.field].color"
                          :show-alpha="true"
                          :predefine="predefineColors"
                        />
                        <input-number
                          v-model="data.style[styleIndex][prop.field].size"
                          :min="0"
                          placeholder="字体大小"
                          class="flex-1"
                        />
                      </div>
                      <div class="flex flex-1 gap-10px mb-10px">
                        <el-select
                          v-model="data.style[styleIndex][prop.field].weight"
                          placeholder="字体加粗"
                        >
                          <el-option
                            v-for="weight in textWeight"
                            :key="weight.value"
                            :label="weight.label"
                            :value="weight.value"
                          />
                        </el-select>
                        <el-select v-model="data.style[styleIndex][prop.field].family"></el-select>
                      </div>
                      <el-select
                        v-model="data.style[styleIndex][prop.field].align"
                        placeholder="对齐方式"
                      >
                        <el-option
                          v-for="align in textAlign"
                          :key="align.value"
                          :label="align.label"
                          :value="align.value"
                        />
                      </el-select>
                    </div>

                    <!-- 边框 -->
                    <div v-if="prop.field === 'border'" class="w-full">
                      <div class="flex flex-1 gap-10px mb-10px">
                        <input-number
                          v-model="data.style[styleIndex][prop.field].width"
                          placeholder="边框大小"
                          class="flex-1"
                          :min="0"
                        />
                        <el-color-picker
                          v-model="data.style[styleIndex][prop.field].color"
                          :show-alpha="true"
                          :predefine="predefineColors"
                        />
                      </div>
                      <div class="flex flex-1 gap-10px">
                        <el-select
                          v-model="data.style[styleIndex][prop.field].side"
                          multiple
                          collapse-tags
                          class="flex-1"
                        >
                          <el-option
                            v-for="sides in borderSides"
                            :key="sides.value"
                            :label="sides.label"
                            :value="sides.value"
                          />
                        </el-select>
                        <input-number
                          v-model="data.style[styleIndex][prop.field].radius"
                          placeholder="圆角大小"
                          class="flex-1"
                          :min="0"
                        />
                      </div>
                    </div>
                    <!-- 阴影 -->
                    <div v-if="prop.field === 'shadow'" class="w-full">
                      <el-color-picker
                        v-model="data.style[styleIndex][prop.field].color"
                        :show-alpha="true"
                        :predefine="predefineColors"
                        class="mb-10px"
                      />
                      <div class="flex flex-1 gap-10px mb-10px">
                        <input-number
                          v-model="data.style[styleIndex][prop.field].x"
                          placeholder="水平偏移"
                          class="flex-1"
                          :min="0"
                        />
                        <input-number
                          v-model="data.style[styleIndex][prop.field].y"
                          placeholder="垂直偏移"
                          class="flex-1"
                          :min="0"
                        />
                      </div>
                      <div class="flex flex-1 gap-10px">
                        <input-number
                          v-model="data.style[styleIndex][prop.field].width"
                          placeholder="模糊半径"
                          class="flex-1"
                          :min="0"
                        />

                        <input-number
                          v-model="data.style[styleIndex][prop.field].spread"
                          placeholder="阴影扩展半径"
                          class="flex-1"
                          :min="0"
                        />
                      </div>
                    </div>
                    <!-- 内边距 -->
                    <div v-if="prop.field === 'padding'" class="w-full">
                      <div class="flex flex-1 gap-10px mb-10px">
                        <input-number
                          v-model="data.style[styleIndex][prop.field].top"
                          placeholder="内部上边距"
                          class="flex-1"
                          :min="0"
                        />
                        <input-number
                          v-model="data.style[styleIndex][prop.field].right"
                          placeholder="内部右边距"
                          class="flex-1"
                          :min="0"
                        />
                      </div>
                      <div class="flex flex-1 gap-10px">
                        <input-number
                          v-model="data.style[styleIndex][prop.field].bottom"
                          placeholder="内部下边距"
                          class="flex-1"
                          :min="0"
                        />

                        <input-number
                          v-model="data.style[styleIndex][prop.field].left"
                          placeholder="内部左边距"
                          class="flex-1"
                          :min="0"
                        />
                      </div>
                    </div>
                    <!-- 间距 -->
                    <div v-if="prop.field === 'gap'" class="w-full flex flex-1 gap-10px">
                      <input-number
                        v-model="data.style[styleIndex][prop.field].row"
                        placeholder="横向"
                        class="flex-1"
                        :min="0"
                      />

                      <input-number
                        v-model="data.style[styleIndex][prop.field].column"
                        placeholder="纵向"
                        class="flex-1"
                        :min="0"
                      />
                    </div>
                  </el-form-item>

                  <!-- 动态显示依赖项 -->
                  <template v-if="prop.valueType === 'dependency'">
                    <el-form-item
                      v-for="dependency in getDynamicFields(prop)"
                      :key="dependency.field"
                      :label="dependency.label"
                    >
                      <!-- 背景颜色 -->
                      <template v-if="dependency.field === 'background'">
                        <template
                          v-if="
                            data.style?.[styleIndex]?.[dependency.field]?.hasOwnProperty('color')
                          "
                        >
                          <div class="flex [flex-direction:column] flex-1">
                            <div class="flex flex-1">
                              <el-color-picker
                                v-model="data.style[styleIndex][dependency.field].color"
                                :show-alpha="true"
                                :predefine="predefineColors"
                              />
                              <div class="ml-10px">
                                {{ data.style[styleIndex][dependency.field].color }}
                              </div>
                            </div>

                            <template
                              v-if="
                                data.style?.[styleIndex]?.[dependency.field]?.hasOwnProperty(
                                  'image'
                                )
                              "
                            >
                              <div class="flex flex-1 mt-10px">
                                <div class="w-32px h-32px bg-#cccc mr-10px"></div>
                                <el-color-picker
                                  v-model="data.style[styleIndex][dependency.field].image.color"
                                  :show-alpha="true"
                                  :predefine="predefineColors"
                                />
                                <div class="ml-10px">
                                  {{ data.style[styleIndex][dependency.field].image.color }}
                                </div>
                              </div>
                            </template>
                          </div>
                        </template>
                      </template>

                      <!-- 字体 -->
                      <div v-if="dependency.field === 'text'" class="w-full">
                        <div class="flex flex-1 gap-10px mb-10px">
                          <el-color-picker
                            v-model="data.style[styleIndex][dependency.field].color"
                            :show-alpha="true"
                            :predefine="predefineColors"
                          />
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].size"
                            :min="0"
                            placeholder="字体大小"
                            class="flex-1"
                          />
                        </div>
                        <div class="flex flex-1 gap-10px mb-10px">
                          <el-select
                            v-model="data.style[styleIndex][dependency.field].weight"
                            placeholder="字体加粗"
                          >
                            <el-option
                              v-for="weight in textWeight"
                              :key="weight.value"
                              :label="weight.label"
                              :value="weight.value"
                            />
                          </el-select>
                          <el-select
                            v-model="data.style[styleIndex][dependency.field].family"
                          ></el-select>
                        </div>
                        <el-select
                          v-model="data.style[styleIndex][dependency.field].align"
                          placeholder="对齐方式"
                        >
                          <el-option
                            v-for="align in textAlign"
                            :key="align.value"
                            :label="align.label"
                            :value="align.value"
                          />
                        </el-select>
                      </div>

                      <!-- 边框 -->
                      <div v-if="dependency.field === 'border'" class="w-full">
                        <div class="flex flex-1 gap-10px mb-10px">
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].width"
                            placeholder="边框大小"
                            class="flex-1"
                            :min="0"
                          />
                          <el-color-picker
                            v-model="data.style[styleIndex][dependency.field].color"
                            :show-alpha="true"
                            :predefine="predefineColors"
                          />
                        </div>
                        <div class="flex flex-1 gap-10px">
                          <el-select
                            v-model="data.style[styleIndex][dependency.field].side"
                            multiple
                            collapse-tags
                            class="flex-1"
                          >
                            <el-option
                              v-for="sides in borderSides"
                              :key="sides.value"
                              :label="sides.label"
                              :value="sides.value"
                            />
                          </el-select>
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].radius"
                            placeholder="圆角大小"
                            class="flex-1"
                            :min="0"
                          />
                        </div>
                      </div>
                      <!-- 阴影 -->
                      <div v-if="dependency.field === 'shadow'" class="w-full">
                        <el-color-picker
                          v-model="data.style[styleIndex][dependency.field].color"
                          :show-alpha="true"
                          :predefine="predefineColors"
                          class="mb-10px"
                        />
                        <div class="flex flex-1 gap-10px mb-10px">
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].x"
                            placeholder="水平偏移"
                            class="flex-1"
                            :min="0"
                          />
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].y"
                            placeholder="垂直偏移"
                            class="flex-1"
                            :min="0"
                          />
                        </div>
                        <div class="flex flex-1 gap-10px">
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].width"
                            placeholder="模糊半径"
                            class="flex-1"
                            :min="0"
                          />

                          <input-number
                            v-model="data.style[styleIndex][dependency.field].spread"
                            placeholder="阴影扩展半径"
                            class="flex-1"
                            :min="0"
                          />
                        </div>
                      </div>
                      <!-- 内边距 -->
                      <div v-if="dependency.field === 'padding'" class="w-full">
                        <div class="flex flex-1 gap-10px mb-10px">
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].top"
                            placeholder="内部上边距"
                            class="flex-1"
                            :min="0"
                          />
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].right"
                            placeholder="内部右边距"
                            class="flex-1"
                            :min="0"
                          />
                        </div>
                        <div class="flex flex-1 gap-10px">
                          <input-number
                            v-model="data.style[styleIndex][dependency.field].bottom"
                            placeholder="内部下边距"
                            class="flex-1"
                            :min="0"
                          />

                          <input-number
                            v-model="data.style[styleIndex][dependency.field].left"
                            placeholder="内部左边距"
                            class="flex-1"
                            :min="0"
                          />
                        </div>
                      </div>
                      <!-- 间距 -->
                      <div v-if="dependency.field === 'gap'" class="w-full flex flex-1 gap-10px">
                        <input-number
                          v-model="data.style[styleIndex][dependency.field].row"
                          placeholder="横向"
                          class="flex-1"
                          :min="0"
                        />

                        <input-number
                          v-model="data.style[styleIndex][dependency.field].column"
                          placeholder="纵向"
                          class="flex-1"
                          :min="0"
                        />
                      </div>
                    </el-form-item>
                  </template>
                </template>
              </template>
            </el-scrollbar>
          </el-collapse>
        </SplitterCollapseItem>
      </SplitterCollapse>
    </el-form>
  </el-scrollbar>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import type { Page } from '@/types/page'
import LvglWidgets from '@/lvgl-widgets'
import { View } from '@element-plus/icons-vue'
import { textAlign, textWeight, borderSides } from '@/constants'
import { SplitterCollapse, SplitterCollapseItem } from '@/components/SplitterCollapse'

interface Emits {
  (e: 'update:selected', val: Page['props']): void
}
const props = defineProps<{
  selected?: Page['props']
}>()
const emit = defineEmits<Emits>()
const data = ref<Page['props']>(props.selected || ({} as Page['props']))
watch(data, (val) => emit('update:selected', val))

watch(
  () => props.selected,
  (value) => {
    if (value) {
      moduleValue.value = LvglWidgets[data.value.type]?.parts[0].name || 'main'
      stateValue.value = LvglWidgets[data.value.type]?.parts[0].stateList[0] || 'default'
      data.value = value || ({} as Page['props'])
    }
  }
)

const activeNames = ref<string[]>(['基本属性', '位置/大小', '添加标识', '删除标识'])

const moduleValue = ref('')
const stateValue = ref('')
const visibleStyle = ref(true)
const predefineColors = [
  '#ff4500',
  '#ff8c00',
  '#ffd700',
  '#90ee90',
  '#00ced1',
  '#1e90ff',
  '#c71585',
  'rgba(255, 69, 0, 0.68)',
  'rgb(255, 120, 0)',
  'hsv(51, 100, 98)',
  'hsva(120, 40, 94, 0.5)',
  'hsl(181, 100%, 37%)',
  'hsla(209, 100%, 56%, 0.73)',
  '#c7158577'
]

const loadStyle = async (name) => {
  try {
    const Json = await import(`@/lvgl-widgets/${name}/style.json`)
    return Json.default
  } catch (error) {
    console.error(error)
  }
}

const styleIndex = computed(() => {
  return data.value.style.findIndex(
    (item) => item.part.name === moduleValue.value && item.part.state === stateValue.value
  )
})

const getStateList = (partName) => {
  const part = LvglWidgets[data.value.type].parts.find((item) => item.name === partName)
  return part ? part.stateList : []
}

const isActive = (prop, addFlags) => {
  return data.value.props[prop.field].some((item) => item.value === addFlags.value)
}

const handleClick = (prop, addFlags) => {
  const selectedOptions = data.value.props[prop.field]

  const index = selectedOptions.findIndex((item) => item.value === addFlags.value)

  if (index !== -1) {
    selectedOptions.splice(index, 1)
  } else {
    selectedOptions.push(addFlags)
  }
}

const handleVisibleStyle = () => {
  visibleStyle.value = !visibleStyle.value
}

const handlePartChange = (targetPartName) => {
  const existingPart = data.value.style.find((item) => item.part.name === targetPartName)
  if (!existingPart) {
    loadStyle(data.value.props.name).then((loadedStyle) => {
      if (loadedStyle) {
        const targetPart = loadedStyle.part.find((item) => item.partName === moduleValue.value)

        if (targetPart) {
          const targetStyle = targetPart.state.find((item) => item.state === targetPart)

          if (targetStyle) {
            targetStyle.style.part = {
              name: moduleValue.value,
              state: targetPart
            }
            data.value.style.push(targetStyle.style)
          }
        }
      }
    })
  }
}

const handleStateChange = (targetState) => {
  const existingState = data.value.style.find((item) => item.part.state === targetState)

  if (!existingState) {
    loadStyle(data.value.props.name).then((loadedStyle) => {
      if (loadedStyle) {
        const targetPart = loadedStyle.part.find((item) => item.partName === moduleValue.value)

        if (targetPart) {
          const targetStyle = targetPart.state.find((item) => item.state === targetState)

          if (targetStyle) {
            targetStyle.style.part = {
              name: moduleValue.value,
              state: targetState
            }
            data.value.style.push(targetStyle.style)
          }
        }
      }
    })
  }
}

const getDynamicFields = (prop) => {
  if (prop.valueType === 'dependency' && prop.name && Array.isArray(prop.name)) {
    const fieldValues = prop.name.reduce((values, field) => {
      if (field === 'part') {
        values[field] = moduleValue.value
      } else {
        values[field] = data.value[field] || data.value.props[field]
      }

      return values
    }, {})

    return prop.dependency(fieldValues) || []
  }
  return []
}
</script>

<style scoped lang="less">
:deep(.el-collapse-item__header) {
  padding-right: 0px;
}
:deep(.el-collapse-item__content) {
  padding-bottom: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 10px;
}

:deep(.el-scrollbar__view) {
  height: 100%;
}
:deep(.flex-none) {
  flex: none !important;
}
</style>
