import type { Nip95Config } from '@/lib/configStorageTypes'
import { Button, Card, Input } from '../ui'
import { t } from '@/lib/i18n'
import { DragHandle } from '../DragHandle'
import { getApiCardClassName } from './getApiCardClassName'

function Nip95ApiCardContent(params: {
  api: Nip95Config
  priority: number
  isEditing: boolean
  onStartEditing: (id: string) => void
  onStopEditing: () => void
  onUpdateUrl: (id: string, url: string) => void
  onToggleEnabled: (id: string, enabled: boolean) => void
  onRemoveApi: (id: string) => void
  onDragStart: (e: React.DragEvent<HTMLDivElement>, id: string) => void
}): React.ReactElement {
  return (
    <>
      <div className="flex items-start justify-between gap-4">
        <div className="flex items-center gap-3 flex-1">
          <DragGrip apiId={params.api.id} onDragStart={params.onDragStart} />
          <UrlCell
            api={params.api}
            isEditing={params.isEditing}
            onStartEditing={params.onStartEditing}
            onStopEditing={params.onStopEditing}
            onUpdateUrl={params.onUpdateUrl}
          />
        </div>
        <ActionsCell api={params.api} onToggleEnabled={params.onToggleEnabled} onRemoveApi={params.onRemoveApi} />
      </div>
      <PriorityRow priority={params.priority} apiId={params.api.id} />
    </>
  )
}

export function Nip95ApiCard(params: {
  api: Nip95Config
  priority: number
  isEditing: boolean
  draggedId: string | null
  dragOverId: string | null
  onStartEditing: (id: string) => void
  onStopEditing: () => void
  onUpdateUrl: (id: string, url: string) => void
  onToggleEnabled: (id: string, enabled: boolean) => void
  onRemoveApi: (id: string) => void
  onDragStart: (e: React.DragEvent<HTMLDivElement>, id: string) => void
  onDragOver: (e: React.DragEvent<HTMLDivElement>, id: string) => void
  onDragLeave: () => void
  onDrop: (e: React.DragEvent<HTMLDivElement>, targetId: string) => void
}): React.ReactElement {
  return (
    <div
      onDragOver={(e: React.DragEvent<HTMLDivElement>) => params.onDragOver(e, params.api.id)}
      onDragLeave={params.onDragLeave}
      onDrop={(e: React.DragEvent<HTMLDivElement>) => params.onDrop(e, params.api.id)}
      className={getApiCardClassName(params.api.id, params.draggedId, params.dragOverId)}
    >
      <Card variant="default" className="bg-cyber-dark space-y-3 transition-all">
        <Nip95ApiCardContent
          api={params.api}
          priority={params.priority}
          isEditing={params.isEditing}
          onStartEditing={params.onStartEditing}
          onStopEditing={params.onStopEditing}
          onUpdateUrl={params.onUpdateUrl}
          onToggleEnabled={params.onToggleEnabled}
          onRemoveApi={params.onRemoveApi}
          onDragStart={params.onDragStart}
        />
      </Card>
    </div>
  )
}

function DragGrip(params: { apiId: string; onDragStart: (e: React.DragEvent<HTMLDivElement>, id: string) => void }): React.ReactElement {
  return (
    <div
      className="drag-handle cursor-grab active:cursor-grabbing"
      draggable
      onDragStart={(e) => {
        params.onDragStart(e, params.apiId)
        e.stopPropagation()
      }}
      onMouseDown={(e) => e.stopPropagation()}
    >
      <DragHandle />
    </div>
  )
}

function UrlCell(params: {
  api: Nip95Config
  isEditing: boolean
  onStartEditing: (id: string) => void
  onStopEditing: () => void
  onUpdateUrl: (id: string, url: string) => void
}): React.ReactElement {
  return <div className="flex-1">{params.isEditing ? <UrlEditor api={params.api} onStop={params.onStopEditing} onUpdate={params.onUpdateUrl} /> : <UrlText api={params.api} onStartEditing={params.onStartEditing} />}</div>
}

function UrlText(params: { api: Nip95Config; onStartEditing: (id: string) => void }): React.ReactElement {
  return (
    <div
      className="text-neon-cyan cursor-pointer hover:text-neon-green transition-colors"
      onClick={() => params.onStartEditing(params.api.id)}
      title={t('settings.nip95.list.editUrl')}
    >
      {params.api.url}
    </div>
  )
}

function UrlEditor(params: { api: Nip95Config; onStop: () => void; onUpdate: (id: string, url: string) => void }): React.ReactElement {
  return (
    <Input
      type="url"
      defaultValue={params.api.url}
      onBlur={(e) => {
        const next = e.target.value
        if (next !== params.api.url) {
          params.onUpdate(params.api.id, next)
        } else {
          params.onStop()
        }
      }}
      onKeyDown={(e) => {
        if (e.key === 'Enter') {
          e.currentTarget.blur()
        } else if (e.key === 'Escape') {
          params.onStop()
        }
      }}
      className="w-full bg-cyber-darker border-neon-cyan/50 text-cyber-light"
      autoFocus
    />
  )
}

function ActionsCell(params: { api: Nip95Config; onToggleEnabled: (id: string, enabled: boolean) => void; onRemoveApi: (id: string) => void }): React.ReactElement {
  return (
    <div className="flex items-center gap-2">
      <EnabledToggle api={params.api} onToggleEnabled={params.onToggleEnabled} />
      <RemoveButton apiId={params.api.id} onRemove={params.onRemoveApi} />
    </div>
  )
}

function EnabledToggle(params: { api: Nip95Config; onToggleEnabled: (id: string, enabled: boolean) => void }): React.ReactElement {
  return (
    <label className="flex items-center gap-2 cursor-pointer">
      <input
        type="checkbox"
        checked={params.api.enabled}
        onChange={(e) => params.onToggleEnabled(params.api.id, e.target.checked)}
        className="w-4 h-4 text-neon-cyan bg-cyber-darker border-cyber-accent rounded focus:ring-neon-cyan"
      />
      <span className="text-sm text-cyber-accent">
        {params.api.enabled ? t('settings.nip95.list.enabled') : t('settings.nip95.list.disabled')}
      </span>
    </label>
  )
}

function RemoveButton(params: { apiId: string; onRemove: (id: string) => void }): React.ReactElement {
  return (
    <Button
      type="button"
      variant="danger"
      size="small"
      onClick={() => params.onRemove(params.apiId)}
      aria-label={t('settings.nip95.list.remove')}
    >
      {t('settings.nip95.list.remove')}
    </Button>
  )
}

function PriorityRow(params: { priority: number; apiId: string }): React.ReactElement {
  return (
    <div className="flex items-center gap-2 text-xs text-cyber-accent/70">
      <span>{t('settings.nip95.list.priorityLabel', { priority: params.priority, id: params.apiId })}</span>
    </div>
  )
}
