import { useCallback, useEffect, useState } from 'react'

import { TFileId, TQueueItemOperation } from '../types'

export const useOperationState = (queueItemOperations: TQueueItemOperation[]) => {
  const [activatedIds, setActivatedIds] = useState<Record<TFileId, string>>({})

  // If an operation is removed from the list while still referenced as "activated",
  // the stored id would re-activate a freshly-added operation with the same id
  // (e.g. an extension re-mounted). Drop any stale entries on list changes so the
  // activation state can never refer to an operation that no longer exists.
  useEffect(() => {
    setActivatedIds((prev) => {
      const validIds = new Set(queueItemOperations.map((op) => op.id))
      let changed = false
      const next: Record<TFileId, string> = {}
      for (const [fileId, opId] of Object.entries(prev)) {
        if (validIds.has(opId)) {
          next[fileId] = opId
        } else {
          changed = true
        }
      }
      return changed ? next : prev
    })
  }, [queueItemOperations])

  const getActivated = useCallback(
    (fileId: TFileId): TQueueItemOperation | undefined => {
      const id = activatedIds[fileId]
      if (!id) return undefined
      return queueItemOperations.find((op) => op.id === id)
    },
    [activatedIds, queueItemOperations],
  )

  const activate = useCallback((fileId: TFileId, operation: TQueueItemOperation) => {
    setActivatedIds((prev) => ({ ...prev, [fileId]: operation.id }))
  }, [])

  const close = useCallback((fileId: TFileId) => {
    setActivatedIds((prev) => {
      if (!(fileId in prev)) return prev
      const updated = { ...prev }
      delete updated[fileId]
      return updated
    })
  }, [])

  return { getActivated, activate, close }
}
