<script setup lang="ts">
import { destroy, store, update } from '@/actions/App/Http/Controllers/Admin/PayrollStructureController';
import ConfirmationModal from '@/Components/Common/ConfirmationModal.vue';
import AdminLayout from '@/Layouts/AdminLayout.vue';
import { router, useForm, usePage } from '@inertiajs/vue3';
import { Pencil, Plus, PlusCircle, Trash2, X } from 'lucide-vue-next';
import { computed, ref } from 'vue';

defineOptions({ layout: AdminLayout });

const page = usePage();

const props = defineProps<{
    structures: Array<{
        id: number;
        name: string;
        description: string | null;
        components: Array<{
            id: number;
            salary_component_id: number;
            calculation_type: string;
            value: string;
            salary_component: { id: number; name: string; type: string };
        }>;
    }>;
    salaryComponents: Array<{ id: number; name: string; type: string }>;
}>();

const showForm = ref(false);
const editing = ref<number | null>(null);

const form = useForm({
    name: '',
    description: '',
    components: [] as Array<{ salary_component_id: number; calculation_type: string; value: string }>,
});

// Track which component IDs are already selected in the current form
const usedComponentIds = computed(() => form.components.map((c) => c.salary_component_id).filter((id) => id > 0));

function isDuplicate(componentId: number, currentIndex: number): boolean {
    return form.components.some((c, i) => i !== currentIndex && c.salary_component_id === componentId && componentId > 0);
}

const hasDuplicates = computed(() => {
    const ids = usedComponentIds.value;
    return new Set(ids).size !== ids.length;
});

function openCreate() {
    editing.value = null;
    form.reset();
    form.components = [];
    showForm.value = true;
}

function openEdit(s: (typeof props.structures)[0]) {
    editing.value = s.id;
    form.name = s.name;
    form.description = s.description ?? '';
    form.components = s.components.map((c) => ({
        salary_component_id: c.salary_component_id,
        calculation_type: c.calculation_type,
        value: c.value,
    }));
    showForm.value = true;
}

function addComponent() {
    form.components.push({ salary_component_id: 0, calculation_type: 'percentage', value: '' });
}

function removeComponent(index: number) {
    form.components.splice(index, 1);
}

function submit() {
    if (hasDuplicates.value) return;

    const url = editing.value ? update({ structure: editing.value }).url : store().url;
    const method = editing.value ? 'put' : 'post';
    form[method](url, {
        preserveScroll: true,
        onSuccess: () => {
            showForm.value = false;
            form.reset();
        },
    });
}

const confirmState = ref({
    show: false,
    title: '',
    message: '',
    type: 'danger' as 'danger' | 'warning' | 'info',
    confirmText: 'Confirm',
    processing: false,
    action: null as (() => void) | null,
});

function closeConfirm() {
    confirmState.value.show = false;
    setTimeout(() => {
        confirmState.value.action = null;
        confirmState.value.processing = false;
    }, 300);
}

function executeConfirm() {
    if (confirmState.value.action) {
        confirmState.value.processing = true;
        confirmState.value.action();
    }
}

function deleteStructure(id: number) {
    confirmState.value = {
        show: true,
        title: 'Delete Structure',
        message: 'Are you sure you want to delete this payroll structure? This action cannot be undone.',
        type: 'danger',
        confirmText: 'Delete',
        processing: false,
        action: () =>
            router.delete(destroy({ structure: id }).url, {
                preserveScroll: true,
                onFinish: closeConfirm,
            }),
    };
}
</script>

<template>
    <div class="relative space-y-6">
        <div class="flex items-center justify-between">
            <div>
                <h1 class="text-xl font-extrabold text-slate-800 dark:text-white">Payroll Structures</h1>
                <p class="text-sm text-slate-500">Group salary components into reusable payroll structures</p>
            </div>
            <button
                @click="openCreate"
                class="flex items-center gap-2 rounded-xl bg-indigo-600 px-4 py-2 text-sm font-bold text-white shadow-2xl shadow-indigo-900/30 transition-all hover:bg-indigo-700 active:scale-95"
            >
                <PlusCircle class="h-4 w-4" /> New Structure
            </button>
        </div>

        <!-- Slide-over -->
        <Teleport to="body">
            <!-- Backdrop -->
            <Transition
                enter-active-class="transition-opacity ease-linear duration-300"
                enter-from-class="opacity-0"
                enter-to-class="opacity-100"
                leave-active-class="transition-opacity ease-linear duration-200"
                leave-from-class="opacity-100"
                leave-to-class="opacity-0"
            >
                <div v-if="showForm" class="fixed inset-0 z-9999 bg-black/30 backdrop-blur-sm" @click="showForm = false" />
            </Transition>

            <!-- Slide-over Panel -->
            <Transition
                enter-active-class="transition ease-in-out duration-300 transform"
                enter-from-class="translate-x-full"
                enter-to-class="translate-x-0"
                leave-active-class="transition ease-in-out duration-200 transform"
                leave-from-class="translate-x-0"
                leave-to-class="translate-x-full"
            >
                <div
                    v-if="showForm"
                    class="fixed inset-y-0 right-0 z-10000 flex h-screen w-full max-w-lg flex-col bg-white shadow-2xl dark:bg-slate-900"
                >
                    <div class="flex items-center justify-between border-b border-slate-200 p-5 dark:border-slate-700">
                        <h2 class="text-base font-bold text-slate-800 dark:text-white">{{ editing ? 'Edit' : 'New' }} Payroll Structure</h2>
                        <button @click="showForm = false"><X class="h-5 w-5 text-slate-400" /></button>
                    </div>
                    <div class="flex-1 space-y-4 overflow-y-auto p-5">
                        <div>
                            <label class="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-300">Name</label>
                            <input
                                v-model="form.name"
                                type="text"
                                placeholder="e.g. Standard Monthly, Executive"
                                class="w-full rounded-xl border border-slate-300 bg-white px-4 py-2 text-sm shadow-inner focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:border-slate-600 dark:bg-slate-800"
                            />
                            <p v-if="form.errors.name" class="mt-1 text-xs text-red-500">{{ form.errors.name }}</p>
                        </div>
                        <div>
                            <label class="mb-1 block text-sm font-medium text-slate-700 dark:text-slate-300">Description</label>
                            <textarea
                                v-model="form.description"
                                rows="2"
                                class="w-full rounded-xl border border-slate-300 bg-white p-3 text-sm shadow-inner focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:border-slate-600 dark:bg-slate-800"
                            />
                        </div>
                        <div>
                            <div class="mb-2 flex items-center justify-between">
                                <label class="text-sm font-medium text-slate-700 dark:text-slate-300">Components</label>
                                <button @click="addComponent" class="flex items-center gap-1 text-xs font-bold text-indigo-600 hover:underline">
                                    <Plus class="h-3.5 w-3.5" /> Add
                                </button>
                            </div>
                            <!-- Duplicate warning banner -->
                            <div
                                v-if="hasDuplicates"
                                class="mb-3 flex items-center gap-2 rounded-xl bg-red-50 px-4 py-2 text-sm font-semibold text-red-700 dark:bg-red-900/20"
                            >
                                <X class="h-4 w-4 shrink-0" />
                                Duplicate components detected. Each component can only be added once.
                            </div>
                            <div
                                v-for="(comp, i) in form.components"
                                :key="i"
                                class="mb-2 flex items-center gap-2 rounded-xl p-3 dark:bg-slate-800"
                                :class="isDuplicate(comp.salary_component_id, i) ? 'bg-red-50 ring-1 ring-red-300' : 'bg-slate-50'"
                            >
                                <select
                                    v-model="comp.salary_component_id"
                                    class="flex-1 rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-sm shadow-inner focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:border-slate-600 dark:bg-slate-700"
                                >
                                    <option :value="0" disabled>Select component</option>
                                    <option
                                        v-for="sc in salaryComponents"
                                        :key="sc.id"
                                        :value="sc.id"
                                        :disabled="usedComponentIds.filter((id: number) => id === sc.id).length > 1"
                                    >
                                        {{ sc.name }} ({{ sc.type }})
                                    </option>
                                </select>
                                <select
                                    v-model="comp.calculation_type"
                                    class="w-28 rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-sm shadow-inner focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:border-slate-600 dark:bg-slate-700"
                                >
                                    <option value="percentage">%</option>
                                    <option value="fixed">Fixed</option>
                                </select>
                                <input
                                    v-model="comp.value"
                                    type="number"
                                    min="0"
                                    step="0.01"
                                    placeholder="Value"
                                    class="w-24 rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-sm shadow-inner focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:border-slate-600 dark:bg-slate-700"
                                />
                                <button @click="removeComponent(i)" class="text-red-400 hover:text-red-600">
                                    <X class="h-4 w-4" />
                                </button>
                            </div>
                            <p v-if="form.errors.components" class="mt-1 text-xs text-red-500">{{ form.errors.components }}</p>
                        </div>
                    </div>
                    <div class="flex gap-3 border-t border-slate-200 p-5 dark:border-slate-700">
                        <button
                            @click="showForm = false"
                            class="flex-1 rounded-xl bg-slate-100 px-4 py-2 text-sm font-bold text-slate-600 transition-colors hover:bg-slate-200 dark:bg-slate-800"
                        >
                            Cancel
                        </button>
                        <button
                            @click="submit"
                            :disabled="form.processing || hasDuplicates"
                            class="flex-1 rounded-xl bg-indigo-600 px-4 py-2 text-sm font-black tracking-widest text-white uppercase shadow-2xl shadow-indigo-900/30 transition-all hover:bg-indigo-700 active:scale-95 disabled:opacity-50"
                        >
                            {{ form.processing ? 'Saving…' : 'Save' }}
                        </button>
                    </div>
                </div>
            </Transition>
        </Teleport>

        <!-- Cards -->
        <div class="grid grid-cols-1 gap-4">
            <div v-for="s in structures" :key="s.id" class="rounded-xl border border-slate-200 bg-white p-5 dark:border-slate-700 dark:bg-slate-900">
                <div class="mb-3 flex items-start justify-between">
                    <div>
                        <div class="text-base font-bold text-slate-800 dark:text-white">{{ s.name }}</div>
                        <div v-if="s.description" class="mt-0.5 text-sm text-slate-500">{{ s.description }}</div>
                    </div>
                    <div class="flex gap-2">
                        <button @click="openEdit(s)" class="rounded-lg p-1.5 transition-colors hover:bg-slate-100 dark:hover:bg-slate-700">
                            <Pencil class="h-4 w-4 text-slate-500" />
                        </button>
                        <button @click="deleteStructure(s.id)" class="rounded-lg p-1.5 transition-colors hover:bg-red-50 dark:hover:bg-red-900/20">
                            <Trash2 class="h-4 w-4 text-red-500" />
                        </button>
                    </div>
                </div>
                <div class="flex flex-wrap gap-2">
                    <span
                        v-for="c in s.components"
                        :key="c.id"
                        :class="
                            c.salary_component?.type === 'earning'
                                ? 'bg-emerald-50 text-emerald-700 ring-1 ring-emerald-200'
                                : 'bg-rose-50 text-rose-700 ring-1 ring-rose-200'
                        "
                        class="inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-semibold"
                    >
                        {{ c.salary_component?.name }}
                        <span class="opacity-70">{{
                            c.calculation_type === 'percentage' ? c.value + '%' : parseFloat(c.value).toLocaleString()
                        }}</span>
                    </span>
                </div>
            </div>
            <div v-if="!structures.length" class="py-12 text-center text-sm text-slate-400">No payroll structures yet.</div>
        </div>

        <ConfirmationModal
            :show="confirmState.show"
            :title="confirmState.title"
            :message="confirmState.message"
            :type="confirmState.type"
            :confirm-text="confirmState.confirmText"
            :processing="confirmState.processing"
            @close="closeConfirm"
            @confirm="executeConfirm"
        />
    </div>
</template>

<style scoped>
.fade-enter-active,
.fade-leave-active {
    transition: opacity 0.3s;
}
.fade-enter-from,
.fade-leave-to {
    opacity: 0;
}
</style>
