<template>
  <kuc-table className='plugin-kuc-table' :columns="columns" :data="modelValue"/>
</template>

<script setup lang="ts">
import type { CachedData, CachedSelectedAppData, FieldsJoinMapping, WhereCondition } from '@/types/model';
import { defineProps, inject, computed, reactive, render, h } from 'vue';
import { generateId, getFieldObj, getFieldsDropdownItems, search } from '@/js/helper';
import { getLeftAvailableJoinType, getRightAvailableJoinType, isLeftJoinForceDisable, isRightJoinForceDisable,  } from '@/js/join';
import { getLeftAvailableMappingType, getRightAvailableMappingType } from '@/js/mapping';
import TableCombobox from './TableCombobox.vue';
import { type FieldType, type OneOf } from '@/js/kintone-rest-api-client';

const props = defineProps<{
  connector: string;
  modelValue: FieldsJoinMapping[];
  type: 'connect' | 'mapping';
}>();

const cachedData = inject<CachedData>('cachedData') as CachedData;
const selectedAppData = inject<CachedSelectedAppData>('selectedAppData') as CachedSelectedAppData;
const table = computed(() => selectedAppData.table.table);

const filterFunc = {
  connect: {
    left: (right?: OneOf | '') => getLeftAvailableJoinType(right),
    right: (left?: OneOf | '') => getRightAvailableJoinType(left),
  },
  mapping: {
    left: (right?: OneOf | '') => getLeftAvailableMappingType(right),
    right: (left?: OneOf | '') => getRightAvailableMappingType(left),
  },
};

const columns = reactive([
  {
    title: '取得元アプリのフィールド',
    field: 'leftField',
    render: (cellData: string, rowData: WhereCondition) => {
      if (!rowData.id) {
        rowData.id = generateId();
      }
      const container = document.createElement('div');
      const vnode = h(TableCombobox, {
        items: computed(() => {
          const dependFilterField = getField('rightField', rowData.id);
          return getFieldsDropdownItems(selectedAppData.appFields, {
            subTableCode: table.value,
            baseFilter: filterFunc[props.type].left() as FieldType[],
            filterType: filterFunc[props.type].left(dependFilterField),
            dependFilterField,
            defaultDisableCallback: isLeftJoinForceDisable,
          });
        }),
        modelValue: computed(() => (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.leftField || ''),
        selectedAppData,
        dataList: props.modelValue,
        id: rowData.id,
        'onUpdate:modelValue': (data) => {
          if (data.obj) {
            (data.obj as FieldsJoinMapping).leftField = data.value;
          }
        },
      });
      render(vnode, container);
      return container;
    },
  },
  {
    title: '',
    field: 'connector',
    render: () => {
      return props.connector;
    },
  },
  {
    title: 'このアプリのフィールド',
    field: 'rightField',
    render: (cellData: string, rowData: WhereCondition) => {
      if (!rowData.id) {
        rowData.id = generateId();
      }
      const container = document.createElement('div');
      const vnode = h(TableCombobox, {
        items: computed(() => {
          const dependFilterField = getField('leftField', rowData.id);
          return getFieldsDropdownItems(cachedData.currentAppFields, {
            subTableCode: '', // subtable not allowed for current app
            baseFilter: filterFunc[props.type].right() as FieldType[],
            filterType: filterFunc[props.type].right(dependFilterField),
            dependFilterField,
            defaultDisableCallback: props.type === 'connect' ? isRightJoinForceDisable : undefined,
          });
        }),
        modelValue: computed(() => (search(props.modelValue, rowData.id) as FieldsJoinMapping)?.rightField || ''),
        selectedAppData,
        dataList: props.modelValue,
        id: rowData.id,
        'onUpdate:modelValue': (data) => {
          if (data.obj) {
            (data.obj as FieldsJoinMapping).rightField = data.value;
          }
        },
      });
      render(vnode, container);
      return container;
    },
  },
]);

function getField(key: 'leftField' | 'rightField', id: string) {
  const dataRow = search(props.modelValue, id) as FieldsJoinMapping | undefined;
  const fieldCode = dataRow ? dataRow[key] || '' : '';
  const targetFieldMap = key === 'leftField' ? selectedAppData.appFields : cachedData.currentAppFields;
  const targetTable = key === 'leftField' ? table.value : '';
  return getFieldObj(fieldCode, targetFieldMap, targetTable);
}
</script>
