<script setup lang="ts">
import { __ } from '@wordpress/i18n'
import { toRefs, reactive, ref } from 'vue';
import { storeToRefs } from 'pinia'
import DynamicComponents from '@/apps/settings/components/DynamicComponents.vue';
import ImporterTool from '@/apps/settings/components/ImporterTool.vue';
import Confirmation from '@/helper/Confirmation.vue';
import Notification from '@/helper/Notification.vue';
import { getSavetoWishlistObj } from '@/config'
import {
  purifyHtml,
  getI18n,
  sendRequest,
} from '@/helper';
import { useSettingsStore } from '@/stores/settings-store'

const props = defineProps({
  sectionData: {
    type: Object,
    required: true,
  },
  parentTab: {
    type: String,
    required: true,
  },
  childTab: {
    type: String,
    required: true,
  },
})
const { sectionData, parentTab, childTab } = toRefs(props)

// Check if this is the importer section
const isImporterSection = childTab.value === 'importer' && Object.keys(sectionData.value).includes('importer_settings')

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

const sections = sectionData;
const parent = parentTab;
const child = childTab;

const emit = defineEmits(['fieldData']);
const handleFieldData = (data: object) => {
  Object.entries(data).forEach(([key, value]) => {
    inputValues.value[key] = value;
  });
  emit('fieldData', inputValues.value);
}

const tabSettings = getSavetoWishlistObj.settings
const factoryDefaults = tabSettings.factoryDefaults ?? {}

/**
 * Every remount bump forces `DynamicComponents` to re-read `inputValues`
 * into each control's initial value, since controls only read their
 * `default` prop once (on mount) rather than reactively.
 */
const resetNonces = reactive<Record<string, number>>({})

const getSectionControls = (sectionkey: string) =>
  tabSettings.controls?.[parent.value]?.[child.value]?.[sectionkey] ?? []

/**
 * The option ids belonging to a section — used both to know which fields
 * are resettable and which ids to reset/persist. Controls flagged
 * `preserve_on_reset` server-side (the Configuration Mode radio) are left
 * out: a reset restores the styling values inside the mode the user is
 * working in, it does not switch modes on them.
 */
const getSectionControlIds = (sectionkey: string) => {
  return getSectionControls(sectionkey)
    .filter((control: any) => !control.preserve_on_reset)
    .map((control: any) => control.id)
    .filter((id: string) => id && Object.prototype.hasOwnProperty.call(factoryDefaults, id))
}

/**
 * A control can gate its whole section's reset button via `reset_hidden_values`
 * — the values of that control for which there is nothing plugin-owned left to
 * restore (e.g. the "Theme Default" configuration mode, where the theme owns
 * the button styling).
 */
const isResetHidden = (sectionkey: string) => getSectionControls(sectionkey).some((control: any) => {
  if (!control.id || !Array.isArray(control.reset_hidden_values)) {
    return false
  }

  const currentValue = inputValues.value[control.id] ?? control.default

  return control.reset_hidden_values.includes(currentValue)
})

const isResettable = (sectionkey: string) => !isResetHidden(sectionkey) && getSectionControlIds(sectionkey).length > 0

const resetTarget = ref<string | null>(null)
const isResetting = ref<boolean>(false)
const notificationMessageTitle = ref<string>('')
const notificationMessage = ref<string>('')
const notificationType = ref<string>('')

const openResetConfirm = (sectionkey: string) => {
  resetTarget.value = sectionkey
}

const closeResetConfirm = () => {
  resetTarget.value = null
}

const closeNotification = () => {
  notificationMessage.value = ''
}

const confirmReset = async () => {
  const sectionkey = resetTarget.value
  if (!sectionkey) {
    return
  }

  isResetting.value = true

  const ids = getSectionControlIds(sectionkey)
  const payload = ids.map((id: string) => ({ key: id, value: factoryDefaults[id] }))

  try {
    const response = await sendRequest(payload)
    notificationType.value = response.type

    if (response.type === 'success') {
      payload.forEach(({ key, value }: { key: string, value: any }) => {
        inputValues.value[key] = value
      })
      resetNonces[sectionkey] = (resetNonces[sectionkey] ?? 0) + 1
      notificationMessageTitle.value = getI18n('resetToDefaultSuccessTitle', __('Reset to Default', 'saveto-wishlist-lite-for-woocommerce'))
      notificationMessage.value = getI18n('resetToDefaultSuccessMessage', __('This section\'s settings have been restored to their default values.', 'saveto-wishlist-lite-for-woocommerce'))
    } else {
      notificationMessageTitle.value = response.title
      notificationMessage.value = response.message
    }
  } catch (error) {
    // inputValues is only written after a successful response, so there is nothing to
    // roll back here — the store still holds the pre-reset values. Just surface the error.
    console.error(error)
    notificationType.value = 'error'
    notificationMessageTitle.value = getI18n('resetToDefaultErrorTitle', __('Reset Failed', 'saveto-wishlist-lite-for-woocommerce'))
    notificationMessage.value = getI18n('resetToDefaultErrorMessage', __('This section\'s settings could not be reset. Please try again.', 'saveto-wishlist-lite-for-woocommerce'))
  } finally {
    isResetting.value = false
    resetTarget.value = null
  }
}
</script>

<template>
  <section
    v-for="(section, sectionkey) in sections"
    :key="sectionkey"
    :data-testid="`stwl-section-${sectionkey}`"
    class="stw-section-handle stwlite-tw-bg-white stwlite-tw-rounded-lg stwlite-tw-shadow-sm stwlite-tw-border stwlite-tw-border-gray-200 stwlite-tw-p-6 stwlite-tw-space-y-6 stwlite-tw-border-solid"
  >
    <div
      v-if="section.label || (!isImporterSection && isResettable(sectionkey.toString()))"
      class="stwlite-tw-flex stwlite-tw-items-center stwlite-tw-justify-between stwlite-tw-gap-4"
    >
      <h3
        v-if="section.label"
        class="stwlite-tw-font-medium stwlite-tw-text-gray-900 stwlite-tw-m-0"
      >
        {{ section.label }}
      </h3>
      <button
        v-if="!isImporterSection && isResettable(sectionkey.toString())"
        type="button"
        class="stwlite-tw-bg-transparent stwlite-tw-text-gray-600 stwlite-tw-border stwlite-tw-border-gray-300 stwlite-tw-border-solid stwlite-tw-rounded-md stwlite-tw-px-3 stwlite-tw-py-1.5 stwlite-tw-text-sm stwlite-tw-font-medium stwlite-tw-cursor-pointer hover:stwlite-tw-bg-gray-50 stwlite-tw-shrink-0 stwlite-tw-ml-auto"
        @click="openResetConfirm(sectionkey.toString())"
      >
        {{ getI18n('resetToDefault', __('Reset to Default', 'saveto-wishlist-lite-for-woocommerce')) }}
      </button>
    </div>
    <div
      v-if="section.desc != ''"
      class="stwlite-tw-text-sm stwlite-tw-text-gray-600 stwlite-tw-mt-1"
      v-html="purifyHtml(section.desc?.length ? section.desc : '')"
    />

    <!-- Load ImporterTool for importer section -->
    <ImporterTool v-if="isImporterSection && sectionkey === 'importer_settings'" />

    <!-- Load controls for other sections -->
    <DynamicComponents
      v-else
      :key="`${sectionkey}-${resetNonces[sectionkey.toString()] ?? 0}`"
      :section-parent="parent"
      :section-child="child"
      :section-key="sectionkey"
      @field-data="handleFieldData"
    />
  </section>

  <Confirmation
    :isOpen="resetTarget !== null"
    :processing="isResetting"
    :title="getI18n('resetToDefaultTitle', __('Reset to Default', 'saveto-wishlist-lite-for-woocommerce'))"
    :message="getI18n('resetToDefaultMessage', __('Are you sure you want to restore this section\'s settings to their default values? This cannot be undone.', 'saveto-wishlist-lite-for-woocommerce'))"
    :confirmText="getI18n('resetToDefaultConfirm', __('Reset', 'saveto-wishlist-lite-for-woocommerce'))"
    :cancelText="getI18n('cancel', __('Cancel', 'saveto-wishlist-lite-for-woocommerce'))"
    @closeAction="closeResetConfirm"
    @confirmAction="confirmReset"
  />

  <Teleport to="#saveto-wishlist-admin-app-settings">
    <Notification
      v-if="notificationMessage"
      :message="notificationMessage"
      :type="notificationType"
      :messageTitle="notificationMessageTitle"
      @closeNotification="closeNotification"
    />
  </Teleport>
</template>

<style lang="scss" scoped>

</style>
