<!--
  ~ Licensed to Apache Software Foundation (ASF) under one or more contributor
  ~ license agreements. See the NOTICE file distributed with
  ~ this work for additional information regarding copyright
  ~ ownership. Apache Software Foundation (ASF) licenses this file to you under
  ~ the Apache License, Version 2.0 (the "License"); you may
  ~ not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing,
  ~ software distributed under the License is distributed on an
  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  ~ KIND, either express or implied.  See the License for the
  ~ specific language governing permissions and limitations
  ~ under the License.
-->

<script lang="ts" setup>
  import type { FormInstance } from 'element-plus';
  import { ref, reactive } from 'vue';

  const ruleFormRef = ref<FormInstance>();
  const data = reactive({
    tableData: [],
    dialogVisible: false,
    form: {
      name: '',
      fieldType: '',
      encodingMethod: '',
      compressionMethod: '',
    },
    fieldOperator: 'Add',
    fieldEditIndex: -1,
  });

  const typeOptions = [
    {
      value: 'FIELD_TYPE_STRING',
      label: 'STRING',
    },
    {
      value: 'FIELD_TYPE_INT',
      label: 'INT',
    },
    {
      value: 'FIELD_TYPE_DATA_BINARY',
      label: 'DATA_BINARY',
    },
    {
      value: 'FIELD_TYPE_FLOAT',
      label: 'FLOAT',
    },
  ];
  const encodingMethodOptions = [
    {
      value: 'ENCODING_METHOD_GORILLA',
      label: 'GORILLA',
    },
  ];
  const compressionMethodOptions = [
    {
      value: 'COMPRESSION_METHOD_ZSTD',
      label: 'ZSTD',
    },
  ];
  const validateName = (rule: any, value: any, callback: any) => {
    if (value === '') {
      callback(new Error('Please input the field name.'));
    } else {
      const index = data.tableData.findIndex((item) => {
        return item.name === value;
      });
      if (index >= 0) {
        if (data.fieldOperator === 'Edit' && data.fieldEditIndex === index) {
          return callback();
        }
        return callback(new Error('The name is exists'));
      }
      callback();
    }
  };
  const rules = {
    name: [
      {
        required: true,
        validator: validateName,
        trigger: 'blur',
      },
    ],
    fieldType: [
      {
        required: true,
        message: 'Please select the field type',
        trigger: 'blur',
      },
    ],
    encodingMethod: [
      {
        required: true,
        message: 'Please select the encoding method',
        trigger: 'blur',
      },
    ],
    compressionMethod: [
      {
        required: true,
        message: 'Please select the compression method',
        trigger: 'blur',
      },
    ],
  };
  const confirmForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid) => {
      if (valid) {
        if (data.fieldOperator === 'Add') {
          data.tableData.push(data.form);
          initForm();
        } else {
          data.tableData[data.fieldEditIndex] = data.form;
          initForm();
        }
        data.dialogVisible = false;
      }
    });
  };
  function initForm() {
    data.form = {
      name: '',
      fieldType: '',
      encodingMethod: '',
      compressionMethod: '',
    };
  }
  function openAddField() {
    data.fieldOperator = 'Add';
    data.dialogVisible = true;
  }
  function openEditField(index) {
    data.form = JSON.parse(JSON.stringify(data.tableData[index]));
    data.fieldEditIndex = index;
    data.fieldOperator = 'Edit';
    data.dialogVisible = true;
  }
  function deleteTableData(index) {
    data.tableData.splice(index, 1);
  }
  function getFields() {
    return data.tableData;
  }
  function setFields(value) {
    data.tableData = value;
  }
  defineExpose({
    getFields,
    setFields,
  });
</script>

<template>
  <el-button size="small" type="primary" color="#6E38F7" style="margin-top: 20px" @click="openAddField"
    >Add Field</el-button
  >
  <el-table :data="data.tableData" style="width: 100%; margin-top: 20px" border>
    <el-table-column label="Name" prop="name"></el-table-column>
    <el-table-column label="Field Type" prop="fieldType"></el-table-column>
    <el-table-column label="Encoding Method" prop="encodingMethod"></el-table-column>
    <el-table-column label="Compression Method" prop="compressionMethod"></el-table-column>
    <el-table-column label="Operator">
      <template #default="scope">
        <el-button
          link
          type="primary"
          @click.prevent="openEditField(scope.$index)"
          style="color: var(--color-main); font-weight: bold"
          >Edit</el-button
        >
        <el-popconfirm @confirm="deleteTableData(scope.$index)" title="Are you sure to delete this?">
          <template #reference>
            <el-button link type="danger" style="color: red; font-weight: bold">Delete</el-button>
          </template>
        </el-popconfirm>
      </template>
    </el-table-column>
  </el-table>
  <el-dialog
    v-model="data.dialogVisible"
    :close-on-click-modal="false"
    align-center
    :title="data.fieldOperator === 'Add' ? 'Create Field' : 'Edit Field'"
    width="30%"
  >
    <el-form ref="ruleFormRef" :rules="rules" :model="data.form" label-width="180" label-position="left">
      <el-form-item label="Name" prop="name">
        <el-input
          v-model="data.form.name"
          placeholder="Input the field name"
          :disabled="data.fieldOperator === 'Edit'"
        ></el-input>
      </el-form-item>
      <el-form-item label="Field Type" prop="fieldType">
        <el-select
          v-model="data.form.fieldType"
          default-first-option
          :reserve-keyword="false"
          placeholder="Choose field type"
          style="width: 100%"
        >
          <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>

      <el-form-item label="Encoding Method" prop="encodingMethod">
        <el-select style="width: 100%" v-model="data.form.encodingMethod" placeholder="Choose encoding method">
          <el-option v-for="item in encodingMethodOptions" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="Compression Method" prop="compressionMethod">
        <el-select style="width: 100%" v-model="data.form.compressionMethod" placeholder="Choose compression method">
          <el-option
            v-for="item in compressionMethodOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
    </el-form>
    <span class="dialog-footer">
      <div style="width: 100%" class="flex center">
        <el-button
          size="small"
          @click="
            data.dialogVisible = false;
            initForm();
          "
          >Cancel</el-button
        >
        <el-button size="small" type="primary" color="#6E38F7" @click="confirmForm(ruleFormRef)"> Confirm </el-button>
      </div>
    </span>
  </el-dialog>
</template>

<style lang="scss" scoped></style>
