<template>
  <div ref="scrollContainerRef" class="property-scroll">
    <!-- 基础属性 -->
    <el-form
      ref="formRef"
      class="px-12px box-border mt-12px"
      label-position="left"
      :model="projectStore.activeWidget"
    >
      <el-row :gutter="12">
        <template
          v-for="(item, index) in formConfig.props || []"
          :key="item.valueType + '_' + index"
        >
          <CusFormItem
            v-if="!item?.hideInForm"
            :schema="item"
            :formData="projectStore.activeWidget!"
          />
        </template>
      </el-row>
    </el-form>
    <!-- 核心属性 -->
    <el-collapse v-model="activeKeys">
      <el-collapse-item name="props" v-if="formConfig?.coreProps">
        <template #title>
          <div class="flex items-center">
            <LuSliders size="12px" />
            <span class="ml-4px text-12px">核心属性</span>
          </div>
        </template>
        <el-form
          ref="formRef"
          class="px-12px box-border mt-12px"
          label-position="left"
          :model="projectStore.activeWidget"
        >
          <el-row :gutter="12">
            <template
              v-for="(item, index) in formConfig.coreProps || []"
              :key="item.valueType + '_' + index"
            >
              <CusFormItem
                v-if="!item?.hideInForm"
                :schema="item"
                :formData="projectStore.activeWidget!"
                :widgetData="projectStore.activeWidget!"
              />
            </template>
          </el-row>
        </el-form>
      </el-collapse-item>
      <!-- 样式设置 -->
      <el-collapse-item v-if="formConfig.styles?.length" name="style">
        <template #title>
          <div class="flex items-center">
            <IoColorPaletteOutline size="12px" />
            <span class="ml-4px text-12px">样式配置</span>
          </div>
        </template>
        <el-form
          ref="formRef"
          class="px-12px box-border"
          label-position="left"
          :model="projectStore.activeWidget"
        >
          <el-form-item
            v-if="formConfig.styles?.find((item) => item.field === 'part')"
            label="主题"
            label-width="60px"
            class="mb-12px!"
          >
            <el-select v-model="editTheme" class="w-full" :options="themeOptions"> </el-select>
          </el-form-item>

          <el-form-item
            v-if="formConfig.styles?.find((item) => item.field === 'part')"
            label="模块/状态"
            class="mb-12px!"
          >
            <div class="w-full">
              <StylePart
                v-model="part"
                :formData="styleFormData"
                :widgetData="projectStore.activeWidget!"
                :formItemsSchema="formConfig.styles"
                :componentProps="
                  formConfig.styles.find((item) => item.field === 'part')?.componentProps
                "
                @change="onChangeStyleByState"
              />
            </div>
          </el-form-item>

          <el-row :gutter="12" v-show="part.expandStyle">
            <template
              v-for="(item, index) in formConfig.styles || []"
              :key="item.valueType + '_' + index"
            >
              <CusFormItem
                v-if="!item?.hideInForm"
                :schema="item"
                :formData="{
                  part,
                  ...styleFormData
                }"
                :widgetData="projectStore.activeWidget!"
                @change-state-style="onChangeStateStyle"
              />
            </template>
          </el-row>
        </el-form>
      </el-collapse-item>
    </el-collapse>
    <div
      :style="{ pointerEvents: isActiveWidgetLocked ? 'auto' : 'none' }"
      class="absolute left-0 top-0 w-full h-full"
      @click="handleClickMask"
    ></div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, provide, watch } from 'vue'
import CusFormItem from './CusFormItem.vue'
import { useProjectStore } from '@/store/modules/project'
import componentMap from '@/lvgl-widgets'
import StylePart from './components/StylePart.vue'
import { DEFAULT_THEME_KEY } from '@/constants'

import { LuSliders } from 'vue-icons-plus/lu'
import { IoColorPaletteOutline } from 'vue-icons-plus/io'
import { klona } from 'klona'
import { assign, get } from 'lodash-es'

const projectStore = useProjectStore()
const activeKeys = ref<string[]>(['props', 'style'])
const scrollContainerRef = ref<HTMLDivElement>()
const part = ref<{
  name: string
  state: string
  expandStyle: boolean
}>({
  name: '',
  state: '',
  expandStyle: true
})

const editTheme = ref(DEFAULT_THEME_KEY)
const isActiveWidgetLocked = computed(() => !!projectStore.activeWidget?.locked)

const getStyleTheme = (item?: Record<string, any>) => {
  return item?.theme || DEFAULT_THEME_KEY
}
// 样式表单数据
const styleFormData = computed(() => {
  const item = projectStore.activeWidget?.style?.find(
    (item) =>
      item?.part.name === part.value?.name &&
      item?.part.state === part.value?.state &&
      getStyleTheme(item) === editTheme.value
  )

  return item
})

// 表单配置
const formConfig = computed(() => {
  return projectStore.activeWidget ? componentMap[projectStore.activeWidget.type].config : {}
})

// 获取控件部件状态集
const parts = computed(() => {
  return projectStore.activeWidget ? componentMap[projectStore.activeWidget.type].parts : []
})

// 主题选项
const themeOptions = computed(() => {
  return projectStore.project?.themes.map((item) => ({
    label: `${item.key}${item.description ? `(${item.description})` : ''}`,
    value: item.key
  }))
})

watch(
  () => projectStore.project?.themes?.map((item) => item.key).join('|'),
  () => {
    const themeKeys = projectStore.project?.themes?.map((item) => item.key) || []
    if (!themeKeys.length) {
      editTheme.value = DEFAULT_THEME_KEY
      return
    }
    if (!themeKeys.includes(editTheme.value)) {
      editTheme.value = projectStore.project?.currentTheme || themeKeys[0]
    }
  },
  {
    immediate: true
  }
)

const handleClickMask = (e: MouseEvent) => {
  if (isActiveWidgetLocked.value) {
    e.stopPropagation()
    e.preventDefault()
  }
}

const setPartByEditThemeStyle = () => {
  const widgetStyles = projectStore.activeWidget?.style || []
  const currentPartThemeStyle = widgetStyles.find(
    (item) =>
      item?.part?.name === part.value.name &&
      item?.part?.state === part.value.state &&
      getStyleTheme(item) === editTheme.value
  )
  const currentThemeStyle = widgetStyles.find((item) => getStyleTheme(item) === editTheme.value)
  const fallbackThemeStyle = widgetStyles.find((item) => getStyleTheme(item) === DEFAULT_THEME_KEY)
  const fallbackStyle = widgetStyles[0]
  const first = currentPartThemeStyle || currentThemeStyle || fallbackThemeStyle || fallbackStyle

  if (first) {
    part.value.name = first.part.name
    part.value.state = first.part.state
  }
  part.value.expandStyle = true
}

provide('parts', parts)

watch(
  () => projectStore.activeWidget?.id,
  () => {
    editTheme.value = projectStore.project?.currentTheme || DEFAULT_THEME_KEY
    setPartByEditThemeStyle()
    scrollContainerRef.value?.scrollTo({
      top: 0
    })
  },
  {
    immediate: true
  }
)

watch(
  () => editTheme.value,
  () => {
    setPartByEditThemeStyle()
  }
)

watch(
  () => part.value,
  ({ name, state }) => {
    if (projectStore.activeWidget && name) {
      projectStore.activeWidget.part = name
      projectStore.activeWidget.state = state
    }
  },
  {
    deep: true
  }
)

/**
 * 获取控件预设样式
 */
const getWidgetDefaultStyle = () => {
  const widgetType = projectStore.activeWidget?.type

  const state = projectStore.globalStyle
    ?.find((item) => item.widget === widgetType)
    ?.part?.find((item) => item.partName === part.value.name)?.state

  const defaultStyle =
    projectStore.globalStyle
      ?.find((item) => item.widget === widgetType)
      ?.part?.find((item) => item.partName === part.value.name)?.defaultStyle || {}

  const stateStyle = state?.find((item) => item.state === part.value.state)?.style || {}

  return klona({
    defaultStyle,
    stateStyle
  })
}

/**
 * 设置控件状态部分样式
 * @param field 样式字段名
 * @param type 修改类型
 */
const onChangeStateStyle = (field: string, type: 'add' | 'delete') => {
  if (type === 'add') {
    const { defaultStyle, stateStyle } = getWidgetDefaultStyle()

    const style = get(assign({}, defaultStyle, stateStyle), field)

    if (styleFormData.value) {
      styleFormData.value[field] = style
    } else {
      const result = klona({
        [field]: style,
        part: {
          name: part.value.name,
          state: part.value.state
        },
        theme: editTheme.value
      })
      projectStore.activeWidget?.style?.push(result)
    }
  } else {
    if (styleFormData.value?.[field]) {
      delete styleFormData.value[field]
    }
  }
}

/**
 * 开启/关闭控件部件状态样式
 * @param type
 */
const onChangeStyleByState = (type: 'add' | 'delete') => {
  if (type === 'add') {
    const { defaultStyle, stateStyle } = getWidgetDefaultStyle()
    // 找多对应样式时添加 状态的样式合并到默认样式
    const result = klona({
      ...assign({}, defaultStyle, stateStyle),
      part: {
        name: part.value.name,
        state: part.value.state
      },
      theme: editTheme.value
    })
    projectStore.activeWidget?.style?.push(result)
  } else {
    // 删除样式
    const index =
      projectStore.activeWidget?.style.findIndex(
        (item) =>
          item.part.name === part.value.name &&
          item.part.state === part.value.state &&
          getStyleTheme(item) === editTheme.value
      ) ?? -1
    if (index !== -1) {
      projectStore.activeWidget?.style.splice(index, 1)
    }
  }
}
</script>

<style scoped>
.property-scroll {
  height: calc(100vh - 130px);
  overflow: auto;
  overscroll-behavior: contain;
  contain: layout paint;
  position: relative;
}

::v-deep(.el-collapse-icon-position-right .el-collapse-item__header) {
  padding: 0 8px;
  box-sizing: border-box;
  /* border-bottom: 1px solid var(--el-collapse-border-color); */
}
::v-deep(.el-collapse-item__content) {
  padding-bottom: 0;
}
:deep(.el-form-item) {
  margin-bottom: 6px;
}
</style>
