<template>
    <Dialog :open="visible" @update:open="(open) => (open ? null : handleClose())">
        <DialogContent class="custom-nav-dialog sm:min-w-[50vw]">
            <DialogHeader>
                <DialogTitle>{{ t('nav_menu.custom_nav.dialog_title') }}</DialogTitle>
            </DialogHeader>
            <div class="custom-nav-dialog__list" v-if="localLayout.length">
                <div
                    v-for="(entry, index) in localLayout"
                    :key="entry.key || entry.id"
                    :class="['custom-nav-entry', `custom-nav-entry--${entry.type}`]">
                    <template v-if="entry.type === 'item'">
                        <div class="custom-nav-entry__info">
                            <i :class="definitionsMap.get(entry.key)?.icon"></i>
                            <span>{{ t(definitionsMap.get(entry.key)?.labelKey || entry.key) }}</span>
                        </div>
                        <div class="custom-nav-entry__controls">
                            <div class="custom-nav-entry__move">
                                <Button
                                    class="rounded-full w-6 h-6 text-xs"
                                    size="icon-sm"
                                    variant="outline"
                                    :disabled="index === 0"
                                    @click="handleMoveEntry(index, -1)">
                                    <i class="ri-arrow-up-line"></i>
                                </Button>
                                <Button
                                    class="rounded-full w-6 h-6 text-xs"
                                    size="icon-sm"
                                    variant="outline"
                                    :disabled="index === localLayout.length - 1"
                                    @click="handleMoveEntry(index, 1)">
                                    <i class="ri-arrow-down-line"></i>
                                </Button>
                            </div>
                        </div>
                    </template>
                    <template v-else>
                        <div class="custom-nav-entry__folder-header">
                            <div class="custom-nav-entry__info">
                                <i :class="entry.icon || defaultFolderIcon"></i>
                                <span>{{
                                    entry.name?.trim() || t('nav_menu.custom_nav.folder_name_placeholder')
                                }}</span>
                            </div>
                            <div class="custom-nav-entry__actions">
                                <Button
                                    size="icon-sm w-6 h-6 text-xs"
                                    variant="outline"
                                    @click="openFolderEditor(index)">
                                    <i class="ri-edit-box-line"></i>
                                    {{ t('nav_menu.custom_nav.edit_folder') }}
                                </Button>
                                <div class="custom-nav-entry__move">
                                    <Button
                                        class="rounded-full text-xs w-6 h-6"
                                        size="icon-sm"
                                        variant="outline"
                                        :disabled="index === 0"
                                        @click="handleMoveEntry(index, -1)">
                                        <i class="ri-arrow-up-line"></i>
                                    </Button>
                                    <Button
                                        class="rounded-full text-xs w-6 h-6"
                                        size="icon-sm"
                                        variant="outline"
                                        :disabled="index === localLayout.length - 1"
                                        @click="handleMoveEntry(index, 1)">
                                        <i class="ri-arrow-down-line"></i>
                                    </Button>
                                </div>
                            </div>
                        </div>
                        <div class="custom-nav-entry__folder-items">
                            <template v-if="entry.items?.length">
                                <Badge
                                    v-for="key in entry.items"
                                    :key="`${entry.id}-${key}`"
                                    variant="outline"
                                    class="custom-nav-entry__folder-tag">
                                    {{ t(definitionsMap.get(key)?.labelKey || key) }}
                                </Badge>
                            </template>
                            <span v-else class="custom-nav-entry__folder-empty">
                                {{ t('nav_menu.custom_nav.folder_empty') }}
                            </span>
                        </div>
                    </template>
                </div>
            </div>
            <!-- <el-alert
                v-if="invalidFolders.length"
                type="warning"
                :closable="false"
                :title="t('nav_menu.custom_nav.invalid_folder')" /> -->
            <DialogFooter>
                <div class="custom-nav-dialog__footer">
                    <div class="custom-nav-dialog__footer-left">
                        <Button variant="outline" @click="openFolderEditor()">
                            {{ t('nav_menu.custom_nav.add_folder') }}
                        </Button>
                        <Button variant="outline" @click="handleReset">
                            {{ t('nav_menu.custom_nav.restore_default') }}
                        </Button>
                    </div>
                    <div class="custom-nav-dialog__footer-right">
                        <Button variant="secondary" @click="handleClose">
                            {{ t('nav_menu.custom_nav.cancel') }}
                        </Button>
                        <Button :disabled="isSaveDisabled" @click="handleSave">
                            {{ t('nav_menu.custom_nav.save') }}
                        </Button>
                    </div>
                </div>
            </DialogFooter>
        </DialogContent>
    </Dialog>

    <Dialog v-model:open="folderEditor.visible">
        <DialogContent class="folder-editor-dialog sm:max-w-[50vw]">
            <DialogHeader>
                <DialogTitle>
                    {{
                        folderEditor.isEditing
                            ? t('nav_menu.custom_nav.edit_folder')
                            : t('nav_menu.custom_nav.add_folder')
                    }}
                </DialogTitle>
            </DialogHeader>
            <div class="folder-editor">
                <div class="folder-editor__form">
                    <InputGroupField
                        class="col-span-2"
                        v-model="folderEditor.data.name"
                        :placeholder="t('nav_menu.custom_nav.folder_name_placeholder')" />
                    <InputGroupField
                        class="col-span-2"
                        v-model="folderEditor.data.icon"
                        :placeholder="t('nav_menu.custom_nav.folder_icon_placeholder')">
                        <template #trailing>
                            <HoverCard>
                                <HoverCardTrigger as-child>
                                    <InputGroupButton
                                        size="icon-xs"
                                        :aria-label="t('nav_menu.custom_nav.folder_icon_placeholder')">
                                        <LinkIcon class="size-3.5" />
                                    </InputGroupButton>
                                </HoverCardTrigger>
                                <HoverCardContent side="bottom" align="end" class="w-80">
                                    <div class="text-sm leading-snug">
                                        <div>
                                            Find the icon you want on this site and paste its class name here, e.g.
                                            <span class="font-mono">ri-arrow-left-up-line</span>
                                        </div>
                                        <div class="mt-2">
                                            <a
                                                class="cursor-pointer text-blue-600"
                                                @click.prevent="openExternalLink('https://remixicon.com/')">
                                                https://remixicon.com/
                                            </a>
                                        </div>
                                    </div>
                                </HoverCardContent>
                            </HoverCard>
                        </template>
                    </InputGroupField>
                </div>
                <div class="folder-editor__lists">
                    <div class="folder-editor__column">
                        <div class="folder-editor__column-title">
                            {{ t('nav_menu.custom_nav.folder_available') }}
                        </div>
                        <div v-if="!folderEditorAvailableItems.length" class="folder-editor__empty">
                            {{ t('nav_menu.custom_nav.folder_empty') }}
                        </div>
                        <ScrollArea v-else type="always" class="folder-editor__scroll">
                            <div
                                v-for="item in folderEditorAvailableItems"
                                :key="item.key"
                                class="folder-editor__option">
                                <label class="folder-editor__option-label">
                                    <Checkbox
                                        :model-value="folderEditor.data.items.includes(item.key)"
                                        @update:modelValue="(val) => toggleFolderItem(item.key, val)" />
                                    <span>
                                        <i :class="item.icon"></i>
                                        {{ t(item.labelKey) }}
                                    </span>
                                </label>
                            </div>
                        </ScrollArea>
                    </div>
                    <div class="folder-editor__column folder-editor__column--selected">
                        <div class="folder-editor__column-title">
                            {{ t('nav_menu.custom_nav.folder_selected') }}
                        </div>
                        <div v-if="!folderEditor.data.items.length" class="folder-editor__empty">
                            {{ t('nav_menu.custom_nav.folder_selected_empty') }}
                        </div>
                        <div
                            v-for="(key, index) in folderEditor.data.items"
                            :key="`selected-${key}`"
                            class="folder-editor__selected-item">
                            <div class="folder-editor__selected-label">
                                <i :class="definitionsMap.get(key)?.icon"></i>
                                <span>{{ t(definitionsMap.get(key)?.labelKey || key) }}</span>
                            </div>
                            <div class="folder-editor__selected-actions">
                                <div class="custom-nav-entry__move">
                                    <Button
                                        class="rounded-full text-xs w-6 h-6"
                                        size="icon-sm"
                                        variant="outline"
                                        :disabled="index === 0"
                                        @click="handleFolderItemMove(index, -1)">
                                        <i class="ri-arrow-up-line"></i>
                                    </Button>
                                    <Button
                                        class="rounded-full text-xs w-6 h-6"
                                        size="icon-sm"
                                        variant="outline"
                                        :disabled="index === folderEditor.data.items.length - 1"
                                        @click="handleFolderItemMove(index, 1)">
                                        <i class="ri-arrow-down-line"></i>
                                    </Button>
                                </div>
                                <Button size="sm" variant="outline" @click="toggleFolderItem(key, false)">
                                    {{ t('nav_menu.custom_nav.remove_from_folder') }}
                                </Button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <DialogFooter>
                <div class="folder-editor__footer">
                    <Button
                        variant="destructive"
                        v-if="folderEditor.isEditing"
                        :disabled="!canDeleteFolder"
                        @click="handleFolderEditorDelete">
                        {{ t('nav_menu.custom_nav.delete_folder') }}
                    </Button>
                    <div class="folder-editor__footer-spacer"></div>
                    <Button variant="secondary" class="mr-2" @click="closeFolderEditor">
                        {{ t('nav_menu.custom_nav.cancel') }}
                    </Button>
                    <Button :disabled="folderEditorSaveDisabled" @click="handleFolderEditorSave">
                        {{ t('nav_menu.custom_nav.save') }}
                    </Button>
                </div>
            </DialogFooter>
        </DialogContent>
    </Dialog>
</template>

<script setup>
    import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
    import { computed, reactive, ref, watch } from 'vue';
    import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
    import { Button } from '@/components/ui/button';
    import { Link as LinkIcon } from 'lucide-vue-next';
    import { openExternalLink } from '@/shared/utils/common';
    import { useI18n } from 'vue-i18n';

    import dayjs from 'dayjs';

    import { InputGroupButton, InputGroupField } from '../ui/input-group';
    import { Badge } from '../ui/badge';
    import { Checkbox } from '../ui/checkbox';
    import { ScrollArea } from '../ui/scroll-area';
    import { navDefinitions } from '../../shared/constants/ui.js';

    // import IconPicker from '../IconPicker.vue';

    const props = defineProps({
        visible: {
            type: Boolean,
            default: false
        },
        layout: {
            type: Array,
            default: () => []
        },
        defaultFolderIcon: {
            type: String
        }
    });

    const emit = defineEmits(['update:visible', 'save', 'reset']);
    const { t } = useI18n();

    const cloneLayout = (source) => {
        if (!Array.isArray(source)) {
            return [];
        }
        return source.map((entry) => {
            if (entry?.type === 'folder') {
                return {
                    type: 'folder',
                    id: entry.id,
                    name: entry.name,
                    icon: entry.icon,
                    items: Array.isArray(entry.items) ? [...entry.items] : []
                };
            }
            return { type: 'item', key: entry.key };
        });
    };

    const localLayout = ref(cloneLayout(props.layout));

    const folderEditor = reactive({
        visible: false,
        isEditing: false,
        index: -1,
        data: {
            id: '',
            name: '',
            icon: '',
            items: []
        }
    });

    watch(
        () => props.visible,
        (visible) => {
            if (visible) {
                localLayout.value = cloneLayout(props.layout);
            }
        }
    );

    const definitionsMap = computed(() => {
        const map = new Map();
        navDefinitions.forEach((definition) => {
            if (definition?.key) {
                map.set(definition.key, definition);
            }
        });
        return map;
    });

    const folderEntries = computed(() => localLayout.value.filter((entry) => entry.type === 'folder'));

    const invalidFolders = computed(() =>
        folderEntries.value.filter((entry) => !entry.name?.trim() || entry.items?.length < 2)
    );

    const isSaveDisabled = computed(() => invalidFolders.value.length > 0);

    const handleMoveEntry = (index, direction) => {
        const targetIndex = index + direction;
        if (targetIndex < 0 || targetIndex >= localLayout.value.length) {
            return;
        }
        const entries = [...localLayout.value];
        const [entry] = entries.splice(index, 1);
        entries.splice(targetIndex, 0, entry);
        localLayout.value = entries;
    };

    const folderEditorSaveDisabled = computed(() => {
        const nameInvalid = !folderEditor.data.name?.trim();
        const insufficientItems = folderEditor.data.items.length < 2;
        return nameInvalid || insufficientItems;
    });

    const canDeleteFolder = computed(() => {
        return localLayout.value[folderEditor.index]?.type === 'folder';
    });

    const usedKeysExcludingEditor = computed(() => {
        const set = new Set();
        localLayout.value.forEach((entry) => {
            if (entry.type !== 'folder') {
                return;
            }
            if (folderEditor.isEditing && entry.id === folderEditor.data.id) {
                return;
            }
            entry.items?.forEach((key) => set.add(key));
        });
        return set;
    });

    const folderEditorAvailableItems = computed(() =>
        navDefinitions.filter(
            (definition) =>
                !usedKeysExcludingEditor.value.has(definition.key) || folderEditor.data.items.includes(definition.key)
        )
    );

    const openFolderEditor = (index) => {
        const isEditing = index !== undefined && index !== null;
        folderEditor.isEditing = isEditing;
        folderEditor.index = isEditing ? index : -1;
        if (folderEditor.isEditing) {
            const entry = localLayout.value[index];
            folderEditor.data = {
                id: entry.id,
                name: entry.name,
                icon: entry.icon,
                items: Array.isArray(entry.items) ? [...entry.items] : []
            };
        } else {
            folderEditor.data = {
                id: `custom-folder-${dayjs().toISOString()}-${Math.random().toString().slice(2, 7)}`,
                name: '',
                icon: '',
                items: []
            };
        }
        folderEditor.visible = true;
    };

    const closeFolderEditor = () => {
        folderEditor.visible = false;
    };

    const toggleFolderItem = (key, enabled) => {
        if (enabled) {
            if (!folderEditor.data.items.includes(key)) {
                folderEditor.data.items.push(key);
            }
        } else {
            folderEditor.data.items = folderEditor.data.items.filter((item) => item !== key);
        }
    };

    const handleFolderItemMove = (index, direction) => {
        const targetIndex = index + direction;
        if (targetIndex < 0 || targetIndex >= folderEditor.data.items.length) {
            return;
        }
        const items = [...folderEditor.data.items];
        const [item] = items.splice(index, 1);
        items.splice(targetIndex, 0, item);
        folderEditor.data.items = items;
    };

    const applyFolderChanges = () => {
        const sanitizedItems = folderEditor.data.items.filter((key) => definitionsMap.value.has(key));
        const sanitizedIcon = folderEditor.data.icon?.trim() || '';
        const entries = [...localLayout.value];

        if (folderEditor.isEditing) {
            const targetIndex = folderEditor.index;
            if (targetIndex < 0) {
                return;
            }
            const existing = entries[targetIndex];
            if (!existing || existing.type !== 'folder') {
                return;
            }
            const removedItems = existing.items.filter((key) => !sanitizedItems.includes(key));
            entries.splice(targetIndex, 1);

            const filteredEntries = entries.filter(
                (entry) => !(entry.type === 'item' && sanitizedItems.includes(entry.key))
            );

            filteredEntries.splice(targetIndex, 0, {
                type: 'folder',
                id: folderEditor.data.id,
                name: folderEditor.data.name.trim(),
                icon: sanitizedIcon,
                items: sanitizedItems
            });

            if (removedItems.length) {
                const insertItems = removedItems.map((key) => ({ type: 'item', key }));
                filteredEntries.splice(targetIndex + 1, 0, ...insertItems);
            }

            localLayout.value = filteredEntries;
            return;
        }

        const filteredEntries = entries.filter(
            (entry) => !(entry.type === 'item' && sanitizedItems.includes(entry.key))
        );

        filteredEntries.push({
            type: 'folder',
            id: folderEditor.data.id,
            name: folderEditor.data.name.trim(),
            icon: sanitizedIcon,
            items: sanitizedItems
        });

        localLayout.value = filteredEntries;
    };

    const handleFolderEditorSave = () => {
        if (folderEditorSaveDisabled.value) {
            return;
        }
        applyFolderChanges();
        closeFolderEditor();
    };

    const handleFolderEditorDelete = () => {
        if (!folderEditor.isEditing) {
            return;
        }
        const entries = [...localLayout.value];
        const targetIndex = folderEditor.index;
        if (targetIndex < 0) {
            return;
        }
        const folder = entries[targetIndex];
        if (!folder || folder.type !== 'folder') {
            return;
        }
        entries.splice(targetIndex, 1);
        const restoredItems = (folder.items || []).map((key) => ({ type: 'item', key }));
        entries.splice(targetIndex, 0, ...restoredItems);
        localLayout.value = entries;
        closeFolderEditor();
    };

    const handleSave = () => {
        if (isSaveDisabled.value) {
            return;
        }
        emit('save', cloneLayout(localLayout.value));
    };

    const handleReset = () => {
        emit('reset');
    };

    const handleClose = () => {
        emit('update:visible', false);
    };
</script>

<style scoped>
    .custom-nav-dialog__list {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 12px;
        overflow-y: auto;
        padding-right: 4px;
    }

    .custom-nav-entry {
        background: var(--card);
        border: 1px solid var(--border);
        border-radius: 8px;
        padding: 10px 12px;
        display: flex;
        flex-direction: column;
        gap: 8px;
        width: 100%;
        margin: 0 auto;
    }

    .custom-nav-entry__info {
        display: flex;
        align-items: center;
        gap: 8px;
        font-weight: 500;
    }

    .custom-nav-entry__info i {
        font-size: 16px;
    }

    .custom-nav-entry__controls {
        display: flex;
        justify-content: flex-end;
    }

    .custom-nav-entry__move {
        display: flex;
        gap: 4px;
    }

    .custom-nav-entry__folder-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 12px;
        flex-wrap: wrap;
    }

    .custom-nav-entry__actions {
        display: flex;
        align-items: center;
        gap: 8px;
    }

    .custom-nav-entry__folder-items {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
    }

    .custom-nav-entry__folder-tag {
        margin: 0;
    }

    .custom-nav-entry__folder-empty {
        font-size: 12px;
    }

    .custom-nav-dialog__footer {
        display: flex;
        justify-content: space-between;
        align-items: center;
        width: 100%;
    }

    .custom-nav-dialog__footer-left {
        display: flex;
        gap: 8px;
    }

    .custom-nav-dialog__footer-right {
        display: flex;
        gap: 8px;
    }

    .folder-editor__form {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 8px;
        align-items: center;
        margin-bottom: 12px;
    }

    .folder-editor__icon-picker {
        justify-self: end;
    }

    .folder-editor__lists {
        display: grid;
        grid-template-columns: minmax(220px, 0.9fr) minmax(260px, 1.1fr);
        gap: 12px;
    }

    .folder-editor__column {
        border-radius: 8px;
        padding: 10px;
        min-height: 220px;
        display: flex;
        flex-direction: column;
    }

    .folder-editor__column-title {
        font-weight: 600;
        margin-bottom: 8px;
    }

    .folder-editor__empty {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 12px;
        text-align: center;
    }

    .folder-editor__scroll {
        max-height: 240px;
    }

    .folder-editor__option {
        padding: 4px 0;
    }

    .folder-editor__option-label {
        display: inline-flex;
        align-items: center;
        gap: 6px;
    }

    .folder-editor__option-label i {
        font-size: 14px;
    }

    .folder-editor__selected-item {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 6px 0;
    }

    .folder-editor__selected-item:last-child {
        border-bottom: none;
    }

    .folder-editor__selected-label {
        display: flex;
        align-items: center;
        gap: 8px;
        flex: 1;
        min-width: 0;
    }

    .folder-editor__selected-label i {
        font-size: 14px;
    }

    .folder-editor__selected-actions {
        display: flex;
        align-items: center;
        gap: 8px;
        flex-wrap: wrap;
    }

    .folder-editor__column--selected {
        min-height: 260px;
    }

    .folder-editor__footer {
        display: flex;
        align-items: center;
        width: 100%;
    }

    .folder-editor__footer-spacer {
        flex: 1;
    }
</style>
