// components/Chat/chatHelpers.tsx
import React from 'react';
import { theme } from './theme';

// ─────────────────────────────────────────────────────────────────────────
// Smart relative timestamps
// ─────────────────────────────────────────────────────────────────────────
export function smartTime(d: string | null | undefined): string {
  if (!d) return '';
  try {
    const date = new Date(d);
    const diff = Date.now() - date.getTime();
    if (diff < 10_000)         return 'just now';
    if (diff < 60_000)         return `${Math.floor(diff / 1000)}s`;
    if (diff < 3_600_000)      return `${Math.floor(diff / 60_000)}m`;
    if (diff < 86_400_000)     return date.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
    if (diff < 172_800_000)    return 'Yesterday';
    if (diff < 604_800_000)    return date.toLocaleDateString('en-GB', { weekday: 'short' });
    return date.toLocaleDateString('en-GB', { day: '2-digit', month: 'short' });
  } catch {
    return '';
  }
}

export function preciseTime(d: string): string {
  try {
    return new Date(d).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
  } catch {
    return '';
  }
}

export function dateHeader(d: string): string {
  try {
    const date = new Date(d);
    const diff = Math.floor((Date.now() - date.getTime()) / 86_400_000);
    if (diff === 0) return 'Today';
    if (diff === 1) return 'Yesterday';
    if (diff < 7)   return date.toLocaleDateString('en-GB', { weekday: 'long' });
    return date.toLocaleDateString('en-GB', { weekday: 'long', day: '2-digit', month: 'short', year: 'numeric' });
  } catch {
    return '';
  }
}

// ─────────────────────────────────────────────────────────────────────────
// Avatar color (deterministic from name)
// ─────────────────────────────────────────────────────────────────────────
export function avatarColor(name: string): string {
  if (!name) return theme.avatarPalette[0];
  let hash = 0;
  for (let i = 0; i < name.length; i++) {
    hash = name.charCodeAt(i) + ((hash << 5) - hash);
  }
  return theme.avatarPalette[Math.abs(hash) % theme.avatarPalette.length];
}

export function initials(name: string): string {
  if (!name) return '?';
  return name.trim().split(/\s+/).map(n => n[0]).slice(0, 2).join('').toUpperCase();
}

// ─────────────────────────────────────────────────────────────────────────
// URL detection + safe linking (using React.createElement to avoid JSX issues)
// ─────────────────────────────────────────────────────────────────────────
const URL_RE = /(https?:\/\/[^\s<>"]+)/gi;

function makeLink(url: string, isMine: boolean, key: string): React.ReactNode {
  return React.createElement('a', {
    key,
    href: url,
    target: '_blank',
    rel: 'noopener noreferrer',
    onClick: (e: React.MouseEvent) => e.stopPropagation(),
    style: {
      color: isMine ? '#fff' : theme.brand[600],
      textDecoration: 'underline',
      textUnderlineOffset: 2,
      wordBreak: 'break-all',
    },
  }, url);
}

export function renderTextWithLinks(text: string, isMine: boolean): React.ReactNode[] {
  const parts: React.ReactNode[] = [];
  let last = 0;
  let m: RegExpExecArray | null;
  URL_RE.lastIndex = 0;

  while ((m = URL_RE.exec(text)) !== null) {
    if (m.index > last) parts.push(text.slice(last, m.index));
    parts.push(makeLink(m[0], isMine, `lnk-${m.index}`));
    last = m.index + m[0].length;
  }
  if (last < text.length) parts.push(text.slice(last));
  return parts.length > 0 ? parts : [text];
}

// ─────────────────────────────────────────────────────────────────────────
// Lightweight markdown: **bold**, *italic*, `code`, auto-links
// ─────────────────────────────────────────────────────────────────────────
type Node = React.ReactNode;

function processCode(parts: Node[], isMine: boolean, lineIdx: number): Node[] {
  return parts.flatMap((part, i) => {
    if (typeof part !== 'string') return [part];
    const out: Node[] = [];
    let last = 0;
    const re = /`([^`]+)`/g;
    let m: RegExpExecArray | null;
    while ((m = re.exec(part)) !== null) {
      if (m.index > last) out.push(part.slice(last, m.index));
      out.push(
        React.createElement(
          'code',
          {
            key: `code-${lineIdx}-${i}-${m.index}`,
            style: {
              backgroundColor: isMine ? 'rgba(255,255,255,0.18)' : theme.gray[100],
              padding: '1px 6px',
              borderRadius: 4,
              fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
              fontSize: '0.9em',
            },
          },
          m[1]
        )
      );
      last = m.index + m[0].length;
    }
    if (last < part.length) out.push(part.slice(last));
    return out.length > 0 ? out : [part];
  });
}

function processBold(parts: Node[], lineIdx: number): Node[] {
  return parts.flatMap((part, i) => {
    if (typeof part !== 'string') return [part];
    const out: Node[] = [];
    let last = 0;
    const re = /\*\*([^*]+)\*\*/g;
    let m: RegExpExecArray | null;
    while ((m = re.exec(part)) !== null) {
      if (m.index > last) out.push(part.slice(last, m.index));
      out.push(React.createElement('strong', { key: `b-${lineIdx}-${i}-${m.index}` }, m[1]));
      last = m.index + m[0].length;
    }
    if (last < part.length) out.push(part.slice(last));
    return out.length > 0 ? out : [part];
  });
}

function processItalic(parts: Node[], lineIdx: number): Node[] {
  return parts.flatMap((part, i) => {
    if (typeof part !== 'string') return [part];
    const out: Node[] = [];
    let last = 0;
    const re = /(?<!\*)\*([^*\n]+)\*(?!\*)/g;
    let m: RegExpExecArray | null;
    while ((m = re.exec(part)) !== null) {
      if (m.index > last) out.push(part.slice(last, m.index));
      out.push(React.createElement('em', { key: `i-${lineIdx}-${i}-${m.index}` }, m[1]));
      last = m.index + m[0].length;
    }
    if (last < part.length) out.push(part.slice(last));
    return out.length > 0 ? out : [part];
  });
}

function processLinks(parts: Node[], isMine: boolean): Node[] {
  return parts.flatMap((part) => {
    if (typeof part !== 'string') return [part];
    return renderTextWithLinks(part, isMine);
  });
}

export function renderMarkdown(text: string, isMine: boolean): React.ReactNode {
  const lines = text.split('\n');
  const segments: Node[] = [];

  lines.forEach((line, lineIdx) => {
    let parts: Node[] = [line];
    parts = processCode(parts, isMine, lineIdx);
    parts = processBold(parts, lineIdx);
    parts = processItalic(parts, lineIdx);
    parts = processLinks(parts, isMine);

    segments.push(
      React.createElement(React.Fragment, { key: `line-${lineIdx}` }, ...parts)
    );

    if (lineIdx < lines.length - 1) {
      segments.push(React.createElement('br', { key: `br-${lineIdx}` }));
    }
  });

  return React.createElement(React.Fragment, null, ...segments);
}