<template>
  <a-button size="small" type="text" class="w-full" @click="actionEditEable">编辑</a-button>

  <a-modal v-model:open="isModalOpen" title="参数编辑" @ok="actionOk">
    <a-table bordered size="small"
      v-model:expandedRowKeys="tableExpandedKeys" 
      :columns="tableColumns" 
      :data-source="tableData" 
      :pagination="false" 
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'value'">
          <!-- Integer -->
          <a-input-number v-if="'java.lang.Integer' === record.type" 
            size="small" class="w-full !border-none" 
            v-model:value="record.value"
          ></a-input-number>

          <!-- Double -->
          <a-input-number v-if="'java.lang.Double' === record.type" 
            size="small" class="w-full !border-none" :step="0.01"
            v-model:value="record.value"
          ></a-input-number>
        </template>
      </template>
    </a-table>
  </a-modal>
</template>
<script setup>
import { nextTick, onMounted, ref } from 'vue';
import ApiClient from '@/utils/ApiClient';
/** @var {Function} */
const emits = defineEmits(['update:value','change', 'save-request']);
/** @var {Object} */
const props = defineProps({
    structClassName : String,
    value : Object,
});
/** @var {Array} */
const tableColumns = ref([
    {key:'title',title:'属性',dataIndex:'title'},
    {key:'value',title:'取值'},
]);
/** @var {Array} */
const tableData = ref([]);
/** @var {String} */
const tableExpandedKeys = ref([]);
/** @var {Boolean} */
const isModalOpen = ref(false);
// on mounted
onMounted(mounted);

// on mounted
async function mounted() {
    let structClassName = props.structClassName;
    tableData.value = await setupTableData(structClassName);
}

// setup tree data
async function setupTableData(structClassName, path=[]) {
    let classPath = `${0===path.length ? '' : path.join('.')+'.'}${structClassName}`;
    console.log(`setup for : ${classPath}`);
    let baseTypes = ['Integer','Double'];
    let client = ApiClient.getClient();

    try {
        let structInfo = await client.call('service-config/class-struct-info-get', {class:structClassName});
        let nodes = [];
        for ( let item of structInfo ) {
            let itemPath = structuredClone(path);
            itemPath.push(item.name);
            tableExpandedKeys.value.push(item.name);

            let node = {};
            node.key = `${classPath}#${item.name}`;
            node.attr = item.name;
            node.title = item.name;
            node.type = item.type;
            node.info = item;
            if ( !baseTypes.includes(item.type) ) {
                node.children = await setupTableData(item.type, itemPath);
            }
            node.value = getValueFromJson(itemPath);
            nodes.push(node);
        }
        return nodes;
    } catch ( e ) { console.error(e); }
}

// get value from json by path
function getValueFromJson( path ) {
    let value = props.value;
    for ( var item of path ) {
        if ( null === value || undefined === value[item] ) {
            return undefined;
        }
        value = value[item];
    }
    return value;
}

// generate json data
function generateJsonData( nodes ) {
    let obj = {};
    for ( let node of nodes ) {
        if ( undefined !== node.children ) {
            obj[node.attr] = generateJsonData(node.children);
        } else {
            obj[node.attr] = node.value;
        }
    }
    return obj;
}

// enable edit
function actionEditEable() {
    isModalOpen.value = true;
}

// ok
async function actionOk() {
    let newValue = generateJsonData(tableData.value);
    emits('update:value', newValue);
    emits('change');
    await nextTick();
    emits('save-request');
    isModalOpen.value = false;
}
</script>