'use client';

import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { Box } from '@tidbcloud/uikit';
import { useTranslation } from '@/lib/i18n';

interface MarkdownContentProps {
  content: string;
  isUser?: boolean;
}

const CODE_FONT = "source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace";

function getPlainText(children: React.ReactNode): string {
  return React.Children.toArray(children)
    .map(child => {
      if (typeof child === 'string' || typeof child === 'number') return String(child);
      if (React.isValidElement<{ children?: React.ReactNode }>(child)) {
        return getPlainText(child.props.children);
      }
      return '';
    })
    .join('')
    .trim();
}

function getTableHeaderTooltip(label: string): string | undefined {
  switch (label.toLowerCase()) {
    case 'scaled tokens':
      return 'Estimated row tokens scaled to the latest actual context_used reported by OpenCode. Use this as attribution, not exact tokenizer output.';
    case 'used %':
      return 'Approximate share of the current context_used attributed to this row.';
    case 'est tokens':
      return 'Raw local estimate before scaling. This is derived from text or bytes and is less accurate than the total context_used.';
    case 'bytes':
      return 'Total file bytes counted for this row.';
    default:
      return undefined;
  }
}

function normalizeTableAlign(align: string | undefined): React.CSSProperties['textAlign'] {
  if (align === 'right' || align === 'center' || align === 'justify') return align;
  return 'left';
}

function spansMultipleMarkdownLines(node: unknown): boolean {
  const position = (node as { position?: { start?: { line?: number }; end?: { line?: number } } } | null)?.position;
  const startLine = position?.start?.line;
  const endLine = position?.end?.line;
  return typeof startLine === 'number' && typeof endLine === 'number' && endLine > startLine;
}

function looksLikeSql(text: string): boolean {
  return /^(select|with|insert|update|delete|create|alter|drop|analyze|explain|show)\b/i.test(text.trimStart());
}

function removeSqlLabelAlignment(label: string, sqlText: string): string {
  const text = sqlText.trimStart().replace(/[ \t]+$/gm, '');
  const lines = text.split('\n');
  if (lines.length <= 1) return text;

  const labelAlignment = ' '.repeat(label.length + 2);
  return lines
    .map((line, index) => (index > 0 && line.startsWith(labelAlignment) ? line.slice(labelAlignment.length) : line))
    .join('\n');
}

function inferCodeBlockPresentation(codeText: string): { language?: string; label?: string; displayText: string } {
  const sqlBlockMatch = codeText.match(/^\s*((?:full_)?sql):[ \t]*([\s\S]*)$/i);
  if (sqlBlockMatch && looksLikeSql(sqlBlockMatch[2])) {
    const label = sqlBlockMatch[1];
    return {
      language: 'sql',
      label,
      displayText: removeSqlLabelAlignment(label, sqlBlockMatch[2]),
    };
  }

  return { displayText: codeText };
}

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

  const handleCopy = () => {
    navigator.clipboard.writeText(text).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };

  return (
    <button
      onClick={handleCopy}
      style={{
        position: 'absolute',
        top: '8px',
        right: '8px',
        background: 'rgba(0, 0, 0, 0.04)',
        border: '1px solid rgba(0, 0, 0, 0.08)',
        borderRadius: '4px',
        padding: '2px 8px',
        fontSize: '11px',
        color: '#6b7280',
        cursor: 'pointer',
        opacity: 0.6,
        transition: 'opacity 0.15s',
        lineHeight: '20px',
      }}
      onMouseEnter={e => { e.currentTarget.style.opacity = '1'; }}
      onMouseLeave={e => { e.currentTarget.style.opacity = '0.6'; }}
    >
      {copied ? t('chat.copied') : t('chat.copy')}
    </button>
  );
}

export const MarkdownContent = React.memo(function MarkdownContent({ content, isUser = false }: MarkdownContentProps) {
  return (
    <Box
      className="markdown-content"
      style={{
        fontSize: '14px',
        lineHeight: '1.6',
        color: isUser ? '#fff' : '#1f2937',
      }}
    >
      <ReactMarkdown
        remarkPlugins={[remarkGfm]}
        components={{
          // Paragraphs
          p: ({ node, ...props }) => (
            <p style={{ margin: '0.5em 0' }} {...props} />
          ),
          // Headings
          h1: ({ node, ...props }) => (
            <h1 style={{ fontSize: '1.5em', fontWeight: 600, margin: '0.8em 0 0.4em', color: isUser ? '#fff' : '#111827' }} {...props} />
          ),
          h2: ({ node, ...props }) => (
            <h2 style={{ fontSize: '1.3em', fontWeight: 600, margin: '0.7em 0 0.3em', color: isUser ? '#fff' : '#111827' }} {...props} />
          ),
          h3: ({ node, ...props }) => (
            <h3 style={{ fontSize: '1.1em', fontWeight: 600, margin: '0.6em 0 0.3em', color: isUser ? '#fff' : '#111827' }} {...props} />
          ),
          // Code blocks
          code: ({ node, className, children, ...props }) => {
            const match = /language-(\w+)/.exec(className || '');
            const codeText = String(children).replace(/\n$/, '');
            const isBlock = !!match || codeText.includes('\n') || spansMultipleMarkdownLines(node);
            const isInline = !isBlock;
            const presentation = inferCodeBlockPresentation(codeText);
            const language = match?.[1] || presentation.language;
            const displayCodeText = presentation.displayText;

            if (isInline) {
              return (
                <code
                  style={{
                    backgroundColor: isUser ? 'rgba(255, 255, 255, 0.2)' : '#f0f1f3',
                    padding: '0.15em 0.4em',
                    borderRadius: '4px',
                    fontSize: '0.875em',
                    fontFamily: CODE_FONT,
                    color: isUser ? '#fff' : '#0d6efd',
                    border: isUser ? 'none' : '1px solid #e2e4e8',
                    fontWeight: 500,
                  }}
                  {...props}
                >
                  {children}
                </code>
              );
            }

            // Block code — with syntax highlighting for assistant messages.
            // Also infer SQL for unlabeled blocks like "full_sql: SELECT ...".
            if (!isUser && language) {
              return (
                <div style={{ position: 'relative' }}>
                  <div style={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: '8px',
                    padding: '6px 12px',
                    background: '#e8e9ec',
                    borderRadius: '8px 8px 0 0',
                    fontSize: '11px',
                    color: '#6b7280',
                    fontFamily: CODE_FONT,
                  }}>
                    <span>{language}</span>
                    {presentation.label && (
                      <span style={{
                        color: '#334155',
                        background: '#f8fafc',
                        border: '1px solid #d7dce3',
                        borderRadius: '999px',
                        padding: '1px 6px',
                      }}>
                        {presentation.label}
                      </span>
                    )}
                  </div>
                  <CopyButton text={codeText} />
                  <SyntaxHighlighter
                    style={oneLight}
                    language={language}
                    PreTag="div"
                    customStyle={{
                      margin: 0,
                      borderRadius: '0 0 8px 8px',
                      padding: '14px 16px',
                      fontSize: '13px',
                      fontFamily: CODE_FONT,
                      border: '1px solid #e2e4e8',
                      borderTop: 'none',
                      background: '#fafbfc',
                    }}
                    codeTagProps={{
                      style: {
                        fontFamily: CODE_FONT,
                        fontSize: '13px',
                        lineHeight: '1.5',
                        whiteSpace: 'pre-wrap',
                        wordBreak: 'break-word',
                      },
                    }}
                    wrapLongLines
                  >
                    {displayCodeText}
                  </SyntaxHighlighter>
                </div>
              );
            }

            // Block code without language or user messages — styled without highlighting
            return (
              <div style={{ position: 'relative' }}>
                {!isUser && <CopyButton text={codeText} />}
                <code
                  style={{
                    display: 'block',
                    backgroundColor: isUser ? 'rgba(255, 255, 255, 0.1)' : '#fafbfc',
                    padding: '14px 16px',
                    borderRadius: '8px',
                    fontSize: '13px',
                    fontFamily: CODE_FONT,
                    overflowX: 'auto',
                    maxWidth: '100%',
                    whiteSpace: 'pre-wrap',
                    wordBreak: 'break-word',
                    color: isUser ? '#fff' : '#1f2937',
                    border: isUser ? '1px solid rgba(255, 255, 255, 0.2)' : '1px solid #e2e4e8',
                    lineHeight: '1.5',
                  }}
                  {...props}
                >
                  {children}
                </code>
              </div>
            );
          },
          // Pre (wrapper for code blocks)
          pre: ({ node, ...props }) => (
            <pre style={{ margin: '0.75em 0', overflow: 'visible' }} {...props} />
          ),
          // Lists
          ul: ({ node, ...props }) => (
            <ul style={{ margin: '0.5em 0', paddingLeft: '1.5em', listStyleType: 'disc' }} {...props} />
          ),
          ol: ({ node, ...props }) => (
            <ol style={{ margin: '0.5em 0', paddingLeft: '1.5em', listStyleType: 'decimal' }} {...props} />
          ),
          li: ({ node, ...props }) => (
            <li style={{ margin: '0.25em 0', listStyleType: 'inherit' }} {...props} />
          ),
          // Blockquote
          blockquote: ({ node, ...props }) => (
            <blockquote
              style={{
                borderLeft: `3px solid ${isUser ? 'rgba(255, 255, 255, 0.5)' : '#6366f1'}`,
                backgroundColor: isUser ? 'rgba(255, 255, 255, 0.08)' : '#f5f5ff',
                padding: '10px 16px',
                margin: '0.75em 0',
                borderRadius: '0 8px 8px 0',
                color: isUser ? 'rgba(255, 255, 255, 0.9)' : '#4b5563',
                fontStyle: 'normal',
              }}
              {...props}
            />
          ),
          // Links
          a: ({ node, ...props }) => (
            <a
              style={{
                color: isUser ? '#fff' : '#3b82f6',
                textDecoration: 'underline',
              }}
              target="_blank"
              rel="noopener noreferrer"
              {...props}
            />
          ),
          // Tables
          table: ({ node, ...props }) => (
            <div style={{ overflowX: 'auto', margin: '0.75em 0', borderRadius: '8px', border: '1px solid #d1d5db', backgroundColor: '#fff' }}>
              <table
                style={{
                  borderCollapse: 'collapse',
                  width: '100%',
                  fontSize: '0.9em',
                  backgroundColor: '#fff',
                  color: '#1f2937',
                }}
                {...props}
              />
            </div>
          ),
          th: ({ node, children, align, ...props }) => {
            const tooltip = getTableHeaderTooltip(getPlainText(children));
            return (
              <th
                {...props}
                title={tooltip || props.title}
                style={{
                  borderBottom: '1px solid #d1d5db',
                  padding: '8px 12px',
                  backgroundColor: '#f3f4f6',
                  color: '#111827',
                  fontWeight: 600,
                  textAlign: normalizeTableAlign(align),
                  whiteSpace: 'nowrap',
                  cursor: tooltip ? 'help' : undefined,
                  textDecoration: tooltip ? 'underline dotted' : undefined,
                  textUnderlineOffset: tooltip ? '3px' : undefined,
                }}
              >
                {children}
              </th>
            );
          },
          td: ({ node, children, align, ...props }) => (
            <td
              {...props}
              style={{
                borderBottom: '1px solid #e5e7eb',
                padding: '8px 12px',
                backgroundColor: '#fff',
                color: '#1f2937',
                textAlign: normalizeTableAlign(align),
              }}
            >
              {children}
            </td>
          ),
          // Horizontal rule
          hr: ({ node, ...props }) => (
            <hr
              style={{
                border: 'none',
                borderTop: `1px solid ${isUser ? 'rgba(255, 255, 255, 0.3)' : '#e5e7eb'}`,
                margin: '1em 0',
              }}
              {...props}
            />
          ),
          // Strong/Bold
          strong: ({ node, ...props }) => (
            <strong style={{ fontWeight: 600 }} {...props} />
          ),
          // Emphasis/Italic
          em: ({ node, ...props }) => (
            <em style={{ fontStyle: 'italic' }} {...props} />
          ),
        }}
      >
        {content}
      </ReactMarkdown>
    </Box>
  );
});
