<template>
    <form :class="{ submitted }" @submit.prevent="validate">
        <div class="flex items-center relative">
            <div class="flex flex-row absolute -left-[60px]">
                <Icon
                    @click="router.push('/admin/user/list')"
                    name="gg:arrow-left-o"
                    size="40"
                    class="cursor-pointer text-primary-500"
                />
            </div>
            <h1 class="text-3xl text-primary-500 font-bold uppercase">
                {{ userId ? "Modification de l'utilisateur" : "Ajout d'un utilisateur" }}
            </h1>
        </div>

        <div class="flex flex-cols-3 justify-between mb-11 pt-7">
            <UiTextInput
                id="user-name"
                v-model="form.username"
                label="Nom de l'utilisateur"
                :disabled="!auth.isAdmin"
                wrapper-class="w-[280px]"
                required
            />

            <UiSelect
                id="user-role"
                v-model="form.role"
                label="Role de l'utilisateur"
                :options="ROLE"
                :disabled="!auth.isAdmin"
                wrapper-class="w-[280px]"
                required
            />

            <UiTextInput
                id="user-password"
                v-model="form.password"
                label="Mot de passe"
                type="password"
                :disabled="!auth.isAdmin"
                wrapper-class="w-[280px]"
                required
            />
        </div>

        <div class="flex items-center justify-center">
            <UiButton
                class="inline-flex mb-28 items-center justify-center text-xl min-w-[194px] text-white uppercase bg-primary-500 h-[50px] rounded hover:opacity-80 justify-self-end"
                type="submit"
                :disabled="isLoading || isHydrating || !auth.isAdmin"
                @click="submitted = true"
            >
                <Icon :name="userId ? '' : 'mdi:plus'" size="28" />
                {{ userId ? 'Valider' : 'Ajouter' }}
            </UiButton>
        </div>
    </form>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import { ROLE } from '~/utils/constants'
import { createUser, updateUser, getUser } from '~/services/auth'
import type { UserData, UserFormData, UserPayload } from '~/services/dto/user-data'
import { useAuthStore } from '~/stores/auth'

const route = useRoute()
const router = useRouter()
const auth = useAuthStore()
const userId = computed(() => resolveUserId(route.params.id))
const isLoading = ref(false)
const isHydrating = ref(false)
const submitted = ref(false)

const resolveUserId = (param: unknown) => {
    const idStr = Array.isArray(param) ? param[0] : param
    if (!idStr) {
        return null
    }
    const id = Number(idStr)
    return Number.isFinite(id) ? id : null
}

const form = reactive<UserFormData>({
    username: '',
    password: '',
    role: ''
})

const hydrateFromUser = (user: UserData | null) => {
    if (!user) {
        return
    }
    isHydrating.value = true
    form.username = user.username ?? ''
    const roles = user.roles ?? []
    const hasAdmin = roles.includes('ROLE_ADMIN')
    form.role = hasAdmin ? 'ROLE_ADMIN' : 'ROLE_USER'
    form.password = ''
    isHydrating.value = false
}

watch(
    () => userId.value,
    async (id) => {
        if (id === null) {
            return
        }
        isLoading.value = true
        try {
            const user = await getUser(id)
            hydrateFromUser(user)
        } finally {
            isLoading.value = false
        }
    },
    { immediate: true }
)

async function validate() {
    if (!auth.isAdmin) return

    const normalizedUsername = form.username.trim()
    const normalizedRole = form.role.trim()
    const normalizedPassword = form.password.trim()

    const basePayload: UserPayload = {
        username: normalizedUsername,
        roles: normalizedRole ? [normalizedRole] : undefined,
    }
    if (normalizedPassword) {
        basePayload.password = normalizedPassword
    }

    if (userId.value) {
        await updateUser(userId.value, basePayload)
        return
    }

    const created = await createUser(basePayload)
    if (created) {
        await router.push('/admin/user/list')
    }
}
</script>
