<template>
  <PackActionButton
    v-bind="$attrs"
    variant="black"
    :label="$t('manager.updateAll')"
    :loading="isUpdating"
    :loading-message="$t('g.updating')"
    @action="updateAllPacks"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'

import PackActionButton from '@/components/dialog/content/manager/button/PackActionButton.vue'
import { useComfyManagerStore } from '@/stores/comfyManagerStore'
import type { components } from '@/types/comfyRegistryTypes'
import { components as ManagerComponents } from '@/types/generatedManagerTypes'

type NodePack = components['schemas']['Node']

const { nodePacks } = defineProps<{
  nodePacks: NodePack[]
}>()

const isUpdating = ref<boolean>(false)

const managerStore = useComfyManagerStore()

const createPayload = (
  updateItem: NodePack
): ManagerComponents['schemas']['ManagerPackInfo'] => {
  if (!updateItem.id) {
    throw new Error('Node ID is required for update')
  }

  return {
    id: updateItem.id,
    version: updateItem.latest_version?.version || 'latest'
  }
}

const updatePack = async (item: NodePack) => {
  if (!item.id || !item.latest_version?.version) {
    console.warn('Pack missing required id or version:', item)
    return
  }
  await managerStore.updatePack.call(createPayload(item))
}

const updateAllPacks = async () => {
  if (!nodePacks?.length) {
    console.warn('No packs provided for update')
    return
  }

  isUpdating.value = true

  const updatablePacks = nodePacks.filter((pack) =>
    managerStore.isPackInstalled(pack.id)
  )

  if (!updatablePacks.length) {
    console.info('No installed packs available for update')
    isUpdating.value = false
    return
  }

  console.info(`Starting update of ${updatablePacks.length} packs`)

  try {
    await Promise.all(updatablePacks.map(updatePack))
    managerStore.updatePack.clear()
    console.info('All packs updated successfully')
  } catch (error) {
    console.error('Pack update failed:', error)
    console.error(
      'Failed packs info:',
      updatablePacks.map((p) => p.id)
    )
  } finally {
    isUpdating.value = false
  }
}
</script>
