<script setup lang="ts">
import { computed, ref, watch, onMounted } from 'vue'
import type { Ref } from 'vue'

interface CustomFieldOption {
  label: string
  value: string
}

interface CustomFieldData {
  label: string
  value: string
  slug: string
  model_type: string
}

interface FieldGroup {
  label: string
  fields: CustomFieldOption[]
}

type FieldType =
  | 'shipping'
  | 'billing'
  | 'customer'
  | 'invoice'
  | 'estimate'
  | 'payment'
  | 'company'

interface Props {
  contentLoading?: boolean
  modelValue?: string
  fields?: FieldType[] | null
  customFields?: CustomFieldData[]
}

interface Emits {
  (e: 'update:modelValue', value: string): void
}

const props = withDefaults(defineProps<Props>(), {
  contentLoading: false,
  modelValue: '',
  fields: null,
  customFields: () => [],
})

const emit = defineEmits<Emits>()

const fieldList = ref<FieldGroup[]>([])
const invoiceFields = ref<CustomFieldData[]>([])
const estimateFields = ref<CustomFieldData[]>([])
const paymentFields = ref<CustomFieldData[]>([])
const customerFields = ref<CustomFieldData[]>([])

watch(
  () => props.fields,
  () => {
    if (props.fields && props.fields.length > 0) {
      getFields()
    }
  }
)

watch(
  () => props.customFields,
  (newValue: CustomFieldData[] | undefined) => {
    const data = newValue ?? []
    invoiceFields.value = data.filter((field) => field.model_type === 'Invoice')
    customerFields.value = data.filter(
      (field) => field.model_type === 'Customer'
    )
    paymentFields.value = data.filter(
      (field) => field.model_type === 'Payment'
    )
    estimateFields.value = data.filter(
      (field) => field.model_type === 'Estimate'
    )
    getFields()
  }
)

const value = computed<string>({
  get: () => props.modelValue,
  set: (val: string) => {
    emit('update:modelValue', val)
  },
})

function getFields(): void {
  fieldList.value = []
  if (!props.fields || props.fields.length === 0) return

  if (props.fields.includes('shipping')) {
    fieldList.value.push({
      label: 'Shipping Address',
      fields: [
        { label: 'Address name', value: 'SHIPPING_ADDRESS_NAME' },
        { label: 'Country', value: 'SHIPPING_COUNTRY' },
        { label: 'State', value: 'SHIPPING_STATE' },
        { label: 'City', value: 'SHIPPING_CITY' },
        { label: 'Address Street 1', value: 'SHIPPING_ADDRESS_STREET_1' },
        { label: 'Address Street 2', value: 'SHIPPING_ADDRESS_STREET_2' },
        { label: 'Phone', value: 'SHIPPING_PHONE' },
        { label: 'Zip Code', value: 'SHIPPING_ZIP_CODE' },
      ],
    })
  }

  if (props.fields.includes('billing')) {
    fieldList.value.push({
      label: 'Billing Address',
      fields: [
        { label: 'Address name', value: 'BILLING_ADDRESS_NAME' },
        { label: 'Country', value: 'BILLING_COUNTRY' },
        { label: 'State', value: 'BILLING_STATE' },
        { label: 'City', value: 'BILLING_CITY' },
        { label: 'Address Street 1', value: 'BILLING_ADDRESS_STREET_1' },
        { label: 'Address Street 2', value: 'BILLING_ADDRESS_STREET_2' },
        { label: 'Phone', value: 'BILLING_PHONE' },
        { label: 'Zip Code', value: 'BILLING_ZIP_CODE' },
      ],
    })
  }

  if (props.fields.includes('customer')) {
    fieldList.value.push({
      label: 'Customer',
      fields: [
        { label: 'Display Name', value: 'CONTACT_DISPLAY_NAME' },
        { label: 'Contact Name', value: 'PRIMARY_CONTACT_NAME' },
        { label: 'Email', value: 'CONTACT_EMAIL' },
        { label: 'Phone', value: 'CONTACT_PHONE' },
        { label: 'Website', value: 'CONTACT_WEBSITE' },
        { label: 'Tax ID', value: 'CONTACT_TAX_ID' },
        ...customerFields.value.map((i) => ({
          label: i.label,
          value: i.slug,
        })),
      ],
    })
  }

  if (props.fields.includes('invoice')) {
    fieldList.value.push({
      label: 'Invoice',
      fields: [
        { label: 'Date', value: 'INVOICE_DATE' },
        { label: 'Due Date', value: 'INVOICE_DUE_DATE' },
        { label: 'Number', value: 'INVOICE_NUMBER' },
        { label: 'Ref Number', value: 'INVOICE_REF_NUMBER' },
        ...invoiceFields.value.map((i) => ({
          label: i.label,
          value: i.slug,
        })),
      ],
    })
  }

  if (props.fields.includes('estimate')) {
    fieldList.value.push({
      label: 'Estimate',
      fields: [
        { label: 'Date', value: 'ESTIMATE_DATE' },
        { label: 'Expiry Date', value: 'ESTIMATE_EXPIRY_DATE' },
        { label: 'Number', value: 'ESTIMATE_NUMBER' },
        { label: 'Ref Number', value: 'ESTIMATE_REF_NUMBER' },
        ...estimateFields.value.map((i) => ({
          label: i.label,
          value: i.slug,
        })),
      ],
    })
  }

  if (props.fields.includes('payment')) {
    fieldList.value.push({
      label: 'Payment',
      fields: [
        { label: 'Date', value: 'PAYMENT_DATE' },
        { label: 'Number', value: 'PAYMENT_NUMBER' },
        { label: 'Mode', value: 'PAYMENT_MODE' },
        { label: 'Amount', value: 'PAYMENT_AMOUNT' },
        ...paymentFields.value.map((i) => ({
          label: i.label,
          value: i.slug,
        })),
      ],
    })
  }

  if (props.fields.includes('company')) {
    fieldList.value.push({
      label: 'Company',
      fields: [
        { label: 'Company Name', value: 'COMPANY_NAME' },
        { label: 'Country', value: 'COMPANY_COUNTRY' },
        { label: 'State', value: 'COMPANY_STATE' },
        { label: 'City', value: 'COMPANY_CITY' },
        { label: 'Address Street 1', value: 'COMPANY_ADDRESS_STREET_1' },
        { label: 'Address Street 2', value: 'COMPANY_ADDRESS_STREET_2' },
        { label: 'Phone', value: 'COMPANY_PHONE' },
        { label: 'Zip Code', value: 'COMPANY_ZIP_CODE' },
        { label: 'Vat Id', value: 'COMPANY_VAT' },
        { label: 'Tax Id', value: 'COMPANY_TAX' },
      ],
    })
  }
}

getFields()
</script>

<template>
  <BaseContentPlaceholders v-if="contentLoading">
    <BaseContentPlaceholdersBox
      :rounded="true"
      class="w-full"
      style="height: 200px"
    />
  </BaseContentPlaceholders>

  <div v-else class="relative">
    <div class="absolute bottom-0 right-0 z-10">
      <BaseDropdown
        :close-on-select="true"
        max-height="220"
        position="top-end"
        width-class="w-auto min-w-[40rem]"
        class="mb-2"
      >
        <template #activator>
          <BaseButton type="button" variant="primary-outline" class="mr-4">
            {{ $t('settings.customization.insert_fields') }}
            <template #left="slotProps">
              <BaseIcon name="PlusSmIcon" :class="slotProps.class" />
            </template>
          </BaseButton>
        </template>

        <div class="flex p-2">
          <ul v-for="(type, index) in fieldList" :key="index" class="list-none">
            <li class="mb-1 ml-2 text-xs font-semibold text-muted uppercase">
              {{ type.label }}
            </li>

            <li
              v-for="(field, fieldIndex) in type.fields"
              :key="fieldIndex"
              class="
                w-48
                text-sm
                font-normal
                cursor-pointer
                hover:bg-hover-strong
                rounded
                ml-1
                py-0.5
              "
              @click="value += `{${field.value}}`"
            >
              <div class="flex pl-1">
                <BaseIcon
                  name="ChevronDoubleRightIcon"
                  class="h-3 mt-1 mr-2 text-subtle"
                />

                {{ field.label }}
              </div>
            </li>
          </ul>
        </div>
      </BaseDropdown>
    </div>
    <BaseEditor v-model="value" />
  </div>
</template>
