<script setup>
    import { computed } from 'vue';
    import {
        mdiArrowDown,
        mdiArrowUp,
        mdiDeleteOutline,
        mdiPlus,
    } from '@mdi/js';

    const props = defineProps({
        modelValue: {
            type: Array,
            default: () => [],
        },
        members: {
            type: Array,
            default: () => [],
        },
        errors: {
            type: Array,
            default: () => [],
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        labels: {
            type: Object,
            required: true,
        },
    });

    const emit = defineEmits(['update:modelValue']);

    const roleOptions = [
        'administrator',
        'manager',
        'workspace-member',
        'client',
        'provider',
    ];
    const membershipOptions = ['Team', 'Client'];
    const targetTypes = ['Role', 'Membership', 'Member'];
    const roleItems = computed(() => roleOptions.map(role => ({
        title: props.labels.roles[role],
        value: role,
    })));
    const membershipItems = computed(() => membershipOptions.map(membership => ({
        title: props.labels.memberships[membership],
        value: membership,
    })));
    const targetTypeItems = computed(() => targetTypes.map(targetType => ({
        title: props.labels.targetTypes[targetType],
        value: targetType,
    })));
    const memberItems = computed(() => props.members.map(member => ({
        title: `${member.displayName} - ${member.email}`,
        value: member.id,
    })));

    function emitSteps(steps) {
        emit('update:modelValue', steps.map((step, index) => ({
            ...step,
            sortOrder: index,
        })));
    }

    function createStep() {
        emitSteps([
            ...props.modelValue,
            {
                name: props.labels.defaultStepName(props.modelValue.length + 1),
                sortOrder: props.modelValue.length,
                targetType: 'Role',
                targetValue: 'manager',
                requiredApproverCount: 1,
            },
        ]);
    }

    function updateStep(index, updates) {
        const steps = props.modelValue.map((step, stepIndex) => {
            if (stepIndex !== index) {
                return step;
            }

            const nextStep = {
                ...step,
                ...updates,
            };

            if (updates.targetType) {
                nextStep.targetValue = defaultTargetValue(updates.targetType);
            }

            return nextStep;
        });

        emitSteps(steps);
    }

    function defaultTargetValue(targetType) {
        if (targetType === 'Membership') {
            return membershipOptions[0];
        }

        if (targetType === 'Member') {
            return props.members[0]?.id ?? '';
        }

        return roleOptions[1];
    }

    function getSelectedMemberIds(step) {
        return (step.targetValue ?? '')
            .split(',')
            .map(value => value.trim())
            .filter(Boolean);
    }

    function updateMemberTargets(index, selectedMemberIds) {
        updateStep(index, { targetValue: selectedMemberIds.filter(Boolean).join(',') });
    }

    function moveStep(index, offset) {
        const nextIndex = index + offset;

        if (nextIndex < 0 || nextIndex >= props.modelValue.length) {
            return;
        }

        const steps = [...props.modelValue];
        const [step] = steps.splice(index, 1);
        steps.splice(nextIndex, 0, step);
        emitSteps(steps);
    }

    function removeStep(index) {
        emitSteps(props.modelValue.filter((_, stepIndex) => stepIndex !== index));
    }
</script>

<template>
    <div class="approval-workflow-editor">
        <div class="approval-editor-header">
            <div>
                <strong>{{ labels.title }}</strong>
                <span>{{ labels.description }}</span>
            </div>

            <button
                type="button"
                class="secondary-button"
                :disabled="disabled"
                @click="createStep"
            >
                <v-icon :icon="mdiPlus" />
                <span>{{ labels.addStep }}</span>
            </button>
        </div>

        <div
            v-if="!modelValue.length"
            class="approval-empty"
        >
            {{ labels.empty }}
        </div>

        <div
            v-else
            class="approval-step-list"
        >
            <section
                v-for="(step, index) in modelValue"
                :key="step.id ?? `${index}-${step.sortOrder}`"
                class="approval-step-card"
            >
                <div class="approval-step-heading">
                    <div>
                        <small>{{ labels.stepNumber(index + 1) }}</small>
                        <strong>{{ step.name || labels.unnamedStep }}</strong>
                    </div>

                    <div class="approval-step-actions">
                        <button
                            type="button"
                            :aria-label="labels.moveUp"
                            :disabled="disabled || index === 0"
                            @click="moveStep(index, -1)"
                        >
                            <v-icon :icon="mdiArrowUp" />
                        </button>
                        <button
                            type="button"
                            :aria-label="labels.moveDown"
                            :disabled="disabled || index === modelValue.length - 1"
                            @click="moveStep(index, 1)"
                        >
                            <v-icon :icon="mdiArrowDown" />
                        </button>
                        <button
                            type="button"
                            :aria-label="labels.removeStep"
                            :disabled="disabled"
                            @click="removeStep(index)"
                        >
                            <v-icon :icon="mdiDeleteOutline" />
                        </button>
                    </div>
                </div>

                <div class="approval-step-fields">
                    <div class="field">
                        <v-text-field
                            :model-value="step.name"
                            :label="labels.fields.name"
                            :disabled="disabled"
                            variant="outlined"
                            hide-details
                            @update:model-value="updateStep(index, { name: $event })"
                        />
                        <small
                            v-if="errors[index]?.name"
                            class="field-error"
                        >
                            {{ errors[index].name }}
                        </small>
                    </div>

                    <v-select
                        :model-value="step.targetType"
                        :items="targetTypeItems"
                        :label="labels.fields.targetType"
                        :disabled="disabled"
                        variant="outlined"
                        hide-details
                        @update:model-value="updateStep(index, { targetType: $event })"
                    />

                    <div class="field">
                        <v-select
                            v-if="step.targetType === 'Role'"
                            :model-value="step.targetValue"
                            :items="roleItems"
                            :label="labels.fields.targetValue"
                            :disabled="disabled"
                            variant="outlined"
                            hide-details
                            @update:model-value="updateStep(index, { targetValue: $event })"
                        />

                        <v-select
                            v-else-if="step.targetType === 'Membership'"
                            :model-value="step.targetValue"
                            :items="membershipItems"
                            :label="labels.fields.targetValue"
                            :disabled="disabled"
                            variant="outlined"
                            hide-details
                            @update:model-value="updateStep(index, { targetValue: $event })"
                        />

                        <v-select
                            v-else
                            :model-value="getSelectedMemberIds(step)"
                            :items="memberItems"
                            :label="labels.fields.targetValue"
                            :disabled="disabled"
                            multiple
                            chips
                            closable-chips
                            variant="outlined"
                            hide-details
                            @update:model-value="updateMemberTargets(index, $event)"
                        />
                        <small
                            v-if="step.targetType === 'Member'"
                            class="field-help"
                        >
                            {{ labels.selectMembers }}
                        </small>

                        <small
                            v-if="errors[index]?.targetValue"
                            class="field-error"
                        >
                            {{ errors[index].targetValue }}
                        </small>
                    </div>

                    <div class="field">
                        <v-text-field
                            :model-value="step.requiredApproverCount"
                            :label="labels.fields.requiredApproverCount"
                            type="number"
                            min="1"
                            step="1"
                            :disabled="disabled"
                            variant="outlined"
                            hide-details
                            @update:model-value="updateStep(index, { requiredApproverCount: Number($event) })"
                        />
                        <small
                            v-if="errors[index]?.requiredApproverCount"
                            class="field-error"
                        >
                            {{ errors[index].requiredApproverCount }}
                        </small>
                    </div>
                </div>
            </section>
        </div>
    </div>
</template>

<style scoped>
@reference "@/assets/main.css";
    .approval-workflow-editor {
        @apply flex flex-col gap-3;
    }

    .approval-editor-header {
        @apply flex flex-col gap-3 rounded-[1rem] border px-4 py-4 sm:flex-row sm:items-center sm:justify-between;
        background: #fffaf2;
        border-color: rgba(23, 32, 51, 0.08);
    }

    .approval-editor-header div,
    .approval-step-heading div:first-child {
        @apply flex min-w-0 flex-col gap-1;
    }

    .approval-editor-header strong,
    .approval-step-heading strong {
        color: #172033;
    }

    .approval-editor-header span,
    .approval-empty,
    .approval-step-heading small {
        @apply text-sm leading-6;
        color: #526178;
    }

    .approval-step-list {
        @apply flex flex-col gap-3;
    }

    .approval-empty,
    .approval-step-card {
        @apply rounded-[1rem] border px-4 py-4;
        background: #fffaf2;
        border-color: rgba(23, 32, 51, 0.08);
    }

    .approval-step-card {
        @apply flex flex-col gap-4;
    }

    .approval-step-heading {
        @apply flex items-start justify-between gap-3;
    }

    .approval-step-actions {
        @apply flex flex-shrink-0 gap-2;
    }

    .approval-step-actions button {
        @apply inline-flex h-9 w-9 items-center justify-center rounded-full;
        background: rgba(23, 32, 51, 0.08);
        color: #172033;
    }

    .approval-step-actions button:disabled {
        cursor: not-allowed;
        opacity: 0.42;
    }

    .approval-step-fields {
        @apply grid gap-3 md:grid-cols-2;
    }

    .secondary-button {
        @apply inline-flex items-center justify-center gap-2 rounded-full px-4 py-2 text-sm font-semibold;
        background: rgba(23, 32, 51, 0.08);
        color: #172033;
    }

    .secondary-button:disabled {
        cursor: not-allowed;
        opacity: 0.56;
    }

    .field {
        @apply flex flex-col gap-2;
    }

    .field span {
        @apply text-sm font-semibold;
        color: #172033;
    }

    .field input,
    .field select {
        @apply rounded-[1rem] border px-4 py-3 text-sm;
        background: #fffdf8;
        border-color: rgba(23, 32, 51, 0.1);
        color: #172033;
        outline: none;
    }

    .field-error {
        @apply text-sm leading-6;
        color: #b91c1c;
    }

    .field-help {
        @apply text-sm leading-6;
        color: #526178;
    }
</style>
