<script setup>
import { ref, watch, computed, nextTick } from "vue";
import axios from "axios";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/Components/ui/dialog";
import { router, usePage } from "@inertiajs/vue3";
import { useForm, Field as FormField } from "vee-validate";
import { toTypedSchema } from "@vee-validate/zod";
import * as z from "zod";
import { FormControl, FormItem, FormLabel, FormMessage } from "@/Components/ui/form";
import { Input } from "@/Components/ui/input";
import { Textarea } from "@/Components/ui/textarea";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/Components/ui/select";
import { Button } from "@/Components/ui/button";
import { ScrollArea } from "@/Components/ui/scroll-area";

const props = defineProps({
  show: { type: Boolean, default: false },
  email: { type: Object, default: null },
  clientCaseUuid: { type: String, default: null },
  emailTemplates: { type: Array, default: () => [] },
  mailProfiles: { type: Array, default: () => [] },
});

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

const page = usePage();
const pageProps = computed(() => page?.props ?? {});

const pageEmailTemplates = computed(() => {
  const fromProps =
    Array.isArray(props.emailTemplates) && props.emailTemplates.length
      ? props.emailTemplates
      : null;
  return fromProps ?? pageProps.value?.email_templates ?? [];
});

const pageMailProfiles = computed(() => {
  const fromProps =
    Array.isArray(props.mailProfiles) && props.mailProfiles.length
      ? props.mailProfiles
      : null;
  return fromProps ?? pageProps.value?.mail_profiles ?? [];
});

// Form schema
const formSchema = toTypedSchema(
  z.object({
    subject: z.string().min(1, "Zadeva je obvezna.").max(255),
    html_body: z.string().nullable().optional(),
    body_text: z.string().max(10000).nullable().optional(),
    template_id: z.number().nullable().optional(),
    mail_profile_id: z.number().nullable().optional(),
    contract_uuid: z.string().nullable().optional(),
  })
);

const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    subject: "",
    html_body: "",
    body_text: "",
    template_id: null,
    mail_profile_id: null,
    contract_uuid: null,
  },
});

const processing = ref(false);
const contractsForCase = ref([]);
const hasBodyText = ref(false); // whether selected template uses {{body_text}}

// WYSIWYG iframe
const iframeRef = ref(null);
let iframeSyncing = false;

function ensureFullDoc(html) {
  if (!html) {
    return '<!doctype html><html><head><meta charset="utf-8" /></head><body></body></html>';
  }
  if (/<html[\s\S]*<\/html>/i.test(html)) return html;
  return `<!doctype html><html><head><meta charset="utf-8" /></head><body>${html}</body></html>`;
}

function writeIframeDocument(html) {
  const iframe = iframeRef.value;
  if (!iframe) return;
  const doc = iframe.contentDocument;
  if (!doc) return;
  const full = ensureFullDoc(html ?? form.values.html_body ?? "");
  doc.open();
  doc.write(full);
  doc.close();
  try {
    doc.body.setAttribute("spellcheck", "false");
  } catch {}
}

function initIframeEditor(html) {
  writeIframeDocument(html);
  const iframe = iframeRef.value;
  if (!iframe) return;
  const doc = iframe.contentDocument;
  if (!doc) return;
  try {
    doc.designMode = "on";
  } catch {}

  const syncHandler = () => {
    if (iframeSyncing) return;
    try {
      iframeSyncing = true;
      const full = doc.documentElement.outerHTML;
      form.setFieldValue("html_body", full);
    } finally {
      iframeSyncing = false;
    }
  };

  doc.removeEventListener("input", syncHandler);
  doc.removeEventListener("keyup", syncHandler);
  doc.addEventListener("input", syncHandler);
  doc.addEventListener("keyup", syncHandler);
}

function iframeExec(command) {
  const iframe = iframeRef.value;
  if (!iframe) return;
  const doc = iframe.contentDocument;
  if (!doc) return;
  try {
    doc.body.focus();
  } catch {}
  try {
    doc.execCommand(command, false, null);
  } catch (e) {
    console.warn("execCommand failed", command, e);
  }
}

// Load template preview from server
const loadingPreview = ref(false);

const updateFromTemplate = async () => {
  if (!form.values.template_id || !props.clientCaseUuid) return;
  loadingPreview.value = true;
  try {
    const url = route("clientCase.email.preview", {
      client_case: props.clientCaseUuid,
      email_id: props.email?.id,
    });
    const { data } = await axios.post(url, {
      template_id: form.values.template_id,
      contract_uuid: form.values.contract_uuid || null,
      body_text: form.values.body_text || "",
    });
    const hadBodyText = hasBodyText.value;
    hasBodyText.value = !!data?.has_body_text;
    // Pre-fill body_text from text_template when the placeholder is present and field is empty
    if (data?.has_body_text && !hadBodyText) {
      const tpl = pageEmailTemplates.value.find((t) => t.id === form.values.template_id);
      if (tpl?.text_template && !form.values.body_text) {
        form.setFieldValue("body_text", tpl.text_template);
      }
    }
    if (data?.subject) {
      form.setFieldValue("subject", data.subject);
    }
    const html = data?.html ?? "";
    form.setFieldValue("html_body", html);
    await nextTick();
    initIframeEditor(html);
  } catch (e) {
    // ignore
  } finally {
    loadingPreview.value = false;
  }
};

watch(
  () => form.values.template_id,
  () => {
    updateFromTemplate();
  }
);

watch(
  () => form.values.contract_uuid,
  () => {
    if (form.values.template_id) {
      updateFromTemplate();
    }
  }
);

// Re-preview when body_text changes (debounce-like: only when a template is active)
watch(
  () => form.values.body_text,
  () => {
    if (form.values.template_id && hasBodyText.value) {
      updateFromTemplate();
    }
  }
);

const loadContractsForCase = async () => {
  try {
    const url = route("clientCase.contracts.list", {
      client_case: props.clientCaseUuid,
    });
    const res = await fetch(url, {
      headers: { "X-Requested-With": "XMLHttpRequest" },
      credentials: "same-origin",
    });
    const json = await res.json();
    contractsForCase.value = Array.isArray(json?.data) ? json.data : [];
  } catch (e) {
    contractsForCase.value = [];
  }
};

watch(
  () => props.show,
  async (newVal) => {
    if (newVal) {
      form.resetForm({
        values: {
          subject: "",
          html_body: "",
          body_text: "",
          template_id: null,
          mail_profile_id: pageMailProfiles.value?.[0]?.id ?? null,
          contract_uuid: null,
        },
      });
      hasBodyText.value = false;
      contractsForCase.value = [];
      await loadContractsForCase();
      // Init empty iframe
      await nextTick();
      initIframeEditor("");
    }
  }
);

const closeDialog = () => {
  emit("close");
};

const onSubmit = form.handleSubmit((values) => {
  if (!props.email || !props.clientCaseUuid) return;
  processing.value = true;
  router.post(
    route("clientCase.email.send", {
      client_case: props.clientCaseUuid,
      email_id: props.email.id,
    }),
    values,
    {
      preserveScroll: true,
      onSuccess: () => {
        processing.value = false;
        closeDialog();
      },
      onError: () => {
        processing.value = false;
      },
      onFinish: () => {
        processing.value = false;
      },
    }
  );
});

const open = computed({
  get: () => props.show,
  set: (value) => {
    if (!value) closeDialog();
  },
});
</script>

<template>
  <Dialog v-model:open="open">
    <DialogContent class="sm:max-w-2xl">
      <DialogHeader>
        <DialogTitle>Pošlji e-pošto</DialogTitle>
        <DialogDescription>
          <p class="text-sm text-gray-600">
            Prejemnik:
            <span class="font-mono">{{ email?.value || email?.email || email?.address }}</span>
          </p>
        </DialogDescription>
      </DialogHeader>

      <ScrollArea class="max-h-[70vh] pr-1">
        <form @submit.prevent="onSubmit" class="space-y-4 pr-3">
          <!-- Mail profile -->
          <FormField v-slot="{ value, handleChange }" name="mail_profile_id">
            <FormItem>
              <FormLabel>E-poštni profil</FormLabel>
              <Select :model-value="value" @update:model-value="handleChange">
                <FormControl>
                  <SelectTrigger>
                    <SelectValue placeholder="—" />
                  </SelectTrigger>
                </FormControl>
                <SelectContent>
                  <SelectItem :value="null">—</SelectItem>
                  <SelectItem
                    v-for="p in pageMailProfiles"
                    :key="p.id"
                    :value="p.id"
                  >
                    {{ p.name || "Profil #" + p.id }}
                  </SelectItem>
                </SelectContent>
              </Select>
              <FormMessage />
            </FormItem>
          </FormField>

          <!-- Contract -->
          <FormField v-slot="{ value, handleChange }" name="contract_uuid">
            <FormItem>
              <FormLabel>Pogodba</FormLabel>
              <Select :model-value="value" @update:model-value="handleChange">
                <FormControl>
                  <SelectTrigger>
                    <SelectValue placeholder="—" />
                  </SelectTrigger>
                </FormControl>
                <SelectContent>
                  <SelectItem :value="null">—</SelectItem>
                  <SelectItem
                    v-for="c in contractsForCase"
                    :key="c.uuid"
                    :value="c.uuid"
                  >
                    {{ c.reference || c.uuid }}
                  </SelectItem>
                </SelectContent>
              </Select>
              <p class="mt-1 text-xs text-gray-500">
                Izberite pogodbo za zapolnitev spremenljivk v predlogi.
              </p>
              <FormMessage />
            </FormItem>
          </FormField>

          <!-- Template -->
          <FormField v-slot="{ value, handleChange }" name="template_id">
            <FormItem>
              <FormLabel>Predloga</FormLabel>
              <Select
                :model-value="value"
                @update:model-value="handleChange"
                :disabled="loadingPreview"
              >
                <FormControl>
                  <SelectTrigger>
                    <SelectValue placeholder="—" />
                  </SelectTrigger>
                </FormControl>
                <SelectContent>
                  <SelectItem :value="null">—</SelectItem>
                  <SelectItem
                    v-for="t in pageEmailTemplates"
                    :key="t.id"
                    :value="t.id"
                  >
                    {{ t.name || "Predloga #" + t.id }}
                  </SelectItem>
                </SelectContent>
              </Select>
              <FormMessage />
            </FormItem>
          </FormField>

          <!-- Subject -->
          <FormField v-slot="{ componentField }" name="subject">
            <FormItem>
              <FormLabel>Zadeva</FormLabel>
              <FormControl>
                <Input
                  type="text"
                  placeholder="Zadeva e-poštnega sporočila..."
                  v-bind="componentField"
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          </FormField>

          <!-- body_text textarea — shown only when the template uses {{body_text}} -->
          <FormField v-if="hasBodyText" v-slot="{ componentField }" name="body_text">
            <FormItem>
              <FormLabel>Besedilo sporočila</FormLabel>
              <FormControl>
                <Textarea
                  placeholder="Vnesite besedilo, ki se vstavi na mesto {{body_text}} v predlogi..."
                  class="min-h-[120px] resize-y"
                  v-bind="componentField"
                />
              </FormControl>
              <p class="mt-1 text-xs text-gray-500">
                Besedilo se vstavi na oznako <code>&#123;&#123;body_text&#125;&#125;</code> v predlogi. Besedilo ne podpira spremenljivk.
              </p>
              <FormMessage />
            </FormItem>
          </FormField>

          <!-- WYSIWYG body editor -->
          <div>
            <label class="text-sm font-medium leading-none">Vsebina</label>
            <!-- Toolbar -->
            <div class="flex gap-1 mt-2 mb-1 border rounded-t-md bg-gray-50 p-1">
              <Button
                type="button"
                size="sm"
                variant="ghost"
                class="font-bold px-2 py-1 h-7"
                title="Krepko (Ctrl+B)"
                @click="iframeExec('bold')"
              >B</Button>
              <Button
                type="button"
                size="sm"
                variant="ghost"
                class="italic px-2 py-1 h-7"
                title="Poševno (Ctrl+I)"
                @click="iframeExec('italic')"
              >I</Button>
              <Button
                type="button"
                size="sm"
                variant="ghost"
                class="underline px-2 py-1 h-7"
                title="Podčrtano (Ctrl+U)"
                @click="iframeExec('underline')"
              >U</Button>
            </div>
            <iframe
              ref="iframeRef"
              class="w-full border rounded-b-md bg-white"
              style="min-height: 240px; max-height: 360px"
              frameborder="0"
              sandbox="allow-same-origin allow-scripts"
            />
            <p class="mt-1 text-xs text-gray-500">
              Kliknite v vsebino in začnite pisati. Izberite predlogo za samodejno zapolnitev.
            </p>
          </div>
        </form>
      </ScrollArea>

      <DialogFooter>
        <Button variant="outline" @click="closeDialog" :disabled="processing">
          Prekliči
        </Button>
        <Button
          @click="onSubmit"
          :disabled="processing || !form.values.subject"
        >
          {{ processing ? "Pošiljanje..." : "Pošlji" }}
        </Button>
      </DialogFooter>
    </DialogContent>
  </Dialog>
</template>
