import React, { useState, useRef, useEffect } from 'react';
import { parseMarkdown } from '../utils/markdown';

const CODE_EXTENSIONS = ['.js', '.jsx', '.ts', '.tsx', '.py', '.html', '.css', '.json', '.md', '.txt', '.sh', '.yml', '.yaml', '.xml', '.sql', '.rb', '.go', '.rs', '.c', '.cpp', '.h', '.java'];

function formatFileSize(bytes) {
  if (!bytes) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB'];
  let i = 0;
  let size = bytes;
  while (size >= 1024 && i < units.length - 1) { size /= 1024; i++; }
  return `${size.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
}

function formatTime(dateStr) {
  const d = new Date(dateStr);
  const now = new Date();
  const isToday = d.toDateString() === now.toDateString();
  const yesterday = new Date(now); yesterday.setDate(yesterday.getDate() - 1);
  const isYesterday = d.toDateString() === yesterday.toDateString();
  const time = d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
  if (isToday) return `Today at ${time}`;
  if (isYesterday) return `Yesterday at ${time}`;
  return `${d.toLocaleDateString()} ${time}`;
}

function isCodeFile(fileName) {
  if (!fileName) return false;
  return CODE_EXTENSIONS.some(ext => fileName.toLowerCase().endsWith(ext));
}

function FilePreview({ message }) {
  const { file_url, file_name, file_size, file_type } = message;
  const [codeContent, setCodeContent] = useState(null);
  const [imageOpen, setImageOpen] = useState(false);

  useEffect(() => {
    if (isCodeFile(file_name)) {
      fetch(file_url).then(r => r.text()).then(text => {
        const lines = text.split('\n').slice(0, 20);
        setCodeContent(lines.join('\n') + (text.split('\n').length > 20 ? '\n...' : ''));
      }).catch(() => {});
    }
  }, [file_url, file_name]);

  // Image preview
  if (file_type?.startsWith('image/')) {
    return (
      <>
        <img
          src={file_url}
          alt={file_name}
          className="max-w-lg rounded-lg mt-2 cursor-pointer hover:opacity-90 transition-opacity"
          onClick={() => setImageOpen(true)}
        />
        {imageOpen && (
          <div className="fixed inset-0 bg-black/80 z-50 flex items-center justify-center cursor-pointer" onClick={() => setImageOpen(false)}>
            <img src={file_url} alt={file_name} className="max-w-[90vw] max-h-[90vh] object-contain rounded" />
          </div>
        )}
      </>
    );
  }

  // Code file preview
  if (isCodeFile(file_name) && codeContent !== null) {
    return (
      <div className="mt-2 max-w-lg">
        <div className="flex items-center justify-between bg-[#1e1e22] rounded-t-lg px-3 py-1.5 text-xs text-gray-400 border border-[#3a3a42] border-b-0">
          <span>{file_name}</span>
          <a href={file_url} download className="text-[#FFD700] hover:underline">Download</a>
        </div>
        <pre className="bg-[#111114] rounded-b-lg px-3 py-2 text-xs text-gray-300 overflow-x-auto border border-[#3a3a42] border-t-0">
          <code>{codeContent}</code>
        </pre>
      </div>
    );
  }

  // Generic file card
  return (
    <div className="mt-2 flex items-center gap-3 bg-[#1e1e22] border border-[#3a3a42] rounded-lg px-4 py-3 max-w-sm">
      <svg className="w-8 h-8 text-[#FFD700] flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
      </svg>
      <div className="min-w-0 flex-1">
        <a href={file_url} download className="text-[#FFD700] hover:underline text-sm font-medium truncate block">{file_name}</a>
        <span className="text-gray-500 text-xs">{formatFileSize(file_size)}</span>
      </div>
    </div>
  );
}

function ReactionBar({ reactions, userId, token, messageId }) {
  if (!reactions || reactions.length === 0) return null;

  const toggleReaction = async (emoji) => {
    const reaction = reactions.find(r => r.emoji === emoji);
    const users = reaction?.users ? reaction.users.split(',') : [];
    const hasReacted = users.includes(String(userId));

    try {
      if (hasReacted) {
        await fetch(`/api/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`, {
          method: 'DELETE',
          headers: { 'Authorization': `Bearer ${token}` },
        });
      } else {
        await fetch(`/api/messages/${messageId}/reactions`, {
          method: 'POST',
          headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
          body: JSON.stringify({ emoji }),
        });
      }
    } catch (err) { console.error(err); }
  };

  return (
    <div className="flex flex-wrap gap-1 mt-1">
      {reactions.map((r, i) => {
        const users = r.users ? r.users.split(',') : [];
        const count = users.length;
        const hasReacted = users.includes(String(userId));
        return (
          <button
            key={`${r.emoji}-${i}`}
            onClick={() => toggleReaction(r.emoji)}
            className={`flex items-center gap-1 px-2 py-0.5 rounded-full text-xs transition-colors duration-200 ${
              hasReacted
                ? 'bg-[#FFD700]/20 border border-[#FFD700]/60 text-gray-100'
                : 'bg-[#25252a] border border-transparent text-gray-400 hover:bg-[#2f2f35]'
            }`}
          >
            <span>{r.emoji}</span>
            <span>{count}</span>
          </button>
        );
      })}
    </div>
  );
}

const EMOJI_QUICK = ['👍', '❤️', '😂', '🎉', '🔥', '👀'];

export default function Message({ message, user, token, onReply, onEdit, onDelete }) {
  const [hovered, setHovered] = useState(false);
  const [editing, setEditing] = useState(false);
  const [editText, setEditText] = useState(message.content || '');
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const editRef = useRef(null);

  const isOwn = user && String(message.user_id) === String(user.id);

  useEffect(() => {
    if (editing && editRef.current) {
      editRef.current.focus();
      editRef.current.selectionStart = editRef.current.value.length;
    }
  }, [editing]);

  const saveEdit = () => {
    const trimmed = editText.trim();
    if (trimmed && trimmed !== message.content) {
      onEdit(message.id, trimmed);
    }
    setEditing(false);
  };

  const handleEditKeyDown = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); saveEdit(); }
    if (e.key === 'Escape') { setEditing(false); setEditText(message.content || ''); }
  };

  const addReaction = async (emoji) => {
    setShowEmojiPicker(false);
    try {
      await fetch(`/api/messages/${message.id}/reactions`, {
        method: 'POST',
        headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
        body: JSON.stringify({ emoji }),
      });
    } catch (err) { console.error(err); }
  };

  return (
    <div
      className="relative group flex gap-3 py-1 px-2 -mx-2 rounded hover:bg-[#1e1e22]/50 transition-colors duration-200"
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => { setHovered(false); setShowEmojiPicker(false); }}
    >
      {/* Avatar */}
      <div className="flex-shrink-0 pt-0.5">
        {message.avatar ? (
          <img src={message.avatar} alt="" className="w-8 h-8 rounded-full object-cover" />
        ) : (
          <div className="w-8 h-8 rounded-full bg-[#3a3a42] flex items-center justify-center text-xs font-bold text-gray-300">
            {(message.username || '?')[0].toUpperCase()}
          </div>
        )}
      </div>

      {/* Body */}
      <div className="flex-1 min-w-0">
        {/* Reply reference */}
        {message.reply_to && (
          <div className="flex items-center gap-1 text-xs text-gray-500 mb-0.5">
            <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" /></svg>
            <span className="text-gray-400">replied to a message</span>
          </div>
        )}

        {/* Header */}
        <div className="flex items-baseline gap-2">
          <span className="font-semibold text-gray-100 text-sm">{message.username || 'Unknown'}</span>
          <span className="text-xs text-gray-500">{formatTime(message.created_at)}</span>
          {message.edited ? <span className="text-xs text-gray-600">(edited)</span> : null}
        </div>

        {/* Content */}
        {editing ? (
          <div className="mt-1">
            <textarea
              ref={editRef}
              value={editText}
              onChange={(e) => setEditText(e.target.value)}
              onKeyDown={handleEditKeyDown}
              className="w-full bg-[#25252a] text-gray-100 text-sm rounded px-3 py-2 outline-none resize-none border border-[#3a3a42] focus:border-[#FFD700]/50"
              rows={2}
            />
            <div className="text-xs text-gray-500 mt-1">
              Press <kbd className="px-1 bg-[#25252a] rounded">Enter</kbd> to save · <kbd className="px-1 bg-[#25252a] rounded">Esc</kbd> to cancel
            </div>
          </div>
        ) : message.content ? (
          <div
            className="text-sm text-gray-300 leading-relaxed break-words message-content"
            dangerouslySetInnerHTML={{ __html: parseMarkdown(message.content) }}
          />
        ) : null}

        {/* File attachment */}
        {message.file_url && <FilePreview message={message} />}

        {/* Reactions */}
        <ReactionBar
          reactions={message.reactions}
          userId={user?.id}
          token={token}
          messageId={message.id}
        />
      </div>

      {/* Hover actions */}
      {hovered && !editing && (
        <div className="absolute -top-3 right-2 flex items-center bg-[#1e1e22] border border-[#3a3a42] rounded-lg shadow-lg overflow-hidden">
          <div className="relative">
            <button
              onClick={() => setShowEmojiPicker(!showEmojiPicker)}
              className="px-2 py-1 text-gray-400 hover:text-[#FFD700] hover:bg-[#25252a] transition-colors duration-200 text-sm"
              title="Add reaction"
            >
              😀
            </button>
            {showEmojiPicker && (
              <div className="absolute top-full right-0 mt-1 bg-[#1e1e22] border border-[#3a3a42] rounded-lg p-2 flex gap-1 shadow-xl z-10">
                {EMOJI_QUICK.map(e => (
                  <button
                    key={e}
                    onClick={() => addReaction(e)}
                    className="hover:bg-[#25252a] rounded px-1.5 py-0.5 transition-colors duration-200"
                  >
                    {e}
                  </button>
                ))}
              </div>
            )}
          </div>
          <button
            onClick={() => onReply(message)}
            className="px-2 py-1 text-gray-400 hover:text-[#FFD700] hover:bg-[#25252a] transition-colors duration-200"
            title="Reply"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" /></svg>
          </button>
          {isOwn && (
            <>
              <button
                onClick={() => { setEditing(true); setEditText(message.content || ''); }}
                className="px-2 py-1 text-gray-400 hover:text-[#FFD700] hover:bg-[#25252a] transition-colors duration-200"
                title="Edit"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" /></svg>
              </button>
              <button
                onClick={() => { if (window.confirm('Delete this message?')) onDelete(message.id); }}
                className="px-2 py-1 text-gray-400 hover:text-red-400 hover:bg-[#25252a] transition-colors duration-200"
                title="Delete"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" /></svg>
              </button>
            </>
          )}
        </div>
      )}
    </div>
  );
}
