<script setup>
import CreateDialog from "@/Components/Dialogs/CreateDialog.vue";
import { useForm } from "vee-validate";
import { toTypedSchema } from "@vee-validate/zod";
import * as z from "zod";
import { ref, watch } from "vue";
import { router } from "@inertiajs/vue3";
import {
  FormControl,
  FormField,
  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 { Switch } from "@/Components/ui/switch";

const props = defineProps({
  show: { type: Boolean, default: false },
  postUrl: { type: String, required: true },
  // Optional list of contracts to allow attaching the document directly to a contract
  // Each item should have at least: { uuid, reference }
  contracts: { type: Array, default: () => [] },
});
const emit = defineEmits(["close", "uploaded"]);

const MAX_SIZE = 25 * 1024 * 1024; // 25MB
const ALLOWED_EXTS = [
  "doc",
  "docx",
  "pdf",
  "txt",
  "csv",
  "xls",
  "xlsx",
  "jpeg",
  "jpg",
  "png",
];

const formSchema = toTypedSchema(
  z.object({
    name: z.string().min(1, "Ime je obvezno"),
    description: z.string().optional(),
    file: z.instanceof(File).refine((file) => file.size > 0, "Izberite datoteko"),
    is_public: z.boolean().default(true),
    contract_uuid: z.string().nullable().optional(),
  })
);

const form = useForm({
  validationSchema: formSchema,
  initialValues: {
    name: "",
    description: "",
    file: null,
    is_public: true,
    contract_uuid: null,
  },
});

const localError = ref("");

watch(
  () => props.show,
  (v) => {
    if (!v) return;
    localError.value = "";
    form.resetForm();
  }
);

const onFileChange = (e) => {
  localError.value = "";
  const f = e.target.files?.[0];
  if (!f) {
    form.setFieldValue("file", null);
    return;
  }
  const ext = (f.name.split(".").pop() || "").toLowerCase();
  if (!ALLOWED_EXTS.includes(ext)) {
    localError.value = "Nepodprta vrsta datoteke. Dovoljeno: " + ALLOWED_EXTS.join(", ");
    e.target.value = "";
    form.setFieldValue("file", null);
    return;
  }
  if (f.size > MAX_SIZE) {
    localError.value = "Datoteka je prevelika. Največja velikost je 25MB.";
    e.target.value = "";
    form.setFieldValue("file", null);
    return;
  }
  form.setFieldValue("file", f);
  if (!form.values.name) {
    form.setFieldValue("name", f.name.replace(/\.[^.]+$/, ""));
  }
};

const submit = form.handleSubmit(async (values) => {
  localError.value = "";
  if (!values.file) {
    localError.value = "Prosimo izberite datoteko.";
    return;
  }
  const ext = (values.file.name.split(".").pop() || "").toLowerCase();
  if (!ALLOWED_EXTS.includes(ext)) {
    localError.value = "Nepodprta vrsta datoteke. Dovoljeno: " + ALLOWED_EXTS.join(", ");
    return;
  }
  if (values.file.size > MAX_SIZE) {
    localError.value = "Datoteka je prevelika. Največja velikost je 25MB.";
    return;
  }

  const formData = new FormData();
  formData.append("name", values.name);
  formData.append("description", values.description || "");
  formData.append("file", values.file);
  formData.append("is_public", values.is_public ? "1" : "0");
  if (values.contract_uuid) {
    formData.append("contract_uuid", values.contract_uuid);
  }

  router.post(props.postUrl, formData, {
    forceFormData: true,
    onSuccess: () => {
      emit("uploaded");
      emit("close");
      form.resetForm();
    },
    onError: (errors) => {
      // Set form errors if any
      if (errors.name) form.setFieldError("name", errors.name);
      if (errors.description) form.setFieldError("description", errors.description);
      if (errors.file) form.setFieldError("file", errors.file);
      if (errors.contract_uuid) form.setFieldError("contract_uuid", errors.contract_uuid);
    },
  });
});

const close = () => emit("close");

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

<template>
  <CreateDialog
    :show="props.show"
    title="Dodaj dokument"
    max-width="lg"
    confirm-text="Naloži"
    :processing="!!form.isSubmitting.value"
    :disabled="!form.values.file"
    @close="close"
    @confirm="onConfirm"
  >
    <form @submit.prevent="submit" class="space-y-4">
      <FormField
        v-if="props.contracts && props.contracts.length"
        v-slot="{ value, handleChange }"
        name="contract_uuid"
      >
        <FormItem>
          <FormLabel>Pripiši k</FormLabel>
          <Select :model-value="value" @update:model-value="handleChange">
            <FormControl>
              <SelectTrigger>
                <SelectValue placeholder="Primer" />
              </SelectTrigger>
            </FormControl>
            <SelectContent>
              <SelectItem :value="null">Primer</SelectItem>
              <SelectItem v-for="c in props.contracts" :key="c.uuid" :value="c.uuid">
                Pogodba: {{ c.reference }}
              </SelectItem>
            </SelectContent>
          </Select>
          <FormMessage />
        </FormItem>
      </FormField>

      <FormField v-slot="{ componentField }" name="name">
        <FormItem>
          <FormLabel>Ime</FormLabel>
          <FormControl>
            <Input
              id="doc_name"
              v-bind="componentField"
              class="w-full max-w-full overflow-hidden text-ellipsis"
            />
          </FormControl>
          <FormMessage />
        </FormItem>
      </FormField>

      <FormField v-slot="{ componentField }" name="description">
        <FormItem>
          <FormLabel>Opis</FormLabel>
          <FormControl>
            <Textarea id="doc_desc" v-bind="componentField" rows="3" />
          </FormControl>
          <FormMessage />
        </FormItem>
      </FormField>

      <FormField v-slot="{ value, handleChange }" name="file">
        <FormItem>
          <FormLabel>Datoteka (max 25MB)</FormLabel>
          <FormControl class="flex w-full">
            <Input
              id="doc_file"
              type="file"
              @change="onFileChange"
              accept=".doc,.docx,.pdf,.txt,.csv,.xls,.xlsx,.jpeg,.jpg,.png"
              class="min-w-0 w-full"
            />
          </FormControl>
          <FormMessage />
          <div v-if="localError" class="text-sm text-red-600 mt-1">{{ localError }}</div>
        </FormItem>
      </FormField>

      <FormField v-slot="{ value, handleChange }" name="is_public">
        <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>Javno</FormLabel>
          </div>
        </FormItem>
      </FormField>
    </form>
  </CreateDialog>
</template>
