import {useRef, useState} from 'react'
import {formatBytes, randomBytes} from '../util'

type Props = {
  target: string | null
  targetName: string
  onSendText: (text: string, target: string | null) => void
  onSendBinary: (
    data: Uint8Array<ArrayBuffer>,
    fileName: string,
    mime: string,
    target: string | null
  ) => Promise<void>
}

const RANDOM_SIZES = [
  {label: '256 KB', bytes: 256 * 1024},
  {label: '1 MB', bytes: 1024 * 1024},
  {label: '8 MB', bytes: 8 * 1024 * 1024},
  {label: '32 MB', bytes: 32 * 1024 * 1024}
]

export function Composer({target, targetName, onSendText, onSendBinary}: Props) {
  const [text, setText] = useState('')
  const [file, setFile] = useState<File | null>(null)
  const [randomSize, setRandomSize] = useState(RANDOM_SIZES[1].bytes)
  const [sending, setSending] = useState(false)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const sendText = () => {
    const trimmed = text.trim()
    if (!trimmed) return
    onSendText(trimmed, target)
    setText('')
  }

  const sendFile = async () => {
    if (!file || sending) return
    setSending(true)
    try {
      const buf = new Uint8Array(await file.arrayBuffer())
      await onSendBinary(
        buf,
        file.name,
        file.type || 'application/octet-stream',
        target
      )
    } finally {
      setSending(false)
    }
  }

  const sendRandom = async () => {
    if (sending) return
    setSending(true)
    try {
      const bytes = randomBytes(randomSize)
      const name = `random-${formatBytes(randomSize).replace(' ', '')}.bin`
      await onSendBinary(bytes, name, 'application/octet-stream', target)
    } finally {
      setSending(false)
    }
  }

  return (
    <div className="panel">
      <h2 className="panel-title">
        Compose <span className="to-badge">→ {targetName}</span>
      </h2>

      <div className="composer-row">
        <input
          className="text-input"
          placeholder={`Message ${targetName}…`}
          value={text}
          onChange={e => setText(e.target.value)}
          onKeyDown={e => {
            if (e.key === 'Enter') sendText()
          }}
        />
        <button className="btn primary" onClick={sendText} disabled={!text.trim()}>
          Send text
        </button>
      </div>

      <div className="divider">
        <span>binary payload</span>
      </div>

      <div className="composer-row">
        <input
          ref={fileInputRef}
          type="file"
          className="file-input"
          onChange={e => setFile(e.target.files?.[0] ?? null)}
        />
        <button
          className="btn"
          onClick={sendFile}
          disabled={!file || sending}
        >
          {sending ? 'Sending…' : 'Send file'}
        </button>
      </div>
      {file && (
        <p className="hint">
          Selected: <b>{file.name}</b> ({formatBytes(file.size)})
        </p>
      )}

      <div className="composer-row">
        <label className="hint" style={{margin: 0}}>
          …or generate a random payload:
        </label>
        <select
          className="select"
          value={randomSize}
          onChange={e => setRandomSize(Number(e.target.value))}
        >
          {RANDOM_SIZES.map(s => (
            <option key={s.bytes} value={s.bytes}>
              {s.label}
            </option>
          ))}
        </select>
        <button className="btn" onClick={sendRandom} disabled={sending}>
          {sending ? 'Sending…' : 'Send random'}
        </button>
      </div>

      <p className="hint subtle">
        Large payloads are automatically chunked & throttled by Trystero and sent
        directly peer-to-peer (end-to-end encrypted). A SHA-256 is computed on
        both ends so you can confirm the bytes arrived intact.
      </p>
    </div>
  )
}
