<script setup>
import BaseButton from "../../../../components/base/BaseButton.vue";

import Button from "primevue/button";
import Column from "primevue/column";
import ConfirmDialog from "primevue/confirmdialog";
import DataTable from "primevue/datatable";
import Dialog from "primevue/dialog";
import Checkbox from "primevue/checkbox";
import InputText from "primevue/inputtext";
import Select from "primevue/select";

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

import { computed, 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 },
);

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>
    <ConfirmDialog />
    <p v-if="error" class="text-red-600 text-sm mb-2">{{ error }}</p>
    <div class="flex justify-end mb-3">
      <BaseButton variant="primary" icon="plus" label="Add address" @click="openCreate" />
    </div>
    <DataTable :value="addresses" data-key="id" :loading="loading" striped-rows>
      <Column field="type" header="Type" />
      <Column field="full_address" header="Address" />
      <Column header="Primary">
        <template #body="{ data }">
          <span>{{ data.is_primary ? "Yes" : "No" }}</span>
        </template>
      </Column>
      <Column header="" body-class="text-end w-36">
        <template #body="{ data }">
          <div class="inline-flex gap-1">
            <Button
              type="button"
              icon="pi pi-pencil"
              rounded
              text
              severity="secondary"
              size="small"
              aria-label="Edit address"
              @click="openEdit(data)"
            />
            <Button
              type="button"
              icon="pi pi-trash"
              rounded
              text
              severity="danger"
              size="small"
              aria-label="Remove address"
              @click="confirmRemove(data)"
            />
          </div>
        </template>
      </Column>
    </DataTable>

    <Dialog
      v-model:visible="dialogVisible"
      modal
      :header="editing ? 'Edit address' : 'New address'"
      class="w-full max-w-md"
      :dismissable-mask="true"
    >
      <form class="flex flex-col gap-3 mt-2" @submit.prevent="saveAddress">
        <div class="flex flex-col gap-1">
          <label class="label-small">Type</label>
          <Select
            v-model="draft.type"
            :options="TYPE_OPTS"
            option-label="label"
            option-value="value"
            fluid
          />
          <p v-if="fieldError('type')" class="text-xs text-red-600 m-0">
            {{ fieldError("type") }}
          </p>
        </div>
        <div class="flex flex-col gap-1">
          <label class="label-small">Street</label>
          <InputText v-model.trim="draft.street" fluid />
          <p v-if="fieldError('street')" class="text-xs text-red-600 m-0">
            {{ fieldError("street") }}
          </p>
        </div>
        <div class="grid grid-cols-2 gap-2">
          <div class="flex flex-col gap-1">
            <label class="label-small">Number</label>
            <InputText v-model.trim="draft.house_number" fluid />
            <p v-if="fieldError('house_number')" class="text-xs text-red-600 m-0">
              {{ fieldError("house_number") }}
            </p>
          </div>
          <div class="flex flex-col gap-1">
            <label class="label-small">Addition</label>
            <InputText v-model.trim="draft.house_number_addition" fluid />
          </div>
        </div>
        <div class="flex flex-col gap-1">
          <label class="label-small">Postal code</label>
          <InputText v-model.trim="draft.postal_code" fluid />
          <p v-if="fieldError('postal_code')" class="text-xs text-red-600 m-0">
            {{ fieldError("postal_code") }}
          </p>
        </div>
        <div class="flex flex-col gap-1">
          <label class="label-small">City</label>
          <InputText v-model.trim="draft.city" fluid />
          <p v-if="fieldError('city')" class="text-xs text-red-600 m-0">
            {{ fieldError("city") }}
          </p>
        </div>
        <div class="flex flex-col gap-1">
          <label class="label-small">Country</label>
          <InputText v-model.trim="draft.country" fluid maxlength="255" />
        </div>
        <div class="flex items-center gap-2 pt-2">
          <Checkbox v-model="draft.is_primary" binary input-id="ca-primary" />
          <label for="ca-primary" class="label-small cursor-pointer">
            Primary address
          </label>
        </div>
        <div class="flex justify-end gap-2 pt-2">
          <Button
            type="button"
            label="Cancel"
            severity="secondary"
            outlined
            @click="dialogVisible = false"
          />
          <BaseButton variant="primary" type="submit" :loading="saving">
            Save
          </BaseButton>
        </div>
      </form>
    </Dialog>
  </div>
</template>
