<script setup lang="ts">
import lodash from "lodash";
import { computed, reactive } from "vue";
import { ElCollapse, ElCollapseItem } from "element-plus";
import DataForm from "@/components/data-form/DataForm.vue";
import type { PropertyFlattenSetter, PropertySetterGroup } from "@/core/base/PropertyTypes.ts";
import type { DataFormProps } from "@/components/data-form/DataFormTypes.ts";
import { defDataFormProps } from "@/editor/widgets/property/PropertyPanelConstant.ts";
import Viewport, { type ViewportState } from "@/core/engine/Viewport.ts";

defineOptions({
    name: 'PropertyPanel',
});

// 定义 Props 类型
interface PropertyPanelProps {
    /** 待编辑数据 */
    data?: any;
    /** Viewport */
    viewport: Viewport;
    /** ViewportState */
    viewportState: ViewportState;
    /** 默认的DataFormProps */
    defDataFormProps?: DataFormProps;
    /** 最上面平铺的设置器 */
    flatten?: PropertyFlattenSetter;
    /** 设置器分组集合 */
    groups?: Array<PropertySetterGroup>;
}

// 读取组件 props 属性
const props = withDefaults(defineProps<PropertyPanelProps>(), {});

// 定义 State 类型
interface PropertyPanelState {
    /** 待编辑数据 */
    data?: any;
    /** 已展开的分组 */
    expandGroups: Array<string>;
}

// state 属性
const state = reactive<PropertyPanelState>({
    data: lodash.cloneDeep(props.data),
    expandGroups: [],
});

// 定义 Data 类型
interface PropertyPanelData {
}

// 内部数据
const data: PropertyPanelData = {};
const flattenFormProps = computed(() => getDefFormProps(props.flatten));

function getDefFormProps(setter?: PropertyFlattenSetter) {
    const formProps: DataFormProps = {
        ...defDataFormProps,
        ...props.defDataFormProps,
    };
    fillFormProps(setter);
    return formProps;
}

function fillFormProps(formProps: DataFormProps, setter?: PropertyFlattenSetter) {
    if (!setter) return;
    if (setter.size) formProps.size = setter.size;
    if (setter.labelWidth) formProps.labelWidth = setter.labelWidth;
}

function getCollapseItemId(group: PropertySetterGroup, idx: number) {
    return `_${idx}_${group.title}`;
}

function onDataChange(newData: any) {
    const viewport = props.viewport;
    if (!viewport) return;
    viewport.stateManager.beginStateUpdate();
    lodash.merge(props.data, newData);
    console.log("onDataChange", props.data === newData);
    viewport.stateManager.endStateUpdate();
}

interface PropertyPanelExpose {
    state: PropertyPanelState;
    data: PropertyPanelData;
}

const expose: PropertyPanelExpose = {
    state,
    data,
};
// 定义组件公开内容
defineExpose(expose);

export type {
    PropertyPanelProps,
    PropertyPanelState,
}
</script>

<template>
    <div class="property-panel">
        <DataForm
            v-if="props.flatten"
            class="property-panel-form"
            v-bind="flattenFormProps"
            :data="state.data"
            :formFields="props.flatten.fields"
            @dataChange="onDataChange"
        />
        <ElCollapse v-if="props.groups" v-model="state.expandGroups">
            <ElCollapseItem
                v-for="(group, idx) in props.groups"
                :name="getCollapseItemId(group, idx)"
                :title="group.title"
            >
                <DataForm
                    v-if="group"
                    class="property-panel-form"
                    v-bind="getDefFormProps(group)"
                    :data="state.data"
                    :formFields="props.flatten.fields"
                    @dataChange="onDataChange"
                />
            </ElCollapseItem>
        </ElCollapse>
    </div>
</template>

<style scoped>
.property-panel {
    padding: 8px 12px 16px 0;
}
</style>
