<script setup>
import { computed, 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, usePage } from "@inertiajs/vue3";
import AppMultiSelect from "@/Components/app/ui/AppMultiSelect.vue";
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 { Switch } from "@/Components/ui/switch";

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

const emit = defineEmits(["close"]);

// Decisions with auto_mail = true from shared Inertia data
const page = usePage();
const decisionOptions = computed(() =>
  (page.props.auto_mail_decisions ?? []).map((d) => ({
    value: String(d.id),
    label: d.name,
  }))
);

// Zod schema for form validation
const formSchema = toTypedSchema(
  z.object({
    value: z.string().email("E-pošta mora biti veljavna.").min(1, "E-pošta je obvezna."),
    label: z.string().optional(),
    receive_auto_mails: z.boolean().optional(),
    valid: z.boolean().default(true),
    failed: z.boolean().default(false),
    decision_ids: z.array(z.string()).optional().default([]),
  })
);

// VeeValidate form
const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    value: "",
    label: "",
    receive_auto_mails: false,
    valid: true,
    failed: false,
    decision_ids: [],
  },
});

// Whether to limit sending to specific decisions (UI-only toggle)
const limitToDecisions = ref(false);

const processing = ref(false);

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

const resetForm = () => {
  limitToDecisions.value = false;
  form.resetForm({
    values: {
      value: "",
      label: "",
      receive_auto_mails: false,
      valid: true,
      failed: false,
      decision_ids: [],
    },
  });
};

// When auto mails is disabled, collapse the decision filter
watch(
  () => form.values.receive_auto_mails,
  (val) => {
    if (!val) {
      limitToDecisions.value = false;
    }
  }
);

// When limit toggle is turned off, clear the selection
watch(limitToDecisions, (val) => {
  if (!val) {
    form.setFieldValue("decision_ids", []);
  }
});

const create = async () => {
  processing.value = true;
  const payload = {
    ...form.values,
    decision_ids: limitToDecisions.value ? (form.values.decision_ids ?? []) : [],
  };

  router.post(
    route("person.email.create", props.person),
    payload,
    {
      preserveScroll: true,
      onSuccess: () => {
        close();
        resetForm();
      },
      onError: (errors) => {
        // Map Inertia errors to VeeValidate field 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 payload = {
    ...form.values,
    decision_ids: limitToDecisions.value ? (form.values.decision_ids ?? []) : [],
  };

  router.put(
    route("person.email.update", { person: props.person, email_id: props.id }),
    payload,
    {
      preserveScroll: true,
      onSuccess: () => {
        close();
        resetForm();
      },
      onError: (errors) => {
        // Map Inertia errors to VeeValidate field 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;
      },
    }
  );
};

watch(
  () => props.show,
  (newVal) => {
    if (!newVal) {
      return;
    }
    if (props.edit && props.id) {
      const list = Array.isArray(props.person?.emails) ? props.person.emails : [];
      const email = list.find((e) => e.id === props.id);
      if (email) {
        const existingDecisionIds = (email.preferences?.decision_ids ?? []).map(String);
        limitToDecisions.value = existingDecisionIds.length > 0;
        form.setValues({
          value: email.value ?? email.email ?? email.address ?? "",
          label: email.label ?? "",
          receive_auto_mails: !!email.receive_auto_mails,
          valid: email.valid !== undefined ? !!email.valid : true,
          failed: !!email.failed,
          decision_ids: existingDecisionIds,
        });
      } else {
        resetForm();
      }
    } else {
      resetForm();
    }
  }
);

const onSubmit = form.handleSubmit((values) => {
  if (props.edit) {
    update();
  } else {
    create();
  }
});

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

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

      <div class="space-y-4">
        <FormField v-slot="{ componentField }" name="value">
          <FormItem>
            <FormLabel>E-pošta</FormLabel>
            <FormControl>
              <Input
                type="email"
                placeholder="example@example.com"
                autocomplete="email"
                v-bind="componentField"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField v-slot="{ componentField }" name="label">
          <FormItem>
            <FormLabel>Oznaka (neobvezno)</FormLabel>
            <FormControl>
              <Input
                type="text"
                placeholder="Oznaka"
                autocomplete="off"
                v-bind="componentField"
              />
            </FormControl>
            <FormMessage />
          </FormItem>
        </FormField>

        <FormField
          v-if="props.person?.client || isClientContext"
          v-slot="{ value, handleChange }"
          name="receive_auto_mails"
        >
          <FormItem class="flex flex-row items-start space-x-3 space-y-0">
            <FormControl>
              <Switch
                :model-value="value"
                @update:model-value="handleChange"
              />
            </FormControl>
            <div class="space-y-1 leading-none">
              <FormLabel class="cursor-pointer">
                Prejemaj samodejna e-sporočila
              </FormLabel>
            </div>
          </FormItem>
        </FormField>

        <FormField v-slot="{ value, handleChange }" name="valid">
          <FormItem class="flex flex-row items-start space-x-3 space-y-0">
            <FormControl>
              <Switch :model-value="value" @update:model-value="handleChange" />
            </FormControl>
            <div class="space-y-1 leading-none">
              <FormLabel class="cursor-pointer">Veljavna</FormLabel>
            </div>
          </FormItem>
        </FormField>

        <FormField v-slot="{ value, handleChange }" name="failed">
          <FormItem class="flex flex-row items-start space-x-3 space-y-0">
            <FormControl>
              <Switch :model-value="value" @update:model-value="handleChange" />
            </FormControl>
            <div class="space-y-1 leading-none">
              <FormLabel class="cursor-pointer">Neuspešna dostava</FormLabel>
            </div>
          </FormItem>
        </FormField>

        <!-- Limit to specific decisions — only shown when receive_auto_mails is on and decisions exist -->
        <template v-if="(props.person?.client || isClientContext) && form.values.receive_auto_mails && decisionOptions.length > 0">
          <div class="flex flex-row items-start space-x-3 space-y-0">
            <Switch
              :model-value="limitToDecisions"
              @update:model-value="(val) => (limitToDecisions = val)"
            />
            <div class="space-y-1 leading-none">
              <label class="text-sm font-medium leading-none cursor-pointer" @click="limitToDecisions = !limitToDecisions">
                Omeji na posamezne odločitve
              </label>
            </div>
          </div>

          <FormField v-if="limitToDecisions" v-slot="{ value, handleChange }" name="decision_ids">
            <FormItem>
              <FormLabel>Odločitve, za katere se pošlje e-pošta</FormLabel>
              <FormControl>
                <AppMultiSelect
                  :model-value="value ?? []"
                  :items="decisionOptions"
                  placeholder="Izberi odločitve..."
                  @update:model-value="handleChange"
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          </FormField>
        </template>
      </div>
    </form>
  </component>
</template>
