import { useState } from 'react'
import { Button, Card } from './ui'
import type { MediaRef } from '@/types/nostr'
import { uploadNip95Media } from '@/lib/nip95'
import { t } from '@/lib/i18n'

interface MarkdownEditorProps {
  value: string
  onChange: (value: string) => void
  onMediaAdd?: (media: MediaRef) => void
  onBannerChange?: (url: string) => void
}

export function MarkdownEditor(props: MarkdownEditorProps): React.ReactElement {
  return <MarkdownEditorInner {...props} />
}

function MarkdownEditorInner({ value, onChange, onMediaAdd, onBannerChange }: MarkdownEditorProps): React.ReactElement {
  const [uploading, setUploading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [preview, setPreview] = useState(false)

  return (
    <div className="space-y-3">
      <MarkdownToolbar
        preview={preview}
        onTogglePreview={() => setPreview((p) => !p)}
        onFileSelected={(file) => {
          const handlers = {
            setError,
            setUploading,
            ...(onMediaAdd ? { onMediaAdd } : {}),
            ...(onBannerChange ? { onBannerChange } : {}),
          }
          void handleUpload(file, handlers)
        }}
        uploading={uploading}
        error={error}
      />
      {preview ? (
        <MarkdownPreview value={value} />
      ) : (
        <textarea
          className="w-full border rounded p-3 h-64"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        />
      )}
    </div>
  )
}

function MarkdownToolbar({
  preview,
  onTogglePreview,
  onFileSelected,
  uploading,
  error,
}: {
  preview: boolean
  onTogglePreview: () => void
  onFileSelected: (file: File) => void
  uploading: boolean
  error: string | null
}): React.ReactElement {
  return (
    <div className="flex items-center gap-2">
      <Button type="button" variant="secondary" size="small" onClick={onTogglePreview} className="px-3 py-1 text-sm rounded bg-gray-200">
        {preview ? t('upload.edit') : t('upload.preview')}
      </Button>
      <label className="px-3 py-1 text-sm rounded bg-blue-600 text-white cursor-pointer hover:bg-blue-700">
        {t('markdown.upload.media')}
        <input
          type="file"
          accept=".png,.jpg,.jpeg,.webp,.mp4,.webm,.mov,.qt"
          className="hidden"
          onChange={(e) => {
            const file = e.target.files?.[0]
            if (file) {
              onFileSelected(file)
            }
          }}
        />
      </label>
      {uploading && <span className="text-sm text-gray-500">{t('markdown.upload.uploading')}</span>}
      {error && <span className="text-sm text-red-600">{error}</span>}
    </div>
  )
}

function MarkdownPreview({ value }: { value: string }): React.ReactElement {
  return (
    <Card variant="default" className="prose max-w-none bg-white whitespace-pre-wrap">
      {value}
    </Card>
  )
}

async function handleUpload(
  file: File,
  handlers: {
    setError: (error: string | null) => void
    setUploading: (uploading: boolean) => void
    onMediaAdd?: (media: MediaRef) => void
    onBannerChange?: (url: string) => void
  }
): Promise<void> {
  handlers.setError(null)
  handlers.setUploading(true)
  try {
    const media = await uploadNip95Media(file)
    handlers.onMediaAdd?.(media)
    if (media.type === 'image') {
      handlers.onBannerChange?.(media.url)
    }
  } catch (e) {
    handlers.setError(e instanceof Error ? e.message : t('upload.error.failed'))
  } finally {
    handlers.setUploading(false)
  }
}
