import { useState, type CSSProperties, type ReactNode } from 'react';
import type { Citation } from './types.js';

export interface CitationChipProps {
  citation: Citation;
  /** Override the chip body — useful for icons. Defaults to `[n]`. */
  children?: ReactNode;
  /** Suppress the popover preview (e.g. when used inline in dense lists). */
  noPreview?: boolean;
  className?: string;
  style?: CSSProperties;
}

/**
 * Inline citation marker. Renders a small `[n]` chip; on hover or focus
 * a preview pops up with the title, snippet, and an outbound link.
 *
 * The preview is a CSS-only popover (no portal, no JS layout) so it
 * stays cheap to embed dozens of times in a single message body.
 */
export function CitationChip({
  citation,
  children,
  noPreview = false,
  className,
  style,
}: CitationChipProps) {
  const [hover, setHover] = useState(false);
  const [focus, setFocus] = useState(false);
  const open = !noPreview && (hover || focus);

  const Wrapper = citation.url ? 'a' : 'span';
  const wrapperProps = citation.url
    ? {
        href: citation.url,
        target: '_blank',
        rel: 'noopener noreferrer',
      }
    : {};

  return (
    <span
      style={{ position: 'relative', display: 'inline-block', ...style }}
      className={className}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
    >
      <Wrapper
        data-testid={`bl-citation-${citation.id}`}
        data-citation-index={citation.index}
        {...wrapperProps}
        onFocus={() => setFocus(true)}
        onBlur={() => setFocus(false)}
        style={{
          display: 'inline-flex',
          alignItems: 'center',
          justifyContent: 'center',
          minWidth: 18,
          height: 18,
          padding: '0 4px',
          marginInline: 2,
          fontSize: 11,
          fontWeight: 700,
          lineHeight: 1,
          color: 'var(--bl-accent, #6366f1)',
          background: 'var(--bl-accent-muted, rgba(99,102,241,0.12))',
          borderRadius: 'var(--bl-radius-pill, 999px)',
          textDecoration: 'none',
          cursor: citation.url ? 'pointer' : 'help',
          verticalAlign: 'super',
        }}
      >
        {children ?? citation.index}
      </Wrapper>

      {open && (
        <span
          role="tooltip"
          data-testid={`bl-citation-preview-${citation.id}`}
          style={{
            position: 'absolute',
            bottom: 'calc(100% + 6px)',
            left: 0,
            zIndex: 50,
            display: 'block',
            width: 280,
            padding: 'var(--bl-space-3, 12px)',
            background: 'var(--bl-surface-card, #fff)',
            color: 'var(--bl-text-primary, inherit)',
            border: '1px solid var(--bl-border, rgba(0,0,0,0.08))',
            borderRadius: 'var(--bl-radius-card, 10px)',
            boxShadow: '0 10px 30px rgba(0,0,0,0.18)',
            fontSize: '0.8rem',
            lineHeight: 1.45,
            fontWeight: 400,
            textAlign: 'left',
            whiteSpace: 'normal',
            pointerEvents: 'none', // hover-only preview; avoids flicker
          }}
        >
          {citation.source && (
            <div
              style={{
                fontSize: '0.65rem',
                textTransform: 'uppercase',
                letterSpacing: '0.06em',
                color: 'var(--bl-text-tertiary, #888)',
                marginBottom: 2,
              }}
            >
              {citation.source}
            </div>
          )}
          <div style={{ fontWeight: 600, marginBottom: 4 }}>{citation.title}</div>
          {citation.snippet && (
            <div style={{ color: 'var(--bl-text-secondary, #444)' }}>
              {citation.snippet}
            </div>
          )}
          {citation.url && (
            <div
              style={{
                marginTop: 6,
                fontSize: '0.7rem',
                color: 'var(--bl-text-tertiary, #888)',
                wordBreak: 'break-all',
              }}
            >
              {truncateUrl(citation.url)}
            </div>
          )}
        </span>
      )}
    </span>
  );
}

function truncateUrl(url: string, max = 56): string {
  return url.length <= max ? url : `${url.slice(0, max - 1)}…`;
}
