<script setup>
import { computed, ref, watch } from 'vue'
import { router } from '@inertiajs/vue3'
import { VueDraggable } from 'vue-draggable-plus'

const props = defineProps({
    songId: {
        type: Number,
        required: true,
    },
    arrangements: {
        type: Array,
        required: true,
    },
    availableGroups: {
        type: Array,
        required: true,
    },
    selectedArrangementId: {
        type: Number,
        default: null,
    },
})

const emit = defineEmits(['arrangement-selected'])

const selectedId = ref(
    props.selectedArrangementId ?? props.arrangements.find((item) => item.is_default)?.id ?? props.arrangements[0]?.id ?? null,
)

const arrangementGroups = ref([])
const poolGroups = ref([])

const selectedArrangement = computed(() =>
    props.arrangements.find((arrangement) => arrangement.id === Number(selectedId.value)) ?? null,
)

watch(
    () => props.availableGroups,
    (groups) => {
        poolGroups.value = groups.map((group) => ({ ...group }))
    },
    { immediate: true, deep: true },
)

watch(
    selectedArrangement,
    (arrangement) => {
        arrangementGroups.value = arrangement?.groups?.map((group) => ({ ...group })) ?? []
    },
    { immediate: true },
)

watch(
    selectedId,
    (arrangementId) => {
        emit('arrangement-selected', Number(arrangementId))
    },
)

const colorMap = computed(() => {
    const map = {}

    poolGroups.value.forEach((group) => {
        map[group.id] = group.color
    })

    arrangementGroups.value.forEach((group) => {
        map[group.id] = group.color
    })

    return map
})

const groupPillStyle = (group) => ({
    backgroundColor: group.color,
})

const addArrangement = () => {
    const name = window.prompt('Name des neuen Arrangements')

    if (!name) {
        return
    }

    router.post(
        `/songs/${props.songId}/arrangements`,
        { name },
        {
            preserveScroll: true,
        },
    )
}

const cloneArrangement = () => {
    if (!selectedArrangement.value) {
        return
    }

    const name = window.prompt('Name des neuen Arrangements', `${selectedArrangement.value.name} Kopie`)

    if (!name) {
        return
    }

    router.post(
        `/arrangements/${selectedArrangement.value.id}/clone`,
        { name },
        {
            preserveScroll: true,
        },
    )
}

const removeGroupAt = (index) => {
    arrangementGroups.value.splice(index, 1)
    saveArrangement()
}

const syncPoolColor = (groupId, color) => {
    poolGroups.value = poolGroups.value.map((group) => {
        if (group.id !== groupId) {
            return group
        }

        return {
            ...group,
            color,
        }
    })
}

const updateGroupColor = (group, color) => {
    group.color = color
    syncPoolColor(group.id, color)
    saveArrangement()
}

const saveArrangement = () => {
    if (!selectedArrangement.value) {
        return
    }

    router.put(
        `/arrangements/${selectedArrangement.value.id}`,
        {
            groups: arrangementGroups.value.map((group, index) => ({
                song_group_id: group.id,
                order: index + 1,
            })),
            group_colors: colorMap.value,
        },
        {
            preserveScroll: true,
            preserveState: true,
        },
    )
}

const deleteArrangement = () => {
    if (!selectedArrangement.value) {
        return
    }

    router.delete(`/arrangements/${selectedArrangement.value.id}`, {
        preserveScroll: true,
    })
}
</script>

<template>
    <div data-testid="arrangement-configurator" class="space-y-4 rounded-lg border border-gray-200 bg-white p-4">
        <div class="flex flex-wrap items-end gap-3">
            <div class="min-w-64 flex-1">
                <label
                    for="arrangement-select"
                    class="mb-1 block text-sm font-medium text-gray-700"
                >
                    Arrangement
                </label>
                <select
                    data-testid="arrangement-select"
                    id="arrangement-select"
                    v-model="selectedId"
                    class="block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
                >
                    <option
                        v-for="arrangement in arrangements"
                        :key="arrangement.id"
                        :value="arrangement.id"
                    >
                        {{ arrangement.name }}
                    </option>
                </select>
            </div>

            <button
                data-testid="arrangement-add-button"
                type="button"
                class="rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white shadow hover:bg-blue-700"
                @click="addArrangement"
            >
                Hinzufügen
            </button>

            <button
                data-testid="arrangement-clone-button"
                type="button"
                class="rounded-md bg-slate-700 px-4 py-2 text-sm font-semibold text-white shadow hover:bg-slate-800"
                @click="cloneArrangement"
            >
                Klonen
            </button>

            <button
                data-testid="arrangement-delete-button"
                type="button"
                class="rounded-md bg-red-600 px-4 py-2 text-sm font-semibold text-white shadow hover:bg-red-700"
                @click="deleteArrangement"
            >
                Löschen
            </button>
        </div>

        <div class="grid gap-4 lg:grid-cols-2">
            <div class="space-y-2">
                <h4 class="text-sm font-semibold uppercase tracking-wide text-gray-600">
                    Verfügbare Gruppen
                </h4>

                <VueDraggable
                    v-model="poolGroups"
                    :group="{ name: 'song-groups', pull: 'clone', put: false }"
                    :sort="false"
                    class="min-h-24 rounded-lg border border-dashed border-gray-300 bg-gray-50 p-3"
                >
                    <div
                        v-for="group in poolGroups"
                        :key="group.id"
                        class="mb-2 flex items-center gap-2 rounded-md border border-gray-200 bg-white p-2"
                    >
                        <span
                            class="inline-flex rounded-full px-3 py-1 text-sm font-semibold text-white"
                            :style="groupPillStyle(group)"
                        >
                            {{ group.name }}
                        </span>

                        <label class="ml-auto flex items-center gap-2 text-xs text-gray-600">
                            Farbe ändern
                            <input
                                type="color"
                                class="h-8 w-8 cursor-pointer rounded border border-gray-300"
                                :value="group.color"
                                @input="updateGroupColor(group, $event.target.value)"
                            >
                        </label>
                    </div>
                </VueDraggable>
            </div>

            <div class="space-y-2">
                <h4 class="text-sm font-semibold uppercase tracking-wide text-gray-600">
                    Gruppenfolge
                </h4>

                <VueDraggable
                    v-model="arrangementGroups"
                    :group="{ name: 'song-groups', pull: true, put: true }"
                    class="min-h-24 rounded-lg border border-gray-200 bg-gray-50 p-3"
                    @end="saveArrangement"
                >
                    <div
                        v-for="(group, index) in arrangementGroups"
                        :key="`${group.id}-${index}`"
                        class="mb-2 flex items-center gap-2 rounded-md border border-gray-200 bg-white p-2"
                    >
                        <span data-testid="arrangement-drag-handle" class="cursor-move text-gray-500">⋮⋮</span>

                        <span
                            class="inline-flex rounded-full px-3 py-1 text-sm font-semibold text-white"
                            :style="groupPillStyle(group)"
                        >
                            {{ group.name }}
                        </span>

                        <label class="ml-auto flex items-center gap-2 text-xs text-gray-600">
                            Farbe ändern
                            <input
                                type="color"
                                class="h-8 w-8 cursor-pointer rounded border border-gray-300"
                                :value="group.color"
                                @input="updateGroupColor(group, $event.target.value)"
                            >
                        </label>

                        <button
                            data-testid="arrangement-remove-button"
                            type="button"
                            class="rounded px-2 py-1 text-xs font-semibold text-red-600 hover:bg-red-50"
                            @click="removeGroupAt(index)"
                        >
                            Entfernen
                        </button>
                    </div>
                </VueDraggable>
            </div>
        </div>
    </div>
</template>
