<script setup>
import { reactive, computed, watch } from 'vue'
import Modal from '@/components/ui/Modal.vue'
import Button from '@/components/ui/Button.vue'
import {
  emptyUserForm,
  ROLE_OPTIONS,
  validateUserForm,
} from '@/composables/userForm'

const props = defineProps({
  open: { type: Boolean, default: false },
  title: { type: String, default: 'Edit User' },
  mode: { type: String, default: 'edit', validator: (v) => ['create', 'edit'].includes(v) },
  initialValues: { type: Object, default: () => emptyUserForm() },
  submitting: { type: Boolean, default: false },
  error: { type: String, default: '' },
})

const emit = defineEmits(['close', 'submit'])

const values = reactive(emptyUserForm())
const touched = reactive({
  username: false,
  password: false,
  displayName: false,
  role: false,
})

const validation = computed(() => validateUserForm(values, props.mode))
const fieldErrors = computed(() => validation.value.errors)

watch(() => props.open, (isOpen) => {
  if (!isOpen) return
  Object.assign(values, props.initialValues)
  for (const key of Object.keys(touched)) touched[key] = false
}, { immediate: true })

function onBlur(key) {
  touched[key] = true
}

function showError(key) {
  return Boolean(touched[key] && fieldErrors.value[key])
}

function submit() {
  for (const key of Object.keys(touched)) touched[key] = true
  if (!validation.value.valid) return
  emit('submit', validation.value.payload)
}
</script>

<template>
  <Modal :open="open" :title="title" @close="emit('close')">
    <form class="space-y-4" @submit.prevent="submit">
      <div v-if="mode === 'create'">
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          Username
        </label>
        <input
          v-model="values.username"
          type="text"
          autocomplete="off"
          class="w-full rounded border px-4 py-2 text-sm focus-visible:ring-2 focus-visible:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          :class="showError('username') ? 'border-red-500' : 'border-gray-300'"
          @blur="onBlur('username')"
        >
        <p v-if="showError('username')" class="mt-1 text-xs text-red-600 dark:text-red-400">
          {{ fieldErrors.username }}
        </p>
      </div>

      <div v-if="mode === 'create'">
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          Password
        </label>
        <input
          v-model="values.password"
          type="password"
          autocomplete="new-password"
          class="w-full rounded border px-4 py-2 text-sm focus-visible:ring-2 focus-visible:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          :class="showError('password') ? 'border-red-500' : 'border-gray-300'"
          @blur="onBlur('password')"
        >
        <p v-if="showError('password')" class="mt-1 text-xs text-red-600 dark:text-red-400">
          {{ fieldErrors.password }}
        </p>
      </div>

      <div>
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          Display name
        </label>
        <input
          v-model="values.displayName"
          type="text"
          class="w-full rounded border px-4 py-2 text-sm focus-visible:ring-2 focus-visible:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          :class="showError('displayName') ? 'border-red-500' : 'border-gray-300'"
          @blur="onBlur('displayName')"
        >
        <p v-if="showError('displayName')" class="mt-1 text-xs text-red-600 dark:text-red-400">
          {{ fieldErrors.displayName }}
        </p>
      </div>

      <div>
        <label class="mb-2 block text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
          Role
        </label>
        <select
          v-model="values.role"
          class="w-full rounded border px-4 py-2 text-sm focus-visible:ring-2 focus-visible:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-white"
          :class="showError('role') ? 'border-red-500' : 'border-gray-300'"
          @blur="onBlur('role')"
        >
          <option v-for="opt in ROLE_OPTIONS" :key="opt.value" :value="opt.value">
            {{ opt.label }}
          </option>
        </select>
        <p v-if="showError('role')" class="mt-1 text-xs text-red-600 dark:text-red-400">
          {{ fieldErrors.role }}
        </p>
      </div>

      <div v-if="mode === 'edit'" class="flex items-center gap-2">
        <input
          id="user-active"
          v-model="values.isActive"
          type="checkbox"
          class="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
        >
        <label for="user-active" class="text-sm text-gray-700 dark:text-gray-300">
          Account active
        </label>
      </div>

      <p v-if="error" class="text-sm text-red-600 dark:text-red-400">{{ error }}</p>

      <div class="flex justify-end gap-2">
        <Button type="button" variant="ghost" @click="emit('close')">Cancel</Button>
        <Button type="submit" :disabled="submitting">
          {{ submitting ? 'Saving…' : 'Save' }}
        </Button>
      </div>
    </form>
  </Modal>
</template>
