/**
 * MarkdownRenderer Component
 * Reusable markdown rendering with syntax highlighting and custom components
 */

import React, { useMemo, useState } from 'react';
import {
  Copy,
  Check,
  ExternalLink,
  TrendingUp,
  TrendingDown,
  AlertTriangle,
  Info,
  CheckCircle,
} from 'lucide-react';

interface MarkdownRendererProps {
  content: string;
  className?: string;
  onLinkClick?: (url: string) => void;
  onSignalClick?: (signal: ParsedSignal) => void;
  enableCodeCopy?: boolean;
  enableSignalParsing?: boolean;
  compact?: boolean;
}

interface ParsedSignal {
  symbol: string;
  action: 'BUY' | 'SELL';
  entry?: number;
  stopLoss?: number;
  takeProfit?: number;
  confidence?: number;
}

// Simple markdown parser without external dependencies
const parseMarkdown = (text: string): React.ReactNode[] => {
  const elements: React.ReactNode[] = [];
  const lines = text.split('\n');
  let inCodeBlock = false;
  let codeBlockContent: string[] = [];
  let codeBlockLanguage = '';
  let listItems: string[] = [];
  let listType: 'ul' | 'ol' | null = null;

  const flushList = () => {
    if (listItems.length > 0 && listType) {
      const ListTag = listType === 'ol' ? 'ol' : 'ul';
      elements.push(
        <ListTag
          key={`list-${elements.length}`}
          className={`my-2 ${listType === 'ol' ? 'list-decimal' : 'list-disc'} list-inside space-y-1`}
        >
          {listItems.map((item, i) => (
            <li key={i} className="text-gray-300">
              {parseInlineMarkdown(item)}
            </li>
          ))}
        </ListTag>
      );
      listItems = [];
      listType = null;
    }
  };

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];

    // Code block handling
    if (line.startsWith('```')) {
      if (!inCodeBlock) {
        flushList();
        inCodeBlock = true;
        codeBlockLanguage = line.slice(3).trim();
        codeBlockContent = [];
      } else {
        elements.push(
          <CodeBlock
            key={`code-${elements.length}`}
            code={codeBlockContent.join('\n')}
            language={codeBlockLanguage}
          />
        );
        inCodeBlock = false;
        codeBlockContent = [];
        codeBlockLanguage = '';
      }
      continue;
    }

    if (inCodeBlock) {
      codeBlockContent.push(line);
      continue;
    }

    // Empty line - flush list and add break
    if (!line.trim()) {
      flushList();
      continue;
    }

    // Headers
    if (line.startsWith('### ')) {
      flushList();
      elements.push(
        <h3 key={`h3-${i}`} className="text-lg font-semibold text-white mt-4 mb-2">
          {parseInlineMarkdown(line.slice(4))}
        </h3>
      );
      continue;
    }
    if (line.startsWith('## ')) {
      flushList();
      elements.push(
        <h2 key={`h2-${i}`} className="text-xl font-semibold text-white mt-4 mb-2">
          {parseInlineMarkdown(line.slice(3))}
        </h2>
      );
      continue;
    }
    if (line.startsWith('# ')) {
      flushList();
      elements.push(
        <h1 key={`h1-${i}`} className="text-2xl font-bold text-white mt-4 mb-2">
          {parseInlineMarkdown(line.slice(2))}
        </h1>
      );
      continue;
    }

    // Blockquotes
    if (line.startsWith('> ')) {
      flushList();
      elements.push(
        <blockquote
          key={`bq-${i}`}
          className="border-l-4 border-blue-500 pl-4 py-1 my-2 text-gray-400 italic"
        >
          {parseInlineMarkdown(line.slice(2))}
        </blockquote>
      );
      continue;
    }

    // Horizontal rule
    if (line.match(/^(-{3,}|\*{3,}|_{3,})$/)) {
      flushList();
      elements.push(<hr key={`hr-${i}`} className="my-4 border-gray-700" />);
      continue;
    }

    // Unordered list
    if (line.match(/^[\s]*[-*+]\s/)) {
      if (listType !== 'ul') {
        flushList();
        listType = 'ul';
      }
      listItems.push(line.replace(/^[\s]*[-*+]\s/, ''));
      continue;
    }

    // Ordered list
    if (line.match(/^[\s]*\d+\.\s/)) {
      if (listType !== 'ol') {
        flushList();
        listType = 'ol';
      }
      listItems.push(line.replace(/^[\s]*\d+\.\s/, ''));
      continue;
    }

    // Regular paragraph
    flushList();
    elements.push(
      <p key={`p-${i}`} className="text-gray-300 my-1">
        {parseInlineMarkdown(line)}
      </p>
    );
  }

  // Flush any remaining list
  flushList();

  // Handle unclosed code block
  if (inCodeBlock && codeBlockContent.length > 0) {
    elements.push(
      <CodeBlock
        key={`code-${elements.length}`}
        code={codeBlockContent.join('\n')}
        language={codeBlockLanguage}
      />
    );
  }

  return elements;
};

// Parse inline markdown (bold, italic, code, links)
const parseInlineMarkdown = (text: string): React.ReactNode => {
  const parts: React.ReactNode[] = [];
  let remaining = text;
  let key = 0;

  while (remaining.length > 0) {
    // Bold **text** or __text__
    let match = remaining.match(/^(.*?)(\*\*|__)(.+?)\2(.*)$/s);
    if (match) {
      if (match[1]) parts.push(parseInlineMarkdown(match[1]));
      parts.push(
        <strong key={key++} className="font-semibold text-white">
          {match[3]}
        </strong>
      );
      remaining = match[4];
      continue;
    }

    // Italic *text* or _text_
    match = remaining.match(/^(.*?)(\*|_)(.+?)\2(.*)$/s);
    if (match) {
      if (match[1]) parts.push(parseInlineMarkdown(match[1]));
      parts.push(
        <em key={key++} className="italic">
          {match[3]}
        </em>
      );
      remaining = match[4];
      continue;
    }

    // Inline code `code`
    match = remaining.match(/^(.*?)`(.+?)`(.*)$/s);
    if (match) {
      if (match[1]) parts.push(match[1]);
      parts.push(
        <code
          key={key++}
          className="px-1.5 py-0.5 bg-gray-700 text-blue-300 rounded text-sm font-mono"
        >
          {match[2]}
        </code>
      );
      remaining = match[3];
      continue;
    }

    // Links [text](url)
    match = remaining.match(/^(.*?)\[(.+?)\]\((.+?)\)(.*)$/s);
    if (match) {
      if (match[1]) parts.push(match[1]);
      parts.push(
        <a
          key={key++}
          href={match[3]}
          target="_blank"
          rel="noopener noreferrer"
          className="text-blue-400 hover:text-blue-300 underline inline-flex items-center gap-1"
        >
          {match[2]}
          <ExternalLink className="w-3 h-3" />
        </a>
      );
      remaining = match[4];
      continue;
    }

    // No more patterns, add remaining text
    parts.push(remaining);
    break;
  }

  return parts.length === 1 ? parts[0] : <>{parts}</>;
};

// Code block component with copy button
const CodeBlock: React.FC<{ code: string; language: string }> = ({ code, language }) => {
  const [copied, setCopied] = useState(false);

  const handleCopy = async () => {
    await navigator.clipboard.writeText(code);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <div className="relative my-3 rounded-lg overflow-hidden">
      <div className="flex items-center justify-between px-4 py-2 bg-gray-900 border-b border-gray-700">
        <span className="text-xs text-gray-400 font-mono">{language || 'code'}</span>
        <button
          onClick={handleCopy}
          className="flex items-center gap-1 px-2 py-1 text-xs text-gray-400 hover:text-white transition-colors"
        >
          {copied ? (
            <>
              <Check className="w-3 h-3 text-green-400" />
              Copied
            </>
          ) : (
            <>
              <Copy className="w-3 h-3" />
              Copy
            </>
          )}
        </button>
      </div>
      <pre className="p-4 bg-gray-900/50 overflow-x-auto">
        <code className="text-sm font-mono text-gray-300 whitespace-pre">{code}</code>
      </pre>
    </div>
  );
};

// Alert/callout component
const AlertBox: React.FC<{
  type: 'info' | 'warning' | 'success' | 'error';
  children: React.ReactNode;
}> = ({ type, children }) => {
  const styles = {
    info: { bg: 'bg-blue-500/10', border: 'border-blue-500/30', icon: Info, color: 'text-blue-400' },
    warning: { bg: 'bg-yellow-500/10', border: 'border-yellow-500/30', icon: AlertTriangle, color: 'text-yellow-400' },
    success: { bg: 'bg-green-500/10', border: 'border-green-500/30', icon: CheckCircle, color: 'text-green-400' },
    error: { bg: 'bg-red-500/10', border: 'border-red-500/30', icon: AlertTriangle, color: 'text-red-400' },
  };

  const style = styles[type];
  const Icon = style.icon;

  return (
    <div className={`flex items-start gap-3 p-3 my-2 rounded-lg ${style.bg} border ${style.border}`}>
      <Icon className={`w-5 h-5 ${style.color} flex-shrink-0 mt-0.5`} />
      <div className="flex-1 text-sm text-gray-300">{children}</div>
    </div>
  );
};

// Trading signal component
const SignalCard: React.FC<{
  signal: ParsedSignal;
  onClick?: () => void;
}> = ({ signal, onClick }) => {
  const isBuy = signal.action === 'BUY';

  return (
    <button
      onClick={onClick}
      className={`w-full p-3 my-2 rounded-lg border transition-colors ${
        isBuy
          ? 'bg-green-500/10 border-green-500/30 hover:bg-green-500/20'
          : 'bg-red-500/10 border-red-500/30 hover:bg-red-500/20'
      }`}
    >
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-2">
          {isBuy ? (
            <TrendingUp className="w-5 h-5 text-green-400" />
          ) : (
            <TrendingDown className="w-5 h-5 text-red-400" />
          )}
          <span className="font-bold text-white">{signal.symbol}</span>
          <span className={`text-sm font-medium ${isBuy ? 'text-green-400' : 'text-red-400'}`}>
            {signal.action}
          </span>
        </div>
        {signal.confidence && (
          <span className="text-xs text-gray-400">{signal.confidence}% confidence</span>
        )}
      </div>
      {(signal.entry || signal.stopLoss || signal.takeProfit) && (
        <div className="flex gap-4 mt-2 text-xs text-gray-400">
          {signal.entry && <span>Entry: {signal.entry}</span>}
          {signal.stopLoss && <span className="text-red-400">SL: {signal.stopLoss}</span>}
          {signal.takeProfit && <span className="text-green-400">TP: {signal.takeProfit}</span>}
        </div>
      )}
    </button>
  );
};

const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({
  content,
  className = '',
  onLinkClick,
  onSignalClick,
  enableCodeCopy = true,
  enableSignalParsing = true,
  compact = false,
}) => {
  const renderedContent = useMemo(() => {
    if (!content) return null;
    return parseMarkdown(content);
  }, [content]);

  return (
    <div className={`markdown-content ${compact ? 'text-sm' : ''} ${className}`}>
      {renderedContent}
    </div>
  );
};

export default MarkdownRenderer;
export { CodeBlock, AlertBox, SignalCard, parseMarkdown, parseInlineMarkdown };
