<template>
  <kuc-text
    v-if="valueType === 'kuc-text'"
    :value="modelValue.value"
    @change="updateValue"
    :className="needPlaceholderWidthClass"
    :placeholder="placeholder"
    :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
  />
  <kuc-combobox
    v-else-if="valueType === 'kuc-combobox'"
    :value="modelValue.value"
    @change="updateValue"
    :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
  />
  <kuc-time-picker
    v-else-if="valueType === 'kuc-time'"
    :value="modelValue.value"
    @change="updateValue"
    :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
  />
  <table-condition-value-date-time
    v-else-if="valueType === 'datetime' || valueType === 'date'"
    :time="valueType === 'datetime'"
    :value="modelValue.value as string"
    @change="updateValue"
    :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
  />
  <kuc-multi-choice
    v-else-if="isMultiChoice"
    :value="multiChoice"
    :items="multiChoiceItems"
    @change="updateMultiChoice"
    :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
  />
  <table-condition-value-multi-input
    v-else-if="isMultiInput"
    :value="multiInput"
    @change="updateMultiInput"
    :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
  />
</template>

<script setup lang="ts">
import { getComponent, multiValueComponent } from '@/js/conditions';
import { getFieldObj, isStringArray, search } from '@/js/helper';
import { isType } from '@/js/kintone-rest-api-client';
import { isSelectType } from '@/js/mapping';
import type { CachedSelectedAppData, StringValue, WhereCondition } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone';
import type {
  ComboboxChangeEventDetail,
  TextInputEventDetail,
  MultiChoiceChangeEventDetail,
} from 'kintone-ui-component';
import { defineProps, defineEmits, computed, type Ref, inject, provide, ref, watch, watchEffect } from 'vue';

const props = defineProps<{
  modelValue: Ref<StringValue>;
  selectedAppData: CachedSelectedAppData;
  whereConditions: WhereCondition[];
  id: string;
  canSave: (canSave: boolean) => void;
}>();

provide('canSave', props.canSave);

const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);

const needPlaceholderWidthClass = computed(() => (placeholder.value ? 'kuc-text-input-placeholder-width' : ''));

const placeholder = computed(() => {
  const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
  if (isType.GROUP_SELECT(field)) {
    return 'グループコードをカンマ区切りで指定';
  } else if (isType.ORGANIZATION_SELECT(field)) {
    return '組織コードをカンマ区切りで指定';
  } else if (isType.USER_SELECT(field) || isType.CREATOR(field) || isType.MODIFIER(field)) {
    return 'ログイン名をカンマ区切りで指定';
  }
  return '';
});

const valueType = computed(() => {
  const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
  return getComponent(whereCondition.value?.condition || '', field);
});

type EmitData = {
  obj?: WhereCondition;
  value: StringValue;
};

const emit = defineEmits<{
  (e: 'update:modelValue', data: EmitData): void;
}>();

const updateValue = (event: KucEvent<ComboboxChangeEventDetail | TextInputEventDetail>) => {
  emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value || '' });
};

// multi choice
const isMultiChoice = computed(() => valueType.value === multiValueComponent.multiChoice);

const multiChoice = computed(() => {
  if (!isMultiChoice.value) {
    return props.modelValue.value;
  }
  return isStringArray(props.modelValue.value) ? props.modelValue.value : [];
});

const multiChoiceItems = computed(() => {
  if (!isMultiChoice.value) {
    return [];
  }
  const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
  const items = [{ label: '--', value: '' }];

  if (field && isSelectType(field)) {
    const multiOpts = Object.values(field.options).map((opt) => ({ label: opt.label, value: opt.label }));
    items.push(...multiOpts);
  }
  return items;
});

const updateMultiChoice = (event: KucEvent<MultiChoiceChangeEventDetail>) => {
  emit('update:modelValue', { obj: whereCondition.value, value: event.detail.value || [] });
};

// multi input
const isMultiInput = computed(() => valueType.value === multiValueComponent.multiInput);
const multiInput = computed(() => {
  if (!isMultiInput.value) {
    return props.modelValue.value as string[];
  }
  return isStringArray(props.modelValue.value) ? props.modelValue.value as string[] : ['', ''];
});

const updateMultiInput = (event: KucEvent<string[]>) => {
  emit('update:modelValue', { obj: whereCondition.value, value: event.detail || ['', ''] });
};
</script>
