<template>
    <div>
        <q-field :label="displayName" labelColor="primary" stack-label>
            <template v-slot:control>
                <q-card flat class="full-width">
                    <q-card-actions vertical>
                        <q-btn color="grey-3" text-color="black" :disable="btnDisable"
                            @click="() => { dgIsShow = true }">クリックで設定</q-btn>
                    </q-card-actions>
                    <q-card-section class="text-caption">
                        <div v-if="mappingObjectsInputDisplay && mappingObjectsInputDisplay.length > 0">
                            <div v-for="(item) in mappingObjectsInputDisplay" :key="item">{{ item }}</div>
                        </div>
                        <div v-else>{{ placeholder }}</div>
                    </q-card-section>
                </q-card>
            </template>
        </q-field>
        <show-dialog v-model:visible="dgIsShow" name="データマッピング" @close="closeDg" min-width="50vw" min-height="60vh">

            <div class="q-mx-md">
                <div class="row q-col-gutter-x-xs flex-center">
                    <div class="col-5">
                        <div class="q-mx-xs">ソース</div>
                    </div>
                    <div class="col-1">
                    </div>
                    <div class="col-5">
                        <div class="q-mx-xs">目標</div>
                    </div>
                    <div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addMappingObject" />
                    </div>
                </div>
                <div class="q-my-sm" v-for="(item, index) in mappingProps" :key="item.id">
                    <div class="row q-col-gutter-x-xs flex-center">
                        <div class="col-5">
                            <ConditionObject :config="config" v-model="item.from" />
                        </div>
                        <div class="col-1">
                        </div>
                        <div class="col-5">
                            <q-field v-model="item.vName" type="text" outlined dense>
                                <template v-slot:append>
                                    <q-icon name="search" class="cursor-pointer"
                                        @click="() => { mappingProps[index].to.isDialogVisible = true }" />
                                </template>
                                <template v-slot:control>
                                    <div class="self-center full-width no-outline" tabindex="0"
                                        v-if="item.to.app?.name && item.to.fields?.length > 0 && item.to.fields[0].label">
                                        {{ `${item.to.app?.name} : ${item.to.fields[0].label}` }}
                                    </div>
                                </template>
                            </q-field>
                        </div>
                        <div class="col-1">
                            <q-btn flat round dense icon="delete" size="sm" @click="() => deleteMappingObject(index)" />
                        </div>
                    </div>

                    <show-dialog v-model:visible="mappingProps[index].to.isDialogVisible" name="フィールド一覧"
                        @close="closeToDg" ref="fieldDlg">
                        <FieldSelect v-if="onlySourceSelect" ref="fieldDlg" name="フィールド" :appId="sourceAppId" not_page
                            :selectedFields="mappingProps[index].to.fields"
                            :updateSelects="(fields) => { mappingProps[index].to.fields = fields; mappingProps[index].to.app = sourceApp }">
                        </FieldSelect>
                        <AppFieldSelectBox v-else v-model:selectedField="mappingProps[index].to" />
                    </show-dialog>
                </div>
            </div>
        </show-dialog>
    </div>
</template>

<script lang="ts">
import { v4 as uuidv4 } from 'uuid';
import { computed, defineComponent, reactive, ref, watchEffect } from 'vue';
import ConditionObject from '../ConditionEditor/ConditionObject.vue';
import ShowDialog from '../ShowDialog.vue';
import AppFieldSelectBox from '../AppFieldSelectBox.vue';
import FieldSelect from '../FieldSelect.vue';
import IAppFields from './AppFieldSelect.vue';

type Props = {
    props?: {
        name: string;
        modelValue?: {
            app: {
                id: string;
                name: string;
            }
        }
    }
};
type ValueType = {
    id: string;
    from: object;
    to: typeof IAppFields & {
        isDialogVisible: boolean;
    };
}

const defaultMappingProp = () => ({ id: uuidv4(), from: {}, to: { app: {}, fields: [], isDialogVisible: false } });

export default defineComponent({
    name: 'DataMapping',
    inheritAttrs: false,
    components: {
        ShowDialog,
        ConditionObject,
        AppFieldSelectBox,
        FieldSelect
    },
    props: {
        context: {
            type: Array<Props>,
            default: '',
        },
        displayName: {
            type: String,
            default: '',
        },
        name: {
            type: String,
            default: '',
        },
        modelValue: {
            type: Object as () => ValueType[],
        },
        placeholder: {
            type: String,
            default: '',
        },
        onlySourceSelect: {
            type: Boolean,
            default: false
        }
    },

    setup(props, { emit }) {
        const closeDg = () => {
            emit('update:modelValue', mappingProps
            );
        }

        const closeToDg = () => {
            emit('update:modelValue', mappingProps
            );
        }

        const mappingProps: ValueType[] = props.modelValue
            ? props.modelValue
            : reactive([defaultMappingProp()]);


        const deleteMappingObject = (index: number) => mappingProps.length === 1
            ? mappingProps.splice(0, mappingProps.length, defaultMappingProp())
            : mappingProps.splice(index, 1);

        const mappingObjectsInputDisplay = computed(() =>
            mappingProps ?
                mappingProps
                    .filter(item => item.from?.sharedText && item.to.fields?.length > 0)
                    .map(item => {
                        return `field(${item.to.app?.id},${item.to.fields[0].label}) = ${item.from.sharedText} `;
                    })
                : []
        );

        const source = props.context.find(element => element?.props?.name === 'sources')

        const sourceApp = computed(() => source?.props?.modelValue?.app);

        const sourceAppId = computed(() => sourceApp.value?.id);

        const btnDisable = computed(() => props.onlySourceSelect ? !(source?.props?.modelValue?.app?.id) : false);

        //集計処理方法

        watchEffect(() => {
            emit('update:modelValue', mappingProps);
        });
        return {
            uuidv4,
            dgIsShow: ref(false),
            closeDg,
            toDgIsShow: ref(false),
            closeToDg,
            mappingProps,
            addMappingObject: () => mappingProps.push(defaultMappingProp()),
            deleteMappingObject,
            mappingObjectsInputDisplay,
            sourceApp,
            sourceAppId,
            btnDisable,
            config: {
                canInput: false,
                buttonsConfig: [
                    { label: '変数', color: 'green', type: 'VariableAdd' },
                ]
            }
        };
    },
});
</script>
<style lang="scss"></style>
