<script setup>
import InputNumber from "@/components/common/InputNumber.vue";
import FileUpload from "@/components/media/FileUpload.vue";
import { isEqual, omitBy } from "es-toolkit";

const props = defineProps({
  productId: Number,
  variantId: Number,
});

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

const { $buildFileUrl, $copy, $empty, $getdata, $insertapi, $patchapi } = useNuxtApp();
const isPending = ref(false);
const defaultBody = ref({
  product: props.productId,
  price: null,
  internal_storage: null,
  ram: null,
  color: null,
  image: null,
  note: "",
});
const body = ref($copy(defaultBody.value));

const productVariant = ref();
onMounted(async () => {
  // if props.variant (edit), fetch data to fill in body
  if (props.variantId) {
    const variant = await $getdata("Product_Variant", {
      first: true,
      params: {
        filter: { id: props.variantId },
        values:
          "id,code,product,product__name,product__os,product__manufacturer,product__battery,product__screen,product__cpu,product__gpu,product__camera_system,product__sim,product__network_technology,product__charging_technology,product__external_storage,product__ip_rating,product__design,color,color__code,color__name,color__hex_code,ram,ram__code,ram__capacity,internal_storage,internal_storage__code,internal_storage__capacity,image,image__path,price,note,create_time,update_time",
      },
    });

    productVariant.value = variant;

    defaultBody.value = {
      product: variant.product,
      price: variant.price,
      internal_storage: variant.internal_storage,
      ram: variant.ram,
      color: variant.color,
      image: variant.image,
      note: variant.note,
    };

    body.value = $copy(defaultBody.value);
  }
});

const isDirty = computed(() => {
  if (!isEqual(body.value, defaultBody.value)) return true;
  if (uploadedImage.value) return true;
});

const uploadedImage = ref();

watch(
  () => props.productId,
  (newVal) => {
    body.value.product = newVal;
  },
);

function selected(field, data) {
  if (data === null || field === "price") {
    body.value[field] = data;
  } else {
    body.value[field] = data.id;
  }
}

function onFiles(files) {
  const file = files[0];
  uploadedImage.value = file;
}

const refreshData = inject("refreshData");
async function submit() {
  isPending.value = true;

  // 1. insert row to Product_Image, get back id
  if (uploadedImage.value) {
    const productImage = await $insertapi("Product_Image", {
      data: {
        name: uploadedImage.value.name,
        path: $buildFileUrl(uploadedImage.value.file),
      },
    });
    body.value.image = productImage.id;
  }

  // 2. upload to Product_Variant table
  const trimmedBody = omitBy(body.value, $empty);
  const res = props.variantId
    ? await $patchapi("Product_Variant", {
        id: props.variantId,
        ...trimmedBody,
      })
    : await $insertapi("Product_Variant", { data: trimmedBody });
  if (res !== "error") {
    if (refreshData) refreshData();
  }
  isPending.value = false;
}
</script>

<template>
  <form class="fixed-grid has-12-cols">
    <div class="grid">
      <div class="cell is-col-span-3">
        <div class="field">
          <label class="label">Đơn giá</label>
          <div class="control">
            <InputNumber
              v-bind="{
                record: body,
                attr: 'price',
                placeholder: 'Đơn giá',
                unit: 'VND',
              }"
              @number="selected('price', $event)"
            />
          </div>
        </div>
      </div>
      <div class="cell is-col-span-3">
        <div class="field">
          <label class="label">Màu sắc</label>
          <SearchBox
            v-bind="{
              api: 'Color',
              field: 'name',
              column: ['name'],
              first: true,
              optionid: body.color,
              placeholder: 'Màu sắc',
              addon: {
                component: 'imports/addons/AddColor',
                width: '60%',
                height: 'auto',
                title: 'Thêm màu sắc',
              },
            }"
            @option="selected('color', $event)"
          />
        </div>
      </div>
      <div class="cell is-col-span-3">
        <div class="field">
          <label class="label">RAM</label>
          <SearchBox
            v-bind="{
              api: 'RAM',
              field: 'code',
              column: ['code'],
              first: true,
              optionid: body.ram,
              placeholder: 'RAM',
              addon: {
                component: 'imports/addons/AddRAM',
                width: '60%',
                height: 'auto',
                title: 'Thêm RAM',
              },
            }"
            @option="selected('ram', $event)"
          />
        </div>
      </div>
      <div class="cell is-col-span-3">
        <div class="field">
          <label class="label">Bộ nhớ trong</label>
          <SearchBox
            v-bind="{
              api: 'Internal_Storage',
              field: 'code',
              column: ['code'],
              first: true,
              optionid: body.internal_storage,
              placeholder: 'Bộ nhớ trong',
              addon: {
                component: 'imports/addons/AddInternalStorage',
                width: '60%',
                height: 'auto',
                title: 'Thêm bộ nhớ trong',
              },
            }"
            @option="selected('internal_storage', $event)"
          />
        </div>
      </div>
      <div class="cell is-col-span-6">
        <div class="field">
          <label class="label">Ghi chú</label>
          <textarea
            v-model.trim="body.note"
            class="textarea"
            name="note"
            placeholder="Ghi chú"
            rows="5"
          ></textarea>
        </div>
      </div>
      <div class="cell is-col-span-6">
        <div class="field">
          <label class="label">Hình ảnh</label>
          <div class="control is-flex is-gap-1">
            <div>
              <div
                v-if="uploadedImage"
                class="relative"
                style="border: 1px solid var(--bulma-grey)"
              >
                <figure class="image is-128x128">
                  <img :src="$buildFileUrl(uploadedImage.file)" />
                </figure>
                <button
                  type="button"
                  class="button is-small is-danger is-light absolute"
                  :style="{ top: '5px', right: '5px' }"
                  @click="uploadedImage = undefined"
                >
                  <span class="icon">
                    <Icon
                      name="material-symbols:delete-outline-rounded"
                      :size="20"
                    />
                  </span>
                </button>
              </div>
              <div v-else-if="productVariant?.image__path">
                <figure class="image is-128x128">
                  <img :src="productVariant.image__path" />
                </figure>
              </div>
              <div
                v-else
                class="w-36 h-36 rounded-md is-flex is-align-items-center is-justify-content-center"
                style="border: 1px solid var(--bulma-grey-lighter)"
              >
                <Icon
                  name="material-symbols:add-photo-alternate-outline-rounded"
                  :size="40"
                  class="has-text-grey-light"
                />
              </div>
            </div>
            <FileUpload
              :type="['image']"
              :multiple="false"
              @files="onFiles"
            >
              <template #icon>
                <Icon
                  name="material-symbols:add-photo-alternate-outline-rounded"
                  :size="20"
                />
              </template>
              <span class="font-medium">Chọn</span>
            </FileUpload>
          </div>
        </div>
      </div>
      <div class="cell is-col-span-12">
        <button
          :class="['button is-primary', { 'is-loading': isPending }]"
          :disabled="!body.product || !isDirty"
          @click.prevent="submit"
        >
          <span class="icon">
            <Icon
              :name="variantId ? 'material-symbols:edit-outline-rounded' : 'material-symbols:add-rounded'"
              :size="18"
            />
          </span>
          <span>{{ variantId ? "Cập nhật" : "Thêm" }} phiên bản</span>
        </button>
      </div>
    </div>
  </form>
</template>
