<script setup lang="ts">
import { ref, shallowRef, watch } from 'vue'
import type { Component } from 'vue'
import { useIntegrationStore } from '@KTXC/stores/integrationStore'
import type { ServiceObject } from '@MailManager/models/service'
import type { ProviderObject } from '@MailManager/models/provider'

const props = defineProps<{
  provider: ProviderObject
  service: ServiceObject
}>()

const emit = defineEmits<{
  'update:service': [value: ServiceObject]
}>()

// Local state
const integrationStore = useIntegrationStore()
const panelCache = new Map<string, Component>()
const panelLoading = ref(false)
const panelActive = shallowRef<Component | null>(null)
const localProvider = ref<ProviderObject>(props.provider)
const localService = ref<ServiceObject>(props.service)

// Local watchers
watch(
  () => props.provider,
  async (provider) => {
    localProvider.value = provider
    await loadProviderPanel()
  }
)

watch(
  () => props.service,
  (service) => {
    localService.value = service
  }
)

watch(
  () => [localProvider.value?.identifier, localService.value?.provider] as const,
  async () => {
    await loadProviderPanel()
  },
  { immediate: true }
)

// Load provider panel
async function loadProviderPanel() {
  const providerIdentifier = localProvider.value?.identifier || localService.value?.provider

  if (!providerIdentifier) {
    panelActive.value = null
    panelLoading.value = false
    return
  }

  // retrieve panel from cache if available
  if (panelCache.has(providerIdentifier)) {
    panelActive.value = panelCache.get(providerIdentifier) || null
    panelLoading.value = false
    return
  }

  panelLoading.value = true

  // retrieve panel from integration store
  const panel = integrationStore.getItems('mail_provider_panels_auth').find((panel: any) => {
    return panel.id === providerIdentifier || panel.id.endsWith(`.${providerIdentifier}`)
  })
  if (!panel?.component) {
    console.warn(`No panel found for provider ID: ${providerIdentifier}`)
    panelActive.value = null
    panelLoading.value = false
    return
  }

  try {
    const module = await panel.component()
    const component = module.default || module
    panelCache.set(providerIdentifier, component)
    panelActive.value = component
  } catch (error) {
    console.error(`Failed to load panel for ${providerIdentifier}:`, error)
    panelActive.value = null
  } finally {
    panelLoading.value = false
  }
}

function handleUpdate(service: ServiceObject) {
  localService.value = service
  emit('update:service', localService.value)
}
</script>

<template>
  <div class="provider-auth-panel">
    <h3 class="text-h6 mb-2">Authentication</h3>
    <p class="text-body-2 text-medium-emphasis mb-6">
      Configure authentication specific settings for {{ localProvider?.label || 'this provider' }}.
    </p>

    <div v-if="panelLoading" class="text-center py-8">
      <v-progress-circular indeterminate color="primary" />
      <p class="text-caption text-medium-emphasis mt-2">
        Loading panel...
      </p>
    </div>

    <v-alert v-else-if="!panelActive" type="info" variant="tonal">
      No panel available for this provider.
    </v-alert>

    <component
      v-else
      :is="panelActive"
      :service="localService"
      @update:service="handleUpdate"
    />
  </div>
</template>
