<script setup lang="ts">
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { useForm } from 'vee-validate'
import { toTypedSchema } from '@vee-validate/zod'
import * as z from 'zod'
import { toast } from 'vue-sonner'
import { api } from '@/api/client'
import type { Zone } from '@/api/types'
import { ref, watch } from 'vue'
import SpinnerLoader from '@/components/SpinnerLoader.vue'

const props = defineProps<{
  open: boolean
  zone?: Zone | null
}>()

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

const submitting = ref(false)
const isEdit = () => !!props.zone

const schema = toTypedSchema(
  z.object({
    zone_id: z.string().min(1, 'Zone ID is required'),
    name: z.string().min(1, 'Name is required'),
    api_key: z.string().min(1, 'API key is required'),
  }),
)

const { handleSubmit, resetForm, setValues } = useForm({
  validationSchema: schema,
})

watch(
  () => props.open,
  (open) => {
    if (open && props.zone) {
      setValues({
        zone_id: props.zone.zone_id,
        name: props.zone.name,
        api_key: props.zone.api_key,
      })
    } else if (open) {
      resetForm()
    }
  },
)

const onSubmit = handleSubmit(async (values) => {
  submitting.value = true
  try {
    if (isEdit() && props.zone) {
      await api.put(`/api/zones/${props.zone.id}`, values)
      toast.success('Zone updated')
    } else {
      await api.post('/api/zones', values)
      toast.success('Zone created')
    }
    emit('update:open', false)
    emit('saved')
  } catch (err) {
    toast.error(err instanceof Error ? err.message : 'Failed to save zone')
  } finally {
    submitting.value = false
  }
})
</script>

<template>
  <Dialog :open="open" @update:open="emit('update:open', $event)">
    <DialogContent class="sm:max-w-md">
      <DialogHeader>
        <DialogTitle>{{ isEdit() ? 'Edit Zone' : 'Add Zone' }}</DialogTitle>
        <DialogDescription>
          {{ isEdit() ? 'Update the Cloudflare zone details.' : 'Add a new Cloudflare zone to manage.' }}
        </DialogDescription>
      </DialogHeader>
      <form @submit="onSubmit" class="space-y-4">
        <FormField name="zone_id" v-slot="{ field }">
          <FormItem>
            <FormLabel>Zone ID</FormLabel>
            <FormControl>
              <Input v-bind="field" placeholder="Cloudflare Zone ID" :disabled="isEdit()" />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField name="name" v-slot="{ field }">
          <FormItem>
            <FormLabel>Name</FormLabel>
            <FormControl>
              <Input v-bind="field" placeholder="example.com" />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField name="api_key" v-slot="{ field }">
          <FormItem>
            <FormLabel>API Key</FormLabel>
            <FormControl>
              <Input v-bind="field" type="password" placeholder="Cloudflare API token" />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <DialogFooter>
          <Button type="button" variant="outline" @click="emit('update:open', false)">
            Cancel
          </Button>
          <Button type="submit" class="bg-orange-500 hover:bg-orange-500/90 text-white">
            <SpinnerLoader v-if="submitting" customClass="w-4 h-4 fill-gray-200 text-orange-500" />
            <template v-else>{{ isEdit() ? 'Update' : 'Create' }}</template>
          </Button>
        </DialogFooter>
      </form>
    </DialogContent>
  </Dialog>
</template>
