'use client';

import { useEffect, useRef, useState } from 'react';
import { ImagePlus, Mic, Paperclip, Send, Square, X } from 'lucide-react';
import type { Attachment } from '../../lib/types';

interface InputBarProps {
  onSend: (text: string, attachments?: Attachment[]) => Promise<void>;
  disabled?: boolean;
  streaming?: boolean;
  onCancel?: () => void;
  initialText?: string;
  examplePrompts?: string[];
}

export function InputBar({
  onSend,
  disabled,
  streaming,
  onCancel,
  initialText = '',
  examplePrompts = [],
}: InputBarProps) {
  const [text, setText] = useState(initialText);
  const [attachments, setAttachments] = useState<Attachment[]>([]);
  const [dragActive, setDragActive] = useState(false);
  const [voiceLoading, setVoiceLoading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const imageInputRef = useRef<HTMLInputElement | null>(null);
  const audioInputRef = useRef<HTMLInputElement | null>(null);

  useEffect(() => {
    setText(initialText);
  }, [initialText]);

  const handleSend = async () => {
    const trimmed = text.trim();
    if ((!trimmed && attachments.length === 0) || disabled || streaming) return;
    await onSend(trimmed, attachments);
    setText('');
    setAttachments([]);
  };

  const readFiles = async (files: FileList | null, forceType?: 'image' | 'file'): Promise<void> => {
    if (!files || files.length === 0) return;

    const next: Attachment[] = [];
    for (const file of Array.from(files)) {
      if (file.size > 10 * 1024 * 1024) continue;

      const isImage = forceType === 'image' || file.type.startsWith('image/');
      const data = await new Promise<string>((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(String(reader.result || ''));
        reader.onerror = () => reject(reader.error);
        if (isImage) {
          reader.readAsDataURL(file);
        } else {
          reader.readAsText(file);
        }
      });

      next.push({
        type: isImage ? 'image' : 'file',
        name: file.name,
        data,
        mimeType: file.type,
        size: file.size,
      });
    }

    setAttachments(prev => [...prev, ...next]);
  };

  const transcribeAudio = async (file: File): Promise<void> => {
    setVoiceLoading(true);
    try {
      const formData = new FormData();
      formData.append('audio', file);
      const res = await fetch('/api/whisper/transcribe', {
        method: 'POST',
        body: formData,
      });

      const data = (await res.json()) as { text?: string; error?: string };
      if (!res.ok) {
        setText(prev => {
          const next = data.error || 'Voice transcription failed';
          return prev ? `${prev}\n${next}` : next;
        });
        return;
      }

      const transcribed = (data.text || '').trim();
      if (transcribed) {
        setText(prev => (prev ? `${prev}\n${transcribed}` : transcribed));
      }
    } catch {
      setText(prev =>
        prev ? `${prev}\nVoice transcription failed` : 'Voice transcription failed'
      );
    } finally {
      setVoiceLoading(false);
    }
  };

  return (
    <div
      className="border-t border-white/10 bg-[var(--bg-elevated)] p-3"
      onDragOver={e => {
        e.preventDefault();
        setDragActive(true);
      }}
      onDragLeave={() => setDragActive(false)}
      onDrop={e => {
        e.preventDefault();
        setDragActive(false);
        void readFiles(e.dataTransfer.files);
      }}
    >
      {dragActive && (
        <div className="mb-2 rounded border border-dashed border-[var(--accent-secondary)] px-3 py-2 text-xs text-[var(--accent-secondary)]">
          Drop files to attach
        </div>
      )}

      {examplePrompts.length > 0 && !text.trim() && (
        <div className="mb-2 flex flex-wrap gap-1">
          {examplePrompts.slice(0, 4).map(prompt => (
            <button
              key={prompt}
              type="button"
              onClick={() => setText(prompt)}
              className="rounded border border-white/10 bg-[var(--surface-muted)] px-2 py-1 text-xs text-[var(--text-secondary)] hover:text-[var(--text-primary)]"
            >
              {prompt}
            </button>
          ))}
        </div>
      )}

      {attachments.length > 0 && (
        <div className="mb-2 flex flex-wrap gap-1">
          {attachments.map((att, idx) => (
            <span
              key={`${att.name}-${idx}`}
              className="inline-flex items-center gap-1 rounded border border-white/10 bg-[var(--surface-muted)] px-2 py-1 text-[11px] text-[var(--text-secondary)]"
              title={att.name}
            >
              {att.type === 'image' ? '🖼' : '📎'}
              <span className="max-w-[160px] truncate">{att.name}</span>
              <button
                type="button"
                onClick={() => setAttachments(prev => prev.filter((_, i) => i !== idx))}
                className="text-[var(--text-tertiary)] hover:text-[var(--text-primary)]"
              >
                <X size={12} />
              </button>
            </span>
          ))}
        </div>
      )}

      <div className="flex items-end gap-2">
        <div className="flex flex-col gap-1">
          <button
            type="button"
            onClick={() => fileInputRef.current?.click()}
            className="inline-flex h-8 w-8 items-center justify-center rounded border border-white/10 bg-[var(--surface-card)] text-[var(--text-secondary)] hover:text-[var(--text-primary)]"
            title="Attach file"
          >
            <Paperclip size={14} />
          </button>
          <button
            type="button"
            onClick={() => imageInputRef.current?.click()}
            className="inline-flex h-8 w-8 items-center justify-center rounded border border-white/10 bg-[var(--surface-card)] text-[var(--text-secondary)] hover:text-[var(--text-primary)]"
            title="Attach image"
          >
            <ImagePlus size={14} />
          </button>
          <button
            type="button"
            onClick={() => audioInputRef.current?.click()}
            className="inline-flex h-8 w-8 items-center justify-center rounded border border-white/10 bg-[var(--surface-card)] text-[var(--text-secondary)] hover:text-[var(--text-primary)]"
            title="Voice input"
            disabled={voiceLoading}
          >
            <Mic size={14} className={voiceLoading ? 'animate-pulse' : ''} />
          </button>
        </div>

        <input
          ref={fileInputRef}
          type="file"
          multiple
          className="hidden"
          onChange={e => void readFiles(e.target.files, 'file')}
        />
        <input
          ref={imageInputRef}
          type="file"
          multiple
          accept="image/*"
          className="hidden"
          onChange={e => void readFiles(e.target.files, 'image')}
        />
        <input
          ref={audioInputRef}
          type="file"
          accept="audio/*"
          className="hidden"
          onChange={e => {
            const file = e.target.files?.[0];
            if (file) {
              void transcribeAudio(file);
            }
            e.currentTarget.value = '';
          }}
        />

        <textarea
          value={text}
          onChange={e => setText(e.target.value)}
          onKeyDown={e => {
            if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
              e.preventDefault();
              void handleSend();
            }
          }}
          disabled={disabled || streaming}
          rows={2}
          placeholder="Message... (Cmd+Enter to send)"
          className="min-h-[56px] flex-1 resize-y rounded-md border border-white/10 bg-[var(--surface-card)] px-3 py-2 text-sm text-[var(--text-primary)] outline-none placeholder:text-[var(--text-tertiary)]"
        />
        {streaming ? (
          <button
            type="button"
            onClick={onCancel}
            className="inline-flex h-10 w-10 items-center justify-center rounded-md bg-[var(--danger)] text-white hover:opacity-90"
            title="Stop"
          >
            <Square size={16} />
          </button>
        ) : (
          <button
            type="button"
            onClick={() => void handleSend()}
            disabled={disabled || !text.trim()}
            className="inline-flex h-10 w-10 items-center justify-center rounded-md bg-[var(--accent-primary)] text-white disabled:cursor-not-allowed disabled:opacity-50"
            title="Send"
          >
            <Send size={16} />
          </button>
        )}
      </div>
    </div>
  );
}
