import { FC, ReactNode } from 'react'

import { PktIcon } from '..'
import { OperationButton, TransferError, TransferInProgress } from './Subcomponents'
import { TFileAndTransfer, TFileId, TItemRenderer, TQueueItemOperation, TTransferItemInProgress } from './types'

const isImageFile = (item: TFileAndTransfer): boolean => {
  if (item.file.type?.startsWith('image/')) return true
  return /\.(jpe?g|png|gif|webp|heic|heif|bmp|svg)$/i.test(item.file.name || '')
}

type TProgressState = 'in-progress' | 'error' | 'idle'

export const getProgressState = (progress: TFileAndTransfer['progress']): TProgressState => {
  if (typeof progress === 'number') return 'in-progress'
  if (progress === 'error') return 'error'
  return 'idle'
}

// ============================================
// OperationActions - Renders action buttons for a file
// ============================================

interface IOperationActions {
  operations: TQueueItemOperation[]
  activatedOperation?: TQueueItemOperation
  onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void
  transferItem: TFileAndTransfer
}

export const OperationActions: FC<IOperationActions> = ({
  operations,
  activatedOperation,
  onActivate,
  transferItem,
}) => (
  <div className="pkt-fileupload__queue-display__item__actions">
    {operations
      .filter((op) => !activatedOperation || op.symbol !== activatedOperation.symbol)
      .map((operation) => (
        <OperationButton
          key={operation.symbol.toString()}
          operation={operation}
          onActivate={onActivate}
          transferItem={transferItem}
        />
      ))}
  </div>
)

// ============================================
// OperationContents - Renders operation content areas
// ============================================

interface IOperationContents {
  operations: TQueueItemOperation[]
  activatedOperation?: TQueueItemOperation
  onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void
  transferItem: TFileAndTransfer
}

export const OperationContents: FC<IOperationContents> = ({
  operations,
  activatedOperation,
  onActivate,
  transferItem,
}) => (
  <>
    {operations
      .filter((op) => op.renderContent)
      .map((operation) => (
        <div className="pkt-fileupload__queue-display__item__operation-content" key={operation.symbol.toString()}>
          {operation.renderContent!(
            transferItem,
            () => onActivate(transferItem.fileId, operation),
            activatedOperation?.symbol === operation.symbol,
          )}
        </div>
      ))}
  </>
)

// ============================================
// IdleStateContent - Renders content for idle/done state
// ============================================

interface IIdleStateContent {
  transferItem: TFileAndTransfer
  activatedOperation?: TQueueItemOperation
  operations: TQueueItemOperation[]
  ItemRenderer: TItemRenderer
  onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void
  onClose: (fileId: TFileId) => void
  onPreviewClick?: () => void
}

export const IdleStateContent: FC<IIdleStateContent> = ({
  transferItem,
  activatedOperation,
  operations,
  ItemRenderer,
  onActivate,
  onClose,
  onPreviewClick,
}) => {
  const closeUI = () => onClose(transferItem.fileId)

  // When any operation UI is active (rename inline or comments extended), hide all action buttons.
  const hasOperationUIActive = activatedOperation?.renderInlineUI || activatedOperation?.renderExtendedUI
  const visibleOperations = hasOperationUIActive ? [] : operations

  return (
    <>
      {activatedOperation?.renderInlineUI ? (
        <>
          <PktIcon name="document-text" className="pkt-fileupload__queue-display__item__icon" />
          <div className="pkt-fileupload__queue-display__item__inline-ui">
            {activatedOperation.renderInlineUI(transferItem, closeUI)}
          </div>
        </>
      ) : (
        <ItemRenderer transferItem={transferItem} queueItemOperations={operations} onPreviewClick={onPreviewClick} />
      )}

      {visibleOperations.length > 0 && (
        <OperationActions
          operations={visibleOperations}
          activatedOperation={activatedOperation}
          onActivate={onActivate}
          transferItem={transferItem}
        />
      )}

      <OperationContents
        operations={operations}
        activatedOperation={activatedOperation}
        onActivate={onActivate}
        transferItem={transferItem}
      />

      {activatedOperation?.renderExtendedUI && (
        <div className="pkt-fileupload__queue-display__item__expanded-operation-ui">
          {activatedOperation.renderExtendedUI(transferItem, closeUI)}
        </div>
      )}
    </>
  )
}

// ============================================
// QueueItemContent - Main content renderer based on state
// ============================================

interface IQueueItemContent {
  transferItem: TFileAndTransfer
  activatedOperation?: TQueueItemOperation
  operations: TQueueItemOperation[]
  ItemRenderer: TItemRenderer
  enableImagePreview: boolean
  onActivate: (fileId: TFileId, operation: TQueueItemOperation) => void
  onClose: (fileId: TFileId) => void
  onCancelTransfer: (fileId: string) => void
  onOpenPreview: (fileId: TFileId) => void
}

export const QueueItemContent: FC<IQueueItemContent> = ({
  transferItem,
  activatedOperation,
  operations,
  ItemRenderer,
  enableImagePreview,
  onActivate,
  onClose,
  onCancelTransfer,
  onOpenPreview,
}) => {
  const state = getProgressState(transferItem.progress)
  const isPreviewable = enableImagePreview && transferItem.progress === 'done' && isImageFile(transferItem)

  switch (state) {
    case 'in-progress':
      return (
        <TransferInProgress
          aria-live="off"
          transferItem={transferItem as TTransferItemInProgress}
          cancelTransfer={() => onCancelTransfer(transferItem.fileId)}
        />
      )
    case 'error':
      return <TransferError transferItem={transferItem} onRemove={() => onCancelTransfer(transferItem.fileId)} />
    case 'idle':
      return (
        <IdleStateContent
          transferItem={transferItem}
          activatedOperation={activatedOperation}
          operations={operations}
          ItemRenderer={ItemRenderer}
          onActivate={onActivate}
          onClose={onClose}
          onPreviewClick={isPreviewable ? () => onOpenPreview(transferItem.fileId) : undefined}
        />
      )
  }
}
