<script setup lang="ts">
import { toRefs, ref, reactive, watch } from 'vue'
import { getSavetoWishlistObj } from '@/config'
import { storeToRefs } from 'pinia'
import {
  loadComponent,
  resolveConditionValue,
} from '@/helper'
import LoadingSpinner from '@/apps/settings/components/LoadingSpinner.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)
}
</script>

<template>
  <div
    v-for="(sectioncontrol, sectioncontrolkey) in controlSettings.controls"
    :key="sectioncontrol.id"
    :data-testid="`stwl-field-${sectioncontrol.id}`"
  >
    <Suspense>
      <component
        :is="loadComponent(sectioncontrol.type)"
        :params="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>
</template> 