<template>
  <div
    :class="[
      'ivyforms-field',
      'ivyforms-total-field',
      'ivyforms-total-field--field-' + field.id,
      field.cssClasses,
    ]"
  >
    <IvyFormItem
      :label="field.hideLabel ? '' : field.label"
      :required="field.required"
      :error="error"
      :prop="field.type + '_' + field.fieldIndex"
      :show-info="!!field.description"
      :info-text="field.description || ''"
      :show-info-icon="false"
      :label-position="field.labelPosition === 'default' ? 'top' : field.labelPosition || 'top'"
    >
      <div
        class="ivyforms-total-field__body ivyforms-flex ivyforms-flex-direction-column ivyforms-gap-16 ivyforms-width-100"
      >
        <div
          v-if="showSummaryPanel"
          class="ivyforms-total-field__summary ivyforms-flex ivyforms-flex-direction-column ivyforms-gap-8 ivyforms-width-100"
        >
          <div
            class="ivyforms-total-field__summary-toolbar ivyforms-flex ivyforms-align-items-center ivyforms-justify-content-end ivyforms-width-100"
          >
            <button
              v-if="totalConfig.showPaymentSummaryCloseButton"
              type="button"
              class="ivyforms-total-field__summary-close ivyforms-cursor-pointer"
              :title="closeButtonLabel || undefined"
              :aria-label="closeButtonLabel || undefined"
              @click="summaryDismissed = true"
            >
              <span
                class="ivyforms-total-field__summary-close-inner ivyforms-flex ivyforms-align-items-center ivyforms-justify-content-center"
                aria-hidden="true"
              >
                <IvyIcon
                  name="close"
                  type="outline"
                  size="s"
                  category="global"
                  color="var(--map-base-dusk-symbol-2)"
                />
              </span>
            </button>
          </div>

          <div
            v-if="summaryDisplayLines.length > 0"
            class="ivyforms-total-field__summary-list ivyforms-flex ivyforms-flex-direction-column ivyforms-gap-8 ivyforms-width-100"
          >
            <div
              v-for="(row, rowIdx) in summaryDisplayLines"
              :key="'summary-item-' + rowIdx"
              class="ivyforms-total-field__summary-item ivyforms-flex ivyforms-flex-direction-column ivyforms-gap-2 ivyforms-width-100"
            >
              <div
                class="ivyforms-total-field__summary-item-row ivyforms-flex ivyforms-gap-10 ivyforms-align-items-start ivyforms-justify-content-between ivyforms-width-100"
              >
                <span class="regular-16 text-primary ivyforms-min-width-0">{{ row.label }}</span>
                <span
                  class="ivyforms-flex ivyforms-gap-10 ivyforms-align-items-center ivyforms-flex-shrink-0"
                >
                  <span class="regular-16 text-primary">{{ row.lineTotal }}</span>
                  <span class="regular-16 text-primary">{{ currencySuffix }}</span>
                </span>
              </div>
              <div
                v-if="rowIdx < summaryDisplayLines.length - 1"
                class="ivyforms-total-field__summary-divider ivyforms-total-field__summary-divider--dotted ivyforms-width-100"
                aria-hidden="true"
              />
            </div>
          </div>

          <div
            class="ivyforms-total-field__summary-total ivyforms-flex ivyforms-gap-10 ivyforms-align-items-start ivyforms-justify-content-between ivyforms-width-100"
          >
            <span class="medium-16 text-primary ivyforms-min-width-0">{{ getLabel('total') }}</span>
            <span
              class="ivyforms-flex ivyforms-gap-10 ivyforms-align-items-center ivyforms-flex-shrink-0"
            >
              <span class="medium-16 text-primary">{{ formattedAmount }}</span>
              <span class="medium-16 text-primary">{{ currencySuffix }}</span>
            </span>
          </div>
        </div>

        <div
          v-else
          class="ivyforms-total-field__simple ivyforms-flex ivyforms-gap-10 ivyforms-align-items-center"
        >
          <span v-if="field.inputPrefix" class="regular-16 text-secondary">{{
            field.inputPrefix
          }}</span>
          <span class="regular-16 text-primary" aria-live="polite">{{ formattedAmount }}</span>
          <span class="regular-16 text-primary">{{ currencySuffix }}</span>
          <span v-if="field.inputSuffix" class="regular-16 text-secondary">{{
            field.inputSuffix
          }}</span>
        </div>

        <div
          v-if="showEmptyPaymentMessage"
          class="ivyforms-total-field__empty-payment ivyforms-width-100 ivyforms-mt-8"
        >
          <SafeHTML
            class="ivyforms-total-field__empty-payment-content regular-14"
            :html="totalConfig.emptyPaymentMessageHtml"
            :allowed-tags="ALLOWED_TAGS"
            :allowed-attributes="ALLOWED_ATTR"
          />
        </div>

        <input
          v-if="totalConfig.enableAutocomplete"
          class="ivyforms-visually-hidden"
          tabindex="-1"
          autocomplete="on"
          :aria-hidden="true"
        />
      </div>
    </IvyFormItem>
  </div>
</template>

<script setup lang="ts">
import { computed, inject, ref, watch, type ComputedRef, type Ref } from 'vue'
import type { Field } from '@/types/field'
import IvyFormItem from '@/views/_components/form/IvyFormItem.vue'
import IvyIcon from '@/views/_components/icon/IvyIcon.vue'
import SafeHTML from '@/views/_components/SafeHTML.vue'
import {
  ALLOWED_HTML_TAGS as ALLOWED_TAGS,
  ALLOWED_HTML_ATTR as ALLOWED_ATTR,
} from '@/constants/html-sanitization.ts'
import { useLabels } from '@/composables/useLabels'
import { parseTotalFieldConfig } from '@/utils/totalFieldConfig'
import {
  buildPaymentCartLines,
  formatTotalAmountForDisplay,
  sumPaymentCartLineTotals,
} from '@/utils/totalFieldPricing'
import {
  DEFAULT_CURRENCY_CODE,
  type CurrencyCode,
  getCurrencySymbolForCode,
  isCurrencyCode,
} from '@/constants/supportedCurrencies'

interface FieldProps {
  modelValue: string | number | null | undefined
  field: Field
  disabled?: boolean
  error?: string
}

const props = withDefaults(defineProps<FieldProps>(), {
  modelValue: '',
  disabled: false,
  error: '',
})

const emit = defineEmits(['update:modelValue'])
const { getLabel } = useLabels()

const closeButtonLabel = computed(() => getLabel('close'))

const formValues = inject<Ref<Record<string, unknown>>>('formValues', ref({}))
const formFields = inject<Ref<Field[]>>('formFields', ref([]))

const summaryDismissed = ref(false)

const totalConfig = computed(() => parseTotalFieldConfig(props.field))

const paymentCurrencyInjected = inject<ComputedRef<CurrencyCode> | undefined>(
  'ivyformsPaymentCurrencyCode',
  undefined,
)

const currencySuffix = computed(() => {
  const v = paymentCurrencyInjected?.value
  const code = typeof v === 'string' && isCurrencyCode(v) ? v : DEFAULT_CURRENCY_CODE
  return getCurrencySymbolForCode(code)
})

const paymentLines = computed(() => {
  return buildPaymentCartLines(formFields.value, formValues.value as Record<string, unknown>)
})

const computedTotalAmount = computed(() => sumPaymentCartLineTotals(paymentLines.value))

const formattedAmount = computed(() => formatTotalAmountForDisplay(computedTotalAmount.value))

const summaryDisplayLines = computed(() => {
  return paymentLines.value
    .filter((line) => line.lineTotal > 0)
    .map((line) => ({
      label: line.label,
      lineTotal: formatTotalAmountForDisplay(line.lineTotal),
    }))
})

const showSummaryPanel = computed(() => {
  return (
    totalConfig.value.enablePaymentSummary &&
    !summaryDismissed.value &&
    paymentLines.value.length > 0
  )
})

const hasProductField = computed(() => formFields.value.some((f) => f.type === 'product'))

const showEmptyPaymentMessage = computed(() => {
  const html = totalConfig.value.emptyPaymentMessageHtml?.trim() ?? ''
  if (html === '' || !hasProductField.value) {
    return false
  }
  return computedTotalAmount.value <= 0
})

/** Persisted value is numeric text; prefix/suffix/currency are presentation-only. */
const displayValueForSubmit = computed(() => formattedAmount.value)

watch(
  displayValueForSubmit,
  (next) => {
    const prev =
      props.modelValue === null || props.modelValue === undefined ? '' : String(props.modelValue)
    if (prev === next) {
      return
    }
    emit('update:modelValue', next)
  },
  { immediate: true },
)

watch(
  () => totalConfig.value.enablePaymentSummary,
  () => {
    summaryDismissed.value = false
  },
)
</script>

<style scoped lang="scss">
.ivyforms-total-field {
  &__summary-divider--dotted {
    border-top: 1px dotted var(--map-base-dusk-stroke--2, #c0c5cb);
  }

  &__summary-close {
    border: none;
    background: transparent;
    padding: 0;
    line-height: 0;
  }

  &__summary-total {
    padding-top: 2px;
    border-top: 1px solid var(--map-base-dusk-stroke--2, #c0c5cb);
  }
}
</style>
