<script setup>
import { ref, watch } from "vue";
import { useForm, Field as FormField } from "vee-validate";
import { toTypedSchema } from "@vee-validate/zod";
import * as z from "zod";
import { router } from "@inertiajs/vue3";
import CreateDialog from "../Dialogs/CreateDialog.vue";
import UpdateDialog from "../Dialogs/UpdateDialog.vue";
import SectionTitle from "../SectionTitle.vue";
import { FormControl, FormItem, FormLabel, FormMessage } from "@/Components/ui/form";
import { Input } from "@/Components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/Components/ui/select";

const props = defineProps({
  show: {
    type: Boolean,
    default: false,
  },
  person: Object,
  types: Array,
  edit: {
    type: Boolean,
    default: false,
  },
  id: {
    type: Number,
    default: 0,
  },
});

const formSchema = toTypedSchema(
  z.object({
    address: z.string().min(1, "Naslov je obvezen."),
    country: z.string().optional(),
    post_code: z.string().optional(),
    city: z.string().optional(),
    type_id: z.number().nullable(),
    description: z.string().optional(),
  })
);

const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    address: "",
    country: "",
    post_code: "",
    city: "",
    type_id: props.types?.[0]?.id ?? null,
    description: "",
  },
});

const processing = ref(false);
const emit = defineEmits(["close"]);

const close = () => {
  emit("close");
  setTimeout(() => {
    form.resetForm();
    processing.value = false;
  }, 300);
};

const resetForm = () => {
  form.resetForm({
    values: {
      address: "",
      country: "",
      post_code: "",
      city: "",
      type_id: props.types?.[0]?.id ?? null,
      description: "",
    },
  });
};

watch(
  () => props.id,
  (id) => {
    if (props.edit && id !== 0) {
      const a = props.person.addresses?.find((x) => x.id === id);
      if (a) {
        form.setValues({
          address: a.address || "",
          country: a.country || "",
          post_code: a.post_code || a.postal_code || "",
          city: a.city || "",
          type_id: a.type_id ?? props.types?.[0]?.id ?? null,
          description: a.description || "",
        });
        return;
      }
    }
    resetForm();
  },
  { immediate: true }
);

watch(
  () => props.show,
  (val) => {
    if (val && props.edit && props.id) {
      const a = props.person.addresses?.find((x) => x.id === props.id);
      if (a) {
        form.setValues({
          address: a.address || "",
          country: a.country || "",
          post_code: a.post_code || a.postal_code || "",
          city: a.city || "",
          type_id: a.type_id ?? props.types?.[0]?.id ?? null,
          description: a.description || "",
        });
      }
    } else if (val && !props.edit) {
      resetForm();
    }
  }
);

const create = async () => {
  processing.value = true;
  const { values } = form;

  router.post(route("person.address.create", props.person), values, {
    preserveScroll: true,
    onSuccess: () => {
      processing.value = false;
      close();
      resetForm();
    },
    onError: (errors) => {
      Object.keys(errors).forEach((field) => {
        const errorMessages = Array.isArray(errors[field])
          ? errors[field]
          : [errors[field]];
        form.setFieldError(field, errorMessages[0]);
      });
      processing.value = false;
    },
    onFinish: () => {
      processing.value = false;
    },
  });
};

const update = async () => {
  processing.value = true;
  const { values } = form;

  router.put(
    route("person.address.update", { person: props.person, address_id: props.id }),
    values,
    {
      preserveScroll: true,
      onSuccess: () => {
        processing.value = false;
        close();
        resetForm();
      },
      onError: (errors) => {
        Object.keys(errors).forEach((field) => {
          const errorMessages = Array.isArray(errors[field])
            ? errors[field]
            : [errors[field]];
          form.setFieldError(field, errorMessages[0]);
        });
        processing.value = false;
      },
      onFinish: () => {
        processing.value = false;
      },
    }
  );
};

const callSubmit = () => {
  if (props.edit) {
    update();
  } else {
    create();
  }
};

const onSubmit = form.handleSubmit(() => {
  callSubmit();
});

const onConfirm = () => {
  onSubmit();
};
</script>

<template>
  <component
    :is="edit ? UpdateDialog : CreateDialog"
    :show="show"
    :title="edit ? 'Spremeni naslov' : 'Dodaj novi naslov'"
    confirm-text="Shrani"
    :processing="processing"
    @close="close"
    @confirm="onConfirm"
  >
    <form @submit.prevent="onSubmit">
      <SectionTitle class="border-b mb-4">
        <template #title> Naslov </template>
      </SectionTitle>

      <div class="space-y-4">
        <FormField v-slot="{ componentField }" name="address">
          <FormItem>
            <FormLabel>Naslov</FormLabel>
            <FormControl>
              <Input
                type="text"
                placeholder="Naslov"
                autocomplete="street-address"
                v-bind="componentField"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField v-slot="{ componentField }" name="country">
          <FormItem>
            <FormLabel>Država</FormLabel>
            <FormControl>
              <Input
                type="text"
                placeholder="Država"
                autocomplete="country"
                v-bind="componentField"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField v-slot="{ componentField }" name="post_code">
          <FormItem>
            <FormLabel>Poštna številka</FormLabel>
            <FormControl>
              <Input
                type="text"
                placeholder="Poštna številka"
                autocomplete="postal-code"
                v-bind="componentField"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField v-slot="{ componentField }" name="city">
          <FormItem>
            <FormLabel>Mesto</FormLabel>
            <FormControl>
              <Input
                type="text"
                placeholder="Mesto"
                autocomplete="address-level2"
                v-bind="componentField"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField v-slot="{ componentField }" name="description">
          <FormItem>
            <FormLabel>Opis</FormLabel>
            <FormControl>
              <Input type="text" placeholder="Opis" v-bind="componentField" />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField v-slot="{ value, handleChange }" name="type_id">
          <FormItem>
            <FormLabel>Tip</FormLabel>
            <Select :model-value="value" @update:model-value="handleChange">
              <FormControl>
                <SelectTrigger>
                  <SelectValue placeholder="Izberi tip" />
                </SelectTrigger>
              </FormControl>
              <SelectContent>
                <SelectItem v-for="type in types" :key="type.id" :value="type.id">
                  {{ type.name }}
                </SelectItem>
              </SelectContent>
            </Select>
            <FormMessage />
          </FormItem>
        </FormField>
      </div>
    </form>
  </component>
</template>
