<script setup lang="ts">
import { __ } from '@wordpress/i18n'
import { toRefs, ref, reactive, watch, computed } from 'vue'
import { getSavetoWishlistObj } from '@/config'
import { storeToRefs } from 'pinia'
import {
  loadComponent,
  resolveConditionValue,
  getI18n,
} from '@/helper'
import LoadingSpinner from '@/apps/settings/components/LoadingSpinner.vue'
import Preview from '@/apps/settings/components/controls/Preview.vue'
import { useSettingsStore } from '@/stores/settings-store'

const props = defineProps({
  sectionParent: {
    type: String,
    required: true,
  },
  sectionChild: {
    type: String,
    required: true,
  },
  sectionKey: {
    type: String,
    required: true,
  },
})

const { sectionParent, sectionChild, sectionKey } = toRefs(props)

const settingsStore = useSettingsStore()
const {
  inputValues,
} = storeToRefs(settingsStore)

const tabSettings = getSavetoWishlistObj.settings
let sectionControls = null
if (typeof tabSettings.controls[sectionParent.value][sectionChild.value] !== 'undefined' && tabSettings.controls[sectionParent.value][sectionChild.value] !== null) {
  sectionControls = tabSettings.controls[sectionParent.value][sectionChild.value][sectionKey.value]
}

const controls = ref(sectionControls)
const controlSettings = reactive({
  controls: controls.value,	
})
const emit = defineEmits(['fieldData'])
const conditionalValues = ref<any>([])

if (typeof controls.value !== 'undefined' && controls.value !== null) {
  controlSettings.controls = controls.value.filter((item: any) => {
    if (typeof item.hide !== 'undefined') {
      if (item.hide) {
        return false
      } else {
        if ( typeof inputValues.value[item.id] !== 'undefined' ) {
          item['default'] = inputValues.value[item.id]
        }

        return true
      }
    } else {
      if ( typeof inputValues.value[item.id] !== 'undefined' ) {
        item['default'] = inputValues.value[item.id]
      }
      
      return true
    }
  })
}

/**
 * Handle field data
 * @param {object} data
 */
const otherFieldData = (data: object) => {
  Object.entries(data).forEach(([key, value]) => {
    inputValues.value[key] = value
  })

  emit('fieldData', inputValues.value)
}

const handleFieldData = (event: any, control: any) => {
  const e = event

  if ( control['type'] === 'checkbox' ) {
    e.target.value = e.target.checked
  }

  inputValues.value[control['id']] = e.target.value
  emit('fieldData', inputValues.value)
}

/**
 * Handle conditional data
 * @param {object} data
 */
const conditionalData = (data: object) => {
  let conditionKey = ''
  let conditionValue = ''
  for (const [key, val] of Object.entries(data)) {
    let value = <any>val
    conditionKey = key
    conditionValue = value
  }

  // Update the conditional values with the new condition
  conditionalValues.value[conditionKey] = conditionValue
  inputValues.value[conditionKey] = conditionValue

  controlSettings.controls = controls.value.filter((item: any) => {
    if (typeof item.condition !== 'undefined') {
      // Check if ANY of the item's conditions match the current active conditional values
      const hasMatchingCondition = item.condition.some((cItem: any) => {
        const conditionValue = resolveConditionValue(cItem, inputValues.value, controls.value, conditionalValues.value)
        return conditionValue === cItem.value
      })
      
      if (hasMatchingCondition) {
        if ( typeof inputValues.value[item.id] !== 'undefined' ) {
          item['default'] = inputValues.value[item.id]
        }
        
        return true
      } else {
        return false
      }
    } else {
      if ( typeof inputValues.value[item.id] !== 'undefined' ) {
        item['default'] = inputValues.value[item.id]
      }
      
      return true
    }
  })

  emit('fieldData', inputValues.value)
}

/**
 * Handle field updated data
 * @param {object} items
 */
const fieldUpdatedData = (items: any) => {
  controlSettings.controls = controls.value.filter((item: any) => {
    // Check if item has condition and verify condition is met with inputValues
    if (typeof item.condition !== 'undefined' && Array.isArray(item.condition)) {
      // Check if ANY of the item's conditions match the values from inputValues
      const hasMatchingCondition = item.condition.some((cItem: any) => {
        if (cItem && typeof cItem.key !== 'undefined') {
          const conditionValue = resolveConditionValue(cItem, inputValues.value, controls.value)
          return conditionValue === cItem.value
        }
        return false
      })

      if (hasMatchingCondition) {
        if ( typeof inputValues.value[item.id] !== 'undefined' && inputValues.value[item.id] !== null ) {
          item['default'] = inputValues.value[item.id]
        }

        return true
      } else {
        return false
      }
    } else {
      // No condition, just update default value if available
      if ( typeof inputValues.value[item.id] !== 'undefined' && inputValues.value[item.id] !== null ) {
        item['default'] = inputValues.value[item.id]
      }

      return true
    }
  })
}

const previewRef = (data: any) => {
  fieldUpdatedData(data)
}

/**
 * The control that carries preview_options (e.g. the "Button Type" select)
 * drives a standalone, read-only preview swatch rendered in a sticky column
 * so it stays visible while editing style fields. The select itself stays
 * inline with the other fields — keeping it in the sticky panel too reads
 * as if it were part of the preview rather than a real, editable setting.
 */
const previewControl = computed(() => {
  return controlSettings.controls.find((item: any) => (
    item.preview_options?.text_color &&
    item.preview_options?.background_color &&
    item.preview_options?.border_color
  ))
})

/**
 * The preview control's own inline swatch and description are suppressed
 * in the fields column since the sticky panel already renders the swatch
 * and carries its own caption — otherwise both would show twice.
 */
const fieldParams = (item: any) => {
  if (previewControl.value && item.id === previewControl.value.id) {
    return { ...item, preview: false, description: '' }
  }

  return item
}
</script>

<template>
  <div
    :class="previewControl
      ? 'stwlite-tw-grid stwlite-tw-grid-cols-1 lg:stwlite-tw-grid-cols-[3fr_2fr] stwlite-tw-gap-8 stwlite-tw-items-start'
      : ''"
  >
    <div :class="previewControl ? 'stwlite-tw-space-y-6' : ''">
      <div
        v-for="sectioncontrol in controlSettings.controls"
        :key="sectioncontrol.id"
        :data-testid="`stwl-field-${sectioncontrol.id}`"
      >
        <Suspense>
          <component
            :is="loadComponent(sectioncontrol.type)"
            :params="fieldParams(sectioncontrol)"
            :control-settings="controlSettings.controls"
            :conditional-values="conditionalValues"
            @input="handleFieldData($event, sectioncontrol)"
            @field-data="otherFieldData"
            @conditional-data="conditionalData"
            @selected-condition="conditionalData"
            @field-updated-data="fieldUpdatedData"
            @preview-ref="previewRef"
          />

          <!-- loading state -->
          <template #fallback>
            <loading-spinner />
          </template>
        </Suspense>
      </div>
    </div>

    <div
      v-if="previewControl"
      class="stw-preview-column stwlite-tw-sticky lg:stwlite-tw-border-0 lg:stwlite-tw-border-l lg:stwlite-tw-border-gray-200 lg:stwlite-tw-border-solid lg:stwlite-tw-pl-8"
    >
      <div class="stwlite-tw-bg-gray-50 stwlite-tw-border stwlite-tw-border-gray-200 stwlite-tw-border-solid stwlite-tw-rounded-lg stwlite-tw-overflow-hidden">
        <h4 class="stwlite-tw-text-xs stwlite-tw-font-semibold stwlite-tw-uppercase stwlite-tw-tracking-wide stwlite-tw-text-gray-500 stwlite-tw-text-center stwlite-tw-m-0 stwlite-tw-px-6 stwlite-tw-py-3 stwlite-tw-border-0 stwlite-tw-border-b stwlite-tw-border-gray-200 stwlite-tw-border-solid">
          {{ getI18n('livePreview', __('Live Preview', 'saveto-wishlist-lite-for-woocommerce')) }}
        </h4>
        <div class="stwlite-tw-p-6 stwlite-tw-flex stwlite-tw-flex-col stwlite-tw-items-center stwlite-tw-gap-4">
          <div class="stwlite-tw-w-full stwlite-tw-bg-white stwlite-tw-border stwlite-tw-border-gray-200 stwlite-tw-border-solid stwlite-tw-rounded-md stwlite-tw-shadow-sm stwlite-tw-py-6 stwlite-tw-flex stwlite-tw-items-center stwlite-tw-justify-center">
            <Preview
              :selected_value="previewControl.default"
              :preview_options="previewControl.preview_options"
              :controls="controlSettings.controls"
            />
          </div>
          <p class="stwlite-tw-text-xs stwlite-tw-text-gray-500 stwlite-tw-text-center stwlite-tw-leading-relaxed stwlite-tw-max-w-[11rem] stwlite-tw-mx-auto stwlite-tw-m-0">
            {{ getI18n('livePreviewHoverHint', __('Hover the button to preview its hover state.', 'saveto-wishlist-lite-for-woocommerce')) }}
          </p>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.stw-preview-column {
  top: var(--stwlite-sticky-top, 113px);
}
</style> 