<template>
  <div>
    <q-stepper v-model="step" ref="stepper" color="primary" animated flat>
      <q-step :name="1" title="データソースの設定" icon="app_registration" :done="step > 1">
        <div class="row justify-between items-center">
          <div>アプリの選択 :</div>
          <div>
            <a v-if="data.sourceApp?.name" class="q-mr-xs"
              :href="data.sourceApp ? `${authStore.currentDomain.kintoneUrl}/k/${data.sourceApp.id}` : ''"
              target="_blank" title="Kiontoneへ">
              {{ data.sourceApp?.name }}
            </a>
            <div v-else class="text-red">APPを選択してください</div>
            <q-btn v-if="data.sourceApp?.name" flat color="grey" icon="clear" size="sm" padding="none"
              @click="clearSelectedApp" />
          </div>
          <q-btn outline dense label="変更" padding="xs sm" color="primary" @click="showAppDialog" />
        </div>

        <!-- フィールド設定部分 -->
        <template v-if="data.sourceApp?.name">
          <q-separator class="q-mt-md" />
          <div class="q-my-md row justify-between items-center">
            データ階層を設定する :
            <q-btn icon="add" size="sm" padding="xs" outline color="primary" @click="addRow" />
          </div>
          <q-virtual-scroll style="max-height: 13.5rem;" :items="data.fieldList" separator v-slot="{ item, index }">
            <div class="row justify-between items-center q-my-md">
              <div>{{ index + 1 }}階層 :</div>
              <div>{{ item.source?.name }}</div>
              <q-btn-group outline>
                <q-btn outline dense label="変更" padding="xs sm" color="primary"
                  @click="() => showFieldDialog(item, 'source')" />
                <q-btn outline dense label="削除" padding="xs sm" color="primary" @click="() => delRow(index)" />
              </q-btn-group>
            </div>
          </q-virtual-scroll>
        </template>

        <!-- アプリ選択ダイアログ -->
        <ShowDialog v-model:visible="data.sourceApp.showSelectApp" name="アプリ選択" @close="closeAppDialog" min-width="50vw"
          min-height="50vh">
          <template v-slot:toolbar>
            <q-input dense debounce="300" v-model="data.sourceApp.appFilter" placeholder="検索" clearable>
              <template v-slot:before>
                <q-icon name="search" />
              </template>
            </q-input>
          </template>
          <AppSelectBox ref="appDg" name="アプリ" type="single" :filter="data.sourceApp.appFilter" />
        </ShowDialog>
      </q-step>

      <q-step :name="2" title="ドロップダウンフィールドの設定" icon="multiple_stop"  :done="step > 2">
        <div class="row q-pa-sm q-col-gutter-x-sm flex-center">
          <div class="col-grow row q-col-gutter-x-sm">
            <div class="col-6">データソース</div>
            <div class="col-6">ドロップダウンフィールド</div>
          </div>
          <div class="col-auto">
            <div style="width: 88px; height: 1px;"></div>
          </div>
        </div>
        <div v-for="(item) in data.fieldList" :key="item.id" class="row q-pa-sm q-col-gutter-x-sm flex-center">
          <div class="col-grow row q-col-gutter-x-sm">

            <div class="col-6">{{ item.source.name }}</div>
            <div class="col-6">{{ item.dropDown?.name }}</div>
          </div>
          <div class="col-auto">
            <div class="row justify-end">
              <q-btn-group outline>
                <q-btn outline dense label="設定" padding="xs sm" color="primary"
                  @click="() => showFieldDialog(item, 'dropDown')" />
                <q-btn outline dense label="クリア" padding="xs sm" color="primary"
                  @click="() => item.dropDown = undefined" />
              </q-btn-group>
            </div>
          </div>
        </div>
      </q-step>

      <!-- ステップナビゲーション -->
      <template v-slot:navigation>
        <q-stepper-navigation>
          <div class="row justify-end q-mt-md">
            <q-btn v-if="step > 1"  flat color="primary" @click="$refs.stepper.previous()" label="戻る" class="q-ml-sm" />
            <q-btn @click="stepperNext"  color="primary" :label="step === 2 ? '確定' : '次へ'"
              :disable="nextBtnCheck()" />
          </div>
        </q-stepper-navigation>
      </template>
    </q-stepper>

    <!-- フィールド選択ダイアログ -->
    <template v-for="(item, index) in data.fieldList" :key="`dg${item.id}`">
      <show-dialog v-model:visible="item.sourceDg.show" name="フィールド一覧" min-width="400px">
        <template v-slot:toolbar>
          <q-input dense debounce="300" v-model="item.sourceDg.filter" placeholder="検索" clearable>
            <template v-slot:before>
              <q-icon name="search" />
            </template>
          </q-input>
        </template>
        <FieldSelect name="フィールド" :appId="data.sourceApp.id" :selectedFields="item.source"
          :filter="item.sourceDg.filter" :updateSelectFields="(f) => updateSelectField(f, item, index, 'source')"
          :blackListLabel="blackListLabel" />
      </show-dialog>

      <show-dialog v-model:visible="item.dropDownDg.show" name="フィールド一覧" min-width="400px">
        <template v-slot:toolbar>
          <q-input dense debounce="300" v-model="item.dropDownDg.filter" placeholder="検索" clearable>
            <template v-slot:before>
              <q-icon name="search" />
            </template>
          </q-input>
        </template>
        <FieldSelect name="フィールド" :appId="data.dropDownApp.id" :selectedFields="item.source"
          :filter="item.dropDownDg.filter" :updateSelectFields="(f) => updateSelectField(f, item, index, 'dropDown')"
          :blackListLabel="blackListLabel" />
      </show-dialog>
    </template>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, ref, watchEffect,watch } from 'vue';
import ShowDialog from './ShowDialog.vue';
import AppSelectBox from './AppSelectBox.vue';
import FieldSelect from './FieldSelect.vue';
import { useAuthStore } from 'src/stores/useAuthStore';
import { useFlowEditorStore } from 'src/stores/flowEditor';
import { v4 as uuidv4 } from 'uuid';
import { useQuasar } from 'quasar';

export default defineComponent({
  name: 'CascadingDropDownBox',
  inheritAttrs: false,
  components: { ShowDialog, AppSelectBox, FieldSelect },
  props: {
    modelValue: {
      type: Object,
      default: () => ({})
    },
    finishDialogHandler: Function,
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const authStore = useAuthStore();
    const flowStore = useFlowEditorStore();
    const $q = useQuasar();
    const appDg = ref();
    const stepper = ref();
    const step = ref(1);

    const data =ref(props.modelValue);
    // const data = ref({
    //   sourceApp: props.modelValue.sourceApp ?? { appFilter: '', showSelectApp: false },
    //   dropDownApp: props.modelValue.dropDownApp,
    //   fieldList: props.modelValue.fieldList ?? [],
    // });

    // アプリ関連の関数
    const showAppDialog = () => data.value.sourceApp.showSelectApp = true;

    const clearSelectedApp = () => {
      data.value.sourceApp = { appFilter: '', showSelectApp: false };
      data.value.fieldList = [];
    };

    const closeAppDialog = (val: 'OK' | 'Cancel') => {
      data.value.sourceApp.showSelectApp = false;
      const selected = appDg.value?.selected[0];
      if (val === 'OK' && selected) {
        if (flowStore.appInfo?.appId === selected.id) {
          $q.notify({
            type: 'negative',
            caption: 'エラー',
            message: 'データソースを現在のアプリにすることはできません。'
          });
        } else if (selected.id !== data.value.sourceApp.id) {
          clearSelectedApp();
          Object.assign(data.value.sourceApp, { id: selected.id, name: selected.name });
        }
      }
    };

    // フィールド関連の関数
    const defaultRow = () => ({
      id: uuidv4(),
      source: undefined,
      dropDown: undefined,
      sourceDg: { show: false, filter: '' },
      dropDownDg: { show: false, filter: '' },
    });

    const addRow = () => data.value.fieldList.push(defaultRow());
    const delRow = (index: number) => data.value.fieldList.splice(index, 1);

    const showFieldDialog = (item: any, keyName: string) => item[`${keyName}Dg`].show = true;

    const updateSelectField = (f: any, item: any, index: number, keyName: 'source' | 'dropDown') => {
      const [selected] = f.value;
      const isDuplicate = data.value.fieldList.some((field, idx) =>
        idx !== index && (field[keyName]?.code === selected.code || field[keyName]?.label === selected.label)
      );

      if (isDuplicate) {
        $q.notify({
          type: 'negative',
          caption: 'エラー',
          message: '重複したフィールドは選択できません'
        });
      } else {
        item[keyName] = selected;
      }
    };

    // ステッパー関連の関数
    const nextBtnCheck = () => {
      const stepNo = step.value
      if (stepNo === 1) {
        return !(data.value.sourceApp?.id && data.value.fieldList?.length > 0 && data.value.fieldList?.every(f => f.source?.name));
      } else if (stepNo === 2) {
        return !data.value.fieldList?.every(f => f.dropDown?.name);
      }
      return true;
    };

    const stepperNext = () => {
      if (step.value === 2) {
        props.finishDialogHandler?.(data.value);
      } else {
        data.value.dropDownApp = { name: flowStore.appInfo?.name, id: flowStore.appInfo?.appId };
        stepper.value?.next();
      }
    };

    // // データ変更の監視
    // watchEffect(() =>{
    //   emit('update:modelValue', data.value);
    // });

    return {
      // 状態と参照
      authStore,
      step,
      stepper,
      appDg,
      data,
      // アプリ関連の関数
      showAppDialog,
      closeAppDialog,
      clearSelectedApp,

      // フィールド関連の関数
      addRow,
      delRow,
      showFieldDialog,
      updateSelectField,

      // ステッパー関連の関数
      nextBtnCheck,
      stepperNext,

      // 定数
      blackListLabel: ['レコード番号', '作業者', '更新者', '更新日時', '作成日時', '作成者', 'カテゴリー', 'ステータス'],
    };
  }
});
</script>
