import { useState, useRef, useEffect } from 'react';
import Avatar from './Avatar.jsx';
import UserProfilePopup from './UserProfilePopup.jsx';
import ImageLightbox from './ImageLightbox.jsx';
import Picker from '@emoji-mart/react';
import data from '@emoji-mart/data';
import './Message.css';

const QUICK_EMOJIS = ['👍', '❤️', '😂', '😮', '😢', '🙏'];

function formatMsgContent(content) {
  if (!content) return '';
  return content.replace(/@\[([^\]]+)\]\(\d+\)/g, (_, name) => `<span class="mention">@${name}</span>`);
}

export default function Message({ message: msg, prevMessage, currentUser, onReply, onDelete, onReact }) {
  const [showActions, setShowActions] = useState(false);
  const [showEmojiPicker, setShowEmojiPicker] = useState(false);
  const wrapperRef = useRef(null);
  const pickerRef = useRef(null);
  const avatarRef = useRef(null);
  const [showProfile, setShowProfile] = useState(false);
  const [lightboxSrc, setLightboxSrc] = useState(null);
  const [pickerOpensDown, setPickerOpensDown] = useState(false);

  const isOwn = msg.user_id === currentUser.id;
  const isDeleted = !!msg.is_deleted;

  // Deleted messages are filtered out by ChatWindow, but guard here too
  if (isDeleted) return null;

  const canDelete = (
    msg.user_id === currentUser.id ||
    currentUser.role === 'admin' ||
    (msg.group_owner_id === currentUser.id)
  );

  const prevSameUser = prevMessage && prevMessage.user_id === msg.user_id &&
    new Date(msg.created_at) - new Date(prevMessage.created_at) < 60000;

  const showDateSep = !prevMessage ||
    new Date(msg.created_at).toDateString() !== new Date(prevMessage.created_at).toDateString();

  const reactionMap = {};
  for (const r of (msg.reactions || [])) {
    if (!reactionMap[r.emoji]) reactionMap[r.emoji] = { count: 0, users: [], hasMe: false };
    reactionMap[r.emoji].count++;
    reactionMap[r.emoji].users.push(r.user_name);
    if (r.user_id === currentUser.id) reactionMap[r.emoji].hasMe = true;
  }

  // Close emoji picker when clicking outside
  useEffect(() => {
    if (!showEmojiPicker) return;
    const handler = (e) => {
      if (pickerRef.current && !pickerRef.current.contains(e.target)) {
        setShowEmojiPicker(false);
      }
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [showEmojiPicker]);

  const handleReact = (emoji) => {
    onReact(msg.id, emoji);
    setShowEmojiPicker(false);
  };

  const handleTogglePicker = () => {
    if (!showEmojiPicker && wrapperRef.current) {
      // If the message is in the top 400px of viewport, open picker downward
      const rect = wrapperRef.current.getBoundingClientRect();
      setPickerOpensDown(rect.top < 400);
    }
    setShowEmojiPicker(p => !p);
  };

  const msgUser = {
    id: msg.user_id,
    name: msg.user_name,
    display_name: msg.user_display_name,
    avatar: msg.user_avatar,
    role: msg.user_role,
    status: msg.user_status,
    hide_admin_tag: msg.user_hide_admin_tag,
    about_me: msg.user_about_me,
  };

  return (
    <>
      {showDateSep && (
        <div className="date-separator">
          <span>{formatDate(msg.created_at)}</span>
        </div>
      )}

      <div
        ref={wrapperRef}
        className={`message-wrapper ${isOwn ? 'own' : 'other'} ${prevSameUser ? 'grouped' : ''}`}
        onMouseEnter={() => setShowActions(true)}
        onMouseLeave={() => { if (!showEmojiPicker) setShowActions(false); }}
      >
        {!isOwn && !prevSameUser && (
          <div ref={avatarRef} style={{ cursor: 'pointer' }} onClick={() => setShowProfile(p => !p)}>
            <Avatar user={msgUser} size="sm" className="msg-avatar" />
          </div>
        )}
        {!isOwn && prevSameUser && <div style={{ width: 32, flexShrink: 0 }} />}

        <div className="message-body">
          {!isOwn && !prevSameUser && (
            <div className="msg-name">
              {msgUser.display_name || msgUser.name}
              {msgUser.role === 'admin' && !msgUser.hide_admin_tag && <span className="role-badge role-admin" style={{ marginLeft: 6 }}>Admin</span>}
              {msgUser.status !== 'active' && <span style={{ marginLeft: 6, fontSize: 11, color: 'var(--text-tertiary)' }}>(inactive)</span>}
            </div>
          )}

          {/* Reply preview */}
          {msg.reply_to_id && (
            <div className="reply-preview">
              <div className="reply-bar" />
              <div>
                <div className="reply-name">{msg.reply_user_display_name || msg.reply_user_name}</div>
                <div className="reply-text">
                  {msg.reply_is_deleted ? <em style={{ color: 'var(--text-tertiary)' }}>Deleted message</em>
                    : msg.reply_image_url ? '📷 Image'
                    : msg.reply_content}
                </div>
              </div>
            </div>
          )}

          {/* Bubble + actions together so actions hover above bubble */}
          <div className="msg-bubble-wrap">
            <div className="msg-bubble-with-actions">
              {/* Actions toolbar — floats above the bubble, aligned to correct side */}
              {!isDeleted && (showActions || showEmojiPicker) && (
                <div className={`msg-actions ${isOwn ? 'actions-left' : 'actions-right'}`}>
                  {QUICK_EMOJIS.map(e => (
                    <button key={e} className="quick-emoji" onClick={() => handleReact(e)} title={e}>{e}</button>
                  ))}
                  <button className="btn-icon action-btn" onClick={handleTogglePicker} title="More reactions">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
                  </button>
                  <button className="btn-icon action-btn" onClick={() => onReply(msg)} title="Reply">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg>
                  </button>
                  {canDelete && (
                    <button className="btn-icon action-btn danger" onClick={() => onDelete(msg.id)} title="Delete">
                      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/></svg>
                    </button>
                  )}

                  {/* Emoji picker anchored to the toolbar */}
                  {showEmojiPicker && (
                    <div
                      className={`emoji-picker-wrap ${isOwn ? 'picker-left' : 'picker-right'} ${pickerOpensDown ? 'picker-down' : ''}`}
                      ref={pickerRef}
                      onMouseDown={e => e.stopPropagation()}
                    >
                      <Picker data={data} onEmojiSelect={(e) => handleReact(e.native)} theme="light" previewPosition="none" skinTonePosition="none" />
                    </div>
                  )}
                </div>
              )}

              <div className={`msg-bubble ${isOwn ? 'out' : 'in'}`}>
                {msg.image_url && (
                  <img
                    src={msg.image_url}
                    alt="attachment"
                    className="msg-image"
                    onClick={() => setLightboxSrc(msg.image_url)}
                  />
                )}
                {msg.content && (
                  <p
                    className="msg-text"
                    dangerouslySetInnerHTML={{ __html: formatMsgContent(msg.content) }}
                  />
                )}
                {msg.link_preview && <LinkPreview data={msg.link_preview} />}
              </div>
            </div>

            <span className="msg-time">{formatTime(msg.created_at)}</span>
          </div>

          {Object.keys(reactionMap).length > 0 && (
            <div className="reactions">
              {Object.entries(reactionMap).map(([emoji, { count, users, hasMe }]) => (
                <button
                  key={emoji}
                  className={`reaction-btn ${hasMe ? 'active' : ''}`}
                  onClick={() => onReact(msg.id, emoji)}
                  title={hasMe ? `${users.join(', ')} · Click to remove` : users.join(', ')}
                >
                  {emoji} <span className="reaction-count">{count}</span>
                  {hasMe && <span className="reaction-remove" title="Remove reaction">×</span>}
                </button>
              ))}
            </div>
          )}
        </div>
      </div>
      {showProfile && (
        <UserProfilePopup
          user={msgUser}
          anchorEl={avatarRef.current}
          onClose={() => setShowProfile(false)}
        />
      )}
      {lightboxSrc && (
        <ImageLightbox src={lightboxSrc} onClose={() => setLightboxSrc(null)} />
      )}
    </>
  );
}

function LinkPreview({ data: raw }) {
  let d;
  try { d = typeof raw === 'string' ? JSON.parse(raw) : raw; } catch { return null; }
  if (!d?.title) return null;

  return (
    <a href={d.url} target="_blank" rel="noopener noreferrer" className="link-preview">
      {d.image && <img src={d.image} alt="" className="link-preview-img" onError={e => e.target.style.display = 'none'} />}
      <div className="link-preview-content">
        {d.siteName && <span className="link-site">{d.siteName}</span>}
        <span className="link-title">{d.title}</span>
        {d.description && <span className="link-desc">{d.description}</span>}
      </div>
    </a>
  );
}

function formatTime(dateStr) {
  return new Date(dateStr).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
}

function formatDate(dateStr) {
  const d = new Date(dateStr);
  const now = new Date();
  if (d.toDateString() === now.toDateString()) return 'Today';
  const yest = new Date(now); yest.setDate(yest.getDate() - 1);
  if (d.toDateString() === yest.toDateString()) return 'Yesterday';
  return d.toLocaleDateString([], { weekday: 'long', month: 'long', day: 'numeric' });
}
