<script setup>
import BaseAlert from "../../../../components/base/BaseAlert.vue";
import BaseButton from "../../../../components/base/BaseButton.vue";
import BaseCheckbox from "../../../../components/base/BaseCheckbox.vue";
import BaseColumn from "../../../../components/base/BaseColumn.vue";
import BaseConfirmDialog from "../../../../components/base/BaseConfirmDialog.vue";
import BaseDataTable from "../../../../components/base/BaseDataTable.vue";
import BaseInputText from "../../../../components/base/BaseInputText.vue";
import BaseModal from "../../../../components/base/BaseModal.vue";
import BaseSelect from "../../../../components/base/BaseSelect.vue";

import { useCustomerAddresses } from "../../composables/useCustomers.js";
import { useConfirm } from "primevue/useconfirm";

import { computed, inject, ref, watch } from "vue";

const TYPE_OPTS = [
  { label: "Billing", value: "billing" },
  { label: "Shipping", value: "shipping" },
  { label: "Other", value: "other" },
];

const props = defineProps({
  customerId: { type: [String, Number], required: true },
});

const cid = computed(() => props.customerId);
const confirm = useConfirm();

const {
  addresses,
  loading,
  error,
  load,
  create,
  update,
  remove,
} = useCustomerAddresses(cid);

const dialogVisible = ref(false);
const editing = ref(null);
const saving = ref(false);
const validation = ref({});
const draft = ref({
  type: "billing",
  street: "",
  house_number: "",
  house_number_addition: "",
  postal_code: "",
  city: "",
  country: "NL",
  is_primary: false,
});

watch(
  () => cid.value,
  () => {
    load();
  },
  { immediate: true },
);

const saveBump = inject("customerDetailSaveBump", null);
watch(
  () => saveBump?.value,
  (n, p) => {
    if (p === undefined) return;
    load();
  },
);

function openCreate() {
  editing.value = null;
  validation.value = {};
  draft.value = {
    type: "billing",
    street: "",
    house_number: "",
    house_number_addition: "",
    postal_code: "",
    city: "",
    country: "NL",
    is_primary: false,
  };
  dialogVisible.value = true;
}

function openEdit(row) {
  editing.value = row;
  validation.value = {};
  draft.value = {
    type: row.type ?? "billing",
    street: row.street ?? "",
    house_number: row.house_number ?? "",
    house_number_addition: row.house_number_addition ?? "",
    postal_code: row.postal_code ?? "",
    city: row.city ?? "",
    country: row.country ?? "NL",
    is_primary: !!row.is_primary,
  };
  dialogVisible.value = true;
}

function fieldError(field) {
  const e = validation.value?.[field];
  return Array.isArray(e) ? e[0] : e ?? "";
}

async function saveAddress() {
  saving.value = true;
  validation.value = {};
  const payload = {
    type: draft.value.type,
    street: draft.value.street.trim(),
    house_number: draft.value.house_number.trim(),
    house_number_addition: draft.value.house_number_addition?.trim() || null,
    postal_code: draft.value.postal_code.trim(),
    city: draft.value.city.trim(),
    country: (draft.value.country || "NL").trim(),
    is_primary: !!draft.value.is_primary,
  };
  try {
    if (!editing.value) {
      await create(payload);
    } else {
      await update(editing.value.id, payload);
    }
    dialogVisible.value = false;
    await load();
  } catch (e) {
    validation.value = e?.response?.data?.errors ?? {};
  } finally {
    saving.value = false;
  }
}

function confirmRemove(row) {
  confirm.require({
    message: `Delete this ${row.type} address?`,
    header: "Confirm",
    icon: "pi pi-exclamation-triangle",
    rejectProps: { label: "Cancel", severity: "secondary", outlined: true },
    acceptProps: { label: "Delete", severity: "danger" },
    accept: async () => {
      await remove(row.id);
      await load();
    },
  });
}

defineExpose({ load });
</script>

<template>
  <div>
    <BaseConfirmDialog />
    <BaseAlert v-if="error" severity="error" class="mb-2">{{ error }}</BaseAlert>
    <div class="flex justify-end mb-3">
      <BaseButton
        variant="primary"
        icon="plus"
        label="Add address"
        @click="openCreate"
      />
    </div>
    <BaseDataTable
      :value="addresses"
      data-key="id"
      :loading="loading"
      striped-rows
    >
      <BaseColumn field="type" header="Type" />
      <BaseColumn field="full_address" header="Address" />
      <BaseColumn header="Primary">
        <template #body="{ data }">
          <span>{{ data.is_primary ? "Yes" : "No" }}</span>
        </template>
      </BaseColumn>
      <BaseColumn header="" body-class="text-end w-36">
        <template #body="{ data }">
          <div class="inline-flex gap-1">
            <BaseButton
              type="button"
              variant="secondary"
              icon="pencil"
              text
              rounded
              size="small"
              :icon-only="true"
              aria-label="Edit address"
              @click="openEdit(data)"
            />
            <BaseButton
              type="button"
              variant="danger"
              icon="trash"
              text
              rounded
              size="small"
              :icon-only="true"
              aria-label="Remove address"
              @click="confirmRemove(data)"
            />
          </div>
        </template>
      </BaseColumn>
    </BaseDataTable>

    <BaseModal
      v-model:visible="dialogVisible"
      :title="editing ? 'Edit address' : 'New address'"
      width="28rem"
      class="w-full max-w-md"
      :dismissable-mask="true"
    >
      <form class="flex flex-col gap-4 mt-2" @submit.prevent="saveAddress">
        <BaseSelect
          id="ca-type"
          v-model="draft.type"
          label="Type"
          :options="TYPE_OPTS"
          option-label="label"
          option-value="value"
          fluid
          :error="fieldError('type')"
        />
        <BaseInputText
          id="ca-street"
          v-model.trim="draft.street"
          label="Street"
          fluid
          :error="fieldError('street')"
        />
        <div class="grid grid-cols-2 gap-2">
          <BaseInputText
            id="ca-hn"
            v-model.trim="draft.house_number"
            label="Number"
            fluid
            :error="fieldError('house_number')"
          />
          <BaseInputText
            id="ca-add"
            v-model.trim="draft.house_number_addition"
            label="Addition"
            fluid
          />
        </div>
        <BaseInputText
          id="ca-pc"
          v-model.trim="draft.postal_code"
          label="Postal code"
          fluid
          :error="fieldError('postal_code')"
        />
        <BaseInputText
          id="ca-city"
          v-model.trim="draft.city"
          label="City"
          fluid
          :error="fieldError('city')"
        />
        <BaseInputText
          id="ca-country"
          v-model.trim="draft.country"
          label="Country"
          fluid
          maxlength="255"
        />
        <BaseCheckbox
          id="ca-primary"
          v-model="draft.is_primary"
          :binary="true"
          label="Primary address"
        />
        <div class="flex justify-end gap-2 pt-2">
          <BaseButton
            variant="secondary"
            outlined
            type="button"
            @click="dialogVisible = false"
          >
            Cancel
          </BaseButton>
          <BaseButton variant="primary" type="submit" :loading="saving">
            Save
          </BaseButton>
        </div>
      </form>
    </BaseModal>
  </div>
</template>
