import { useState } from 'react';
import { useUserAvatar } from '../hooks/useUserAvatar';
import type { Message } from '../types';
import { getDisplayText, getImageUrls, getThinking } from '../utils/message';
import { getMessageSaveActions } from '../utils/messageSave';
import { renderMarkdown } from '../utils/markdown';
import { filterText } from '../utils/wordFilter';
import { formatChatTime, shouldShowTimestamp } from '../utils/time';
import { TKMindAvatar } from './TKMindAvatar';
import { UserAvatar } from './UserAvatar';

function CopyIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <rect x="8" y="8" width="12" height="12" rx="2" stroke="currentColor" strokeWidth="1.8" />
      <path
        d="M6 16H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinecap="round"
      />
    </svg>
  );
}

function CheckIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <path
        d="M5 12.5l4.5 4.5L19 7.5"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

function ToolBadge({ message }: { message: Message }) {
  const tools = message.content.filter((c) => c.type === 'toolRequest' || c.type === 'toolResponse');
  if (tools.length === 0) return null;
  return (
    <div className="tool-badges">
      {tools.map((tool, i) => (
        <span key={`${message.id}-${i}`} className="tool-badge">
          {tool.type === 'toolRequest'
            ? `🔧 ${tool.toolCall.functionName}`
            : `✓ 工具完成`}
        </span>
      ))}
    </div>
  );
}

function CopyButton({ text }: { text: string }) {
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    if (!text) return;
    try {
      await navigator.clipboard.writeText(text);
      setCopied(true);
      window.setTimeout(() => setCopied(false), 1500);
    } catch {
      const textarea = document.createElement('textarea');
      textarea.value = text;
      textarea.style.position = 'fixed';
      textarea.style.opacity = '0';
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand('copy');
      document.body.removeChild(textarea);
      setCopied(true);
      window.setTimeout(() => setCopied(false), 1500);
    }
  };

  return (
    <button
      type="button"
      className={`msg-copy${copied ? ' msg-copy-done' : ''}`}
      aria-label={copied ? '已复制' : '复制'}
      title={copied ? '已复制' : '复制'}
      onClick={() => void handleCopy()}
    >
      {copied ? <CheckIcon /> : <CopyIcon />}
    </button>
  );
}

function TimeDivider({ timestamp }: { timestamp: number }) {
  return (
    <div className="msg-time-divider">
      <span>{formatChatTime(timestamp)}</span>
    </div>
  );
}

function ChevronIcon({ open }: { open: boolean }) {
  return (
    <svg
      width="16"
      height="16"
      viewBox="0 0 24 24"
      fill="none"
      aria-hidden="true"
      className={open ? 'msg-actions-chevron is-open' : 'msg-actions-chevron'}
    >
      <path
        d="M9 6l6 6-6 6"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />
    </svg>
  );
}

function MessageRow({
  message,
  avatarUrl,
  onAvatarClick,
  onSaveAsPage,
  saveDisabled,
  publishUserId,
  publishUsername,
  compact = false,
}: {
  message: Message;
  avatarUrl: string | null;
  onAvatarClick?: () => void;
  onSaveAsPage?: (message: Message) => void;
  saveDisabled?: boolean;
  publishUserId?: string;
  publishUsername?: string;
  compact?: boolean;
}) {
  const [actionsOpen, setActionsOpen] = useState(false);
  const rawText = getDisplayText(message);
  const text = filterText(rawText);
  const saveActions = getMessageSaveActions(text, { userId: publishUserId, username: publishUsername });
  const thinking = getThinking(message);
  const isUser = message.role === 'user';
  const imageUrls = getImageUrls(message);
  const copyText = [thinking ? `【思考】\n${thinking}` : '', text].filter(Boolean).join('\n\n');

  if (!text && !thinking && message.role === 'assistant') {
    return (
      <div className={`msg-row msg-row-assistant`}>
        <TKMindAvatar />
        <div className="msg-content">
          <ToolBadge message={message} />
        </div>
      </div>
    );
  }

  const hasAssistantActions =
    !isUser && Boolean(message.id && onSaveAsPage && copyText);
  const showActionsToggle = compact && Boolean(copyText);

  return (
    <div className={`msg-row ${isUser ? 'msg-row-user' : 'msg-row-assistant'}`}>
      {!isUser && <TKMindAvatar />}
      <div className="msg-content">
        <div className={`msg-bubble-wrap${compact ? ' msg-bubble-wrap-compact' : ''}`}>
          <div className={compact ? 'msg-bubble-row' : undefined}>
            <div className={`msg-bubble ${isUser ? 'msg-bubble-user' : 'msg-bubble-assistant'}`}>
              {thinking && (
                <details className="thinking">
                  <summary>思考中…</summary>
                  <pre>{thinking}</pre>
                </details>
              )}
              {imageUrls.length > 0 && (
                <div className="msg-image-gallery">
                  {imageUrls.map((imageUrl, index) => (
                    <a
                      key={`${imageUrl}-${index}`}
                      href={imageUrl}
                      target="_blank"
                      rel="noreferrer"
                      className="msg-image-link"
                    >
                      <img
                        src={imageUrl}
                        alt={`图片 ${index + 1}`}
                        className="msg-image-thumb"
                        loading="lazy"
                      />
                    </a>
                  ))}
                </div>
              )}
              {text && (
                <div
                  className="bubble-text"
                  dangerouslySetInnerHTML={{ __html: renderMarkdown(text) }}
                />
              )}
              <ToolBadge message={message} />
            </div>
            {showActionsToggle && (
              <button
                type="button"
                className={`msg-actions-toggle${actionsOpen ? ' is-open' : ''}`}
                aria-label={actionsOpen ? '收起操作' : '展开操作'}
                aria-expanded={actionsOpen}
                onClick={() => setActionsOpen((current) => !current)}
              >
                <ChevronIcon open={actionsOpen} />
              </button>
            )}
          </div>
          {copyText && !compact && (
            <div className="msg-actions">
              <CopyButton text={copyText} />
              {hasAssistantActions && (
                <>
                  <button
                    type="button"
                    className="msg-save-page"
                    disabled={saveDisabled}
                    onClick={() => onSaveAsPage!(message)}
                  >
                    {saveActions.kind === 'page' ? '保存页面' : '保存为文章'}
                  </button>
                  {saveActions.previewUrl && (
                    <a
                      className="msg-open-preview"
                      href={saveActions.previewUrl}
                      target="_blank"
                      rel="noreferrer"
                    >
                      打开预览
                    </a>
                  )}
                </>
              )}
            </div>
          )}
          {copyText && compact && actionsOpen && (
            <div className="msg-actions msg-actions-compact">
              <CopyButton text={copyText} />
              {hasAssistantActions && (
                <>
                  <button
                    type="button"
                    className="msg-save-page"
                    disabled={saveDisabled}
                    onClick={() => onSaveAsPage!(message)}
                  >
                    {saveActions.kind === 'page' ? '保存页面' : '保存为文章'}
                  </button>
                  {saveActions.previewUrl && (
                    <a
                      className="msg-open-preview"
                      href={saveActions.previewUrl}
                      target="_blank"
                      rel="noreferrer"
                    >
                      打开预览
                    </a>
                  )}
                </>
              )}
            </div>
          )}
        </div>
      </div>
      {isUser && (
        <UserAvatar
          avatarUrl={avatarUrl}
          className="msg-avatar msg-avatar-user"
          onClick={onAvatarClick}
          title={onAvatarClick ? '点击更换头像' : undefined}
        />
      )}
    </div>
  );
}

export function MessageList({
  messages,
  streaming,
  onAvatarClick,
  onSaveAsPage,
  publishUserId,
  publishUsername,
  compact = false,
}: {
  messages: Message[];
  streaming: boolean;
  onAvatarClick?: () => void;
  onSaveAsPage?: (message: Message) => void;
  publishUserId?: string;
  publishUsername?: string;
  compact?: boolean;
}) {
  const { avatarUrl } = useUserAvatar();

  return (
    <div className="message-list">
      {messages.length === 0 && (
        <div className={`empty-state${compact ? ' empty-state-compact' : ''}`}>
          <TKMindAvatar />
          <h2>TKMind</h2>
          <p>{compact ? '继续和空间里的 Agent 对话' : '发送消息即可在本机执行 Agent 任务'}</p>
        </div>
      )}
      {messages.map((message, index) => {
        const prev = index > 0 ? messages[index - 1] : undefined;
        const showTime = shouldShowTimestamp(message.created, prev?.created);
        return (
          <div key={message.id ?? `msg-${index}`} className="msg-block">
            {showTime && <TimeDivider timestamp={message.created} />}
            <MessageRow
              message={message}
              avatarUrl={avatarUrl}
              onAvatarClick={onAvatarClick}
              onSaveAsPage={onSaveAsPage}
              saveDisabled={streaming}
              publishUserId={publishUserId}
              publishUsername={publishUsername}
              compact={compact}
            />
          </div>
        );
      })}
      {streaming && (
        <div className="msg-row msg-row-assistant">
          <TKMindAvatar />
          <div className="msg-content">
            <div className="msg-bubble msg-bubble-assistant msg-typing">
              <span className="typing-dots">
                <span />
                <span />
                <span />
              </span>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
