import type { ReactNode } from 'react'
import { Card } from './Card'
import { Button } from './Button'
import { t } from '@/lib/i18n'
import { classifyError, type ErrorClassification } from '@/lib/errorClassification'

interface ErrorStateProps {
  message: string
  action?: ReactNode
  className?: string
  onRetry?: () => void
  onCheckConnection?: () => void
  showDocumentationLink?: boolean
  error?: unknown
}

function ErrorIcon(): React.ReactElement {
  return (
    <svg
      className="w-5 h-5"
      fill="none"
      stroke="currentColor"
      viewBox="0 0 24 24"
      xmlns="http://www.w3.org/2000/svg"
    >
      <path
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeWidth={2}
        d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
      />
    </svg>
  )
}

function getUserFriendlyMessage(classification: ErrorClassification): string {
  return classification.message
}

function getErrorClassification(error: unknown | undefined): ErrorClassification | null {
  if (error === undefined) {
    return null
  }
  return classifyError(error)
}

function RetryButton({ onRetry }: { onRetry: () => void }): React.ReactElement {
  return (
    <Button type="button" variant="primary" size="small" onClick={onRetry}>
      {t('errors.actions.retry')}
    </Button>
  )
}

function CheckConnectionButton({ onCheckConnection }: { onCheckConnection: () => void }): React.ReactElement {
  return (
    <Button type="button" variant="secondary" size="small" onClick={onCheckConnection}>
      {t('errors.actions.checkConnection')}
    </Button>
  )
}

function DocumentationButton(): React.ReactElement {
  return (
    <Button
      type="button"
      variant="ghost"
      size="small"
      onClick={() => {
        window.open('/docs', '_blank')
      }}
    >
      {t('errors.actions.viewDocumentation')}
    </Button>
  )
}

function computeActionFlags(
  classification: ErrorClassification | null,
  onRetry: (() => void) | undefined,
  onCheckConnection: (() => void) | undefined,
  showDocumentationLink: boolean
): { showRetry: boolean; showCheck: boolean; showDoc: boolean } {
  const canRetry = classification?.canRetry ?? false
  const canCheckConnection = classification?.canCheckConnection ?? false
  const needsDocumentation = classification?.needsDocumentation ?? false

  return {
    showRetry: canRetry && onRetry !== undefined,
    showCheck: canCheckConnection && onCheckConnection !== undefined,
    showDoc: needsDocumentation && showDocumentationLink,
  }
}

function hasAnyAction(
  action: ReactNode | undefined,
  showRetry: boolean,
  showCheck: boolean,
  showDoc: boolean
): boolean {
  return action !== undefined || showRetry || showCheck || showDoc
}

function ErrorActions({
  action,
  classification,
  onRetry,
  onCheckConnection,
  showDocumentationLink,
}: {
  action?: ReactNode
  classification: ErrorClassification | null
  onRetry?: () => void
  onCheckConnection?: () => void
  showDocumentationLink?: boolean
}): React.ReactElement | null {
  const flags = computeActionFlags(classification, onRetry, onCheckConnection, showDocumentationLink ?? false)

  if (!hasAnyAction(action, flags.showRetry, flags.showCheck, flags.showDoc)) {
    return null
  }

  return (
    <div className="mt-3 flex flex-wrap gap-2">
      {action !== undefined && action}
      {flags.showRetry && onRetry !== undefined && <RetryButton onRetry={onRetry} />}
      {flags.showCheck && onCheckConnection !== undefined && <CheckConnectionButton onCheckConnection={onCheckConnection} />}
      {flags.showDoc && <DocumentationButton />}
    </div>
  )
}

export function ErrorState({
  message,
  action,
  className = '',
  onRetry,
  onCheckConnection,
  showDocumentationLink = false,
  error,
}: ErrorStateProps): React.ReactElement {
  const classification = getErrorClassification(error)
  const displayMessage = classification !== null ? getUserFriendlyMessage(classification) : message
  const suggestion = classification?.suggestion !== undefined ? t(classification.suggestion) : undefined

  return (
    <Card variant="default" className={`bg-red-900/20 border-red-500/50 ${className}`} role="alert">
      <div className="flex items-start gap-3">
        <div className="flex-shrink-0 text-red-400">
          <ErrorIcon />
        </div>
        <div className="flex-1">
          <p className="text-sm text-red-400 font-medium mb-2">{displayMessage}</p>
          {suggestion !== undefined && <p className="text-xs text-red-400/70 mb-3">{suggestion}</p>}
          <ErrorActions
            action={action}
            classification={classification}
            {...(onRetry !== undefined ? { onRetry } : {})}
            {...(onCheckConnection !== undefined ? { onCheckConnection } : {})}
            showDocumentationLink={showDocumentationLink}
          />
        </div>
      </div>
    </Card>
  )
}
