<template>
    <Teleport v-if="modelValue" to="body">
        <Transition name="modal" appear>
            <div class="fixed inset-0 z-50 flex items-center justify-center">
                <div class="absolute inset-0 bg-black/30" @click="close" />
                <div class="relative z-10 w-full max-w-2xl rounded-lg bg-white p-6 shadow-xl">
                    <h3 class="text-lg font-bold text-neutral-900">{{ $t('workflows.switchTitle') }}</h3>

                    <div class="mt-5 flex flex-col gap-5">
                        <MalioSelect
                            v-model="targetWorkflowId"
                            :options="targetOptions"
                            :label="$t('workflows.switchTargetLabel')"
                            empty-option-label="—"
                            group-class="!w-full"
                        />

                        <div v-if="targetWorkflow" class="flex flex-col gap-2">
                            <h4 class="text-sm font-bold text-neutral-900">{{ $t('workflows.switchMappingTitle') }}</h4>

                            <table class="w-full text-sm">
                                <thead>
                                    <tr class="border-b text-left text-xs text-neutral-500">
                                        <th class="py-2 pr-3">{{ $t('workflows.switchSourceCol') }}</th>
                                        <th class="py-2 pr-3">{{ $t('workflows.switchTargetCol') }}</th>
                                        <th class="py-2 text-right">{{ $t('workflows.switchTaskCountCol') }}</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr v-for="row in mappingRows" :key="row.sourceId ?? 'backlog'" class="border-b last:border-0">
                                        <td class="py-2 pr-3">
                                            <span
                                                v-if="row.source"
                                                class="mr-2 inline-block h-3 w-3 rounded-full align-middle"
                                                :style="{ backgroundColor: row.source.color }"
                                            />
                                            {{ row.source?.label ?? $t('myTasks.backlog') }}
                                            <span class="ml-1 text-xs text-neutral-400">
                                                ({{ row.source?.category ? $t(`workflows.categories.${row.source.category}`) : '—' }})
                                            </span>
                                        </td>
                                        <td class="py-2 pr-3">
                                            <select
                                                v-model="row.targetId"
                                                class="h-9 w-full rounded border border-neutral-300 px-2 text-sm"
                                            >
                                                <option :value="null">{{ $t('workflows.switchToBacklog') }}</option>
                                                <option
                                                    v-for="s in targetWorkflow.statuses"
                                                    :key="s.id"
                                                    :value="s.id"
                                                >
                                                    {{ s.label }}
                                                </option>
                                            </select>
                                        </td>
                                        <td class="py-2 text-right text-neutral-700">{{ row.count }}</td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>

                        <div class="flex justify-end gap-3">
                            <MalioButton
                                variant="tertiary"
                                label="Annuler"
                                button-class="w-auto px-4"
                                @click="close"
                            />
                            <MalioButton
                                :label="$t('workflows.switchConfirm')"
                                button-class="w-auto px-6"
                                :disabled="!canConfirm || isSubmitting"
                                @click="confirm"
                            />
                        </div>
                    </div>
                </div>
            </div>
        </Transition>
    </Teleport>
</template>

<script setup lang="ts">
import type { Project } from '~/services/dto/project'
import type { Task } from '~/services/dto/task'
import type { Workflow } from '~/services/dto/workflow'
import type { TaskStatus } from '~/services/dto/task-status'
import { useWorkflowService } from '~/services/workflows'
import { useTaskService } from '~/services/tasks'

const props = defineProps<{
    modelValue: boolean
    project: Project
}>()

const emit = defineEmits<{
    (e: 'update:modelValue', value: boolean): void
    (e: 'switched'): void
}>()

const workflows = ref<Workflow[]>([])
const projectTasks = ref<Task[]>([])
const targetWorkflowId = ref<number | null>(null)
const isSubmitting = ref(false)

const workflowService = useWorkflowService()
const taskService = useTaskService()

const targetOptions = computed(() =>
    workflows.value
        .filter(w => w.id !== props.project.workflow.id)
        .map(w => ({ label: w.name, value: w.id })),
)

const targetWorkflow = computed<Workflow | null>(() =>
    workflows.value.find(w => w.id === targetWorkflowId.value) ?? null,
)

type Row = {
    sourceId: number | null
    source: TaskStatus | null
    targetId: number | null
    count: number
}

const mappingRows = ref<Row[]>([])

function smartPrefill(source: TaskStatus | null, target: Workflow): number | null {
    if (!source) return null
    const sameCat = target.statuses
        .filter(s => s.category === source.category)
        .sort((a, b) => a.position - b.position)
    return sameCat[0]?.id ?? null
}

watch(targetWorkflow, (tw) => {
    if (!tw) {
        mappingRows.value = []
        return
    }
    const usedStatusIds = new Map<number | null, number>()
    for (const t of projectTasks.value) {
        const key = t.status?.id ?? null
        usedStatusIds.set(key, (usedStatusIds.get(key) ?? 0) + 1)
    }
    mappingRows.value = [...usedStatusIds.entries()].map(([sourceId, count]) => {
        const source = props.project.workflow.statuses.find(s => s.id === sourceId) ?? null
        return {
            sourceId,
            source,
            targetId: smartPrefill(source, tw),
            count,
        }
    })
})

const canConfirm = computed(() => {
    if (!targetWorkflow.value) return false
    return mappingRows.value.every(r => r.sourceId === null || r.targetId !== undefined)
})

watch(() => props.modelValue, async (open) => {
    if (!open) return
    targetWorkflowId.value = null
    const [allWorkflows, tasks] = await Promise.all([
        workflowService.getAll(),
        taskService.getFiltered({ project: `/api/projects/${props.project.id}`, archived: false }),
    ])
    workflows.value = allWorkflows
    projectTasks.value = tasks
})

function close() {
    emit('update:modelValue', false)
}

async function confirm() {
    if (!targetWorkflow.value) return
    isSubmitting.value = true
    try {
        const mapping: Record<string, number | null> = {}
        for (const r of mappingRows.value) {
            if (r.sourceId !== null) {
                mapping[String(r.sourceId)] = r.targetId
            }
        }
        await workflowService.switchOnProject(props.project.id, {
            workflowId: targetWorkflow.value.id,
            mapping,
        })
        emit('switched')
        close()
    } finally {
        isSubmitting.value = false
    }
}
</script>

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