import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import { Loader } from 'lucide-react';

const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';

// ---------------------------------------------------------------------------
// Severity color mapping — matches DESIGN_SYSTEM.md badge colors
// ---------------------------------------------------------------------------
const SEVERITY_COLORS = {
  Critical: { border: '#EF4444', bg: 'rgba(239, 68, 68, 0.25)', text: '#FCA5A5', dot: '#EF4444' },
  High:     { border: '#F59E0B', bg: 'rgba(245, 158, 11, 0.25)', text: '#FCD34D', dot: '#F59E0B' },
  Medium:   { border: '#0EA5E9', bg: 'rgba(14, 165, 233, 0.25)', text: '#7DD3FC', dot: '#0EA5E9' },
  Low:      { border: '#10B981', bg: 'rgba(16, 185, 129, 0.25)', text: '#6EE7B7', dot: '#10B981' },
};

// ---------------------------------------------------------------------------
// Pure positioning function — exported for testability
// ---------------------------------------------------------------------------
const TOOLTIP_GAP = 8;
const ARROW_SIZE = 6;

export function calcTooltipPosition(anchorRect, tooltipHeight, viewportHeight) {
  const spaceAbove = anchorRect.top;
  const spaceBelow = viewportHeight - anchorRect.bottom;
  const needed = tooltipHeight + TOOLTIP_GAP + ARROW_SIZE;

  const placeAbove = spaceAbove >= needed || spaceAbove >= spaceBelow;

  let top;
  if (placeAbove) {
    top = anchorRect.top - tooltipHeight - TOOLTIP_GAP - ARROW_SIZE;
    if (top < 0) top = 0;
  } else {
    top = anchorRect.bottom + TOOLTIP_GAP + ARROW_SIZE;
    if (top + tooltipHeight > viewportHeight) top = viewportHeight - tooltipHeight;
  }

  const left = anchorRect.left + anchorRect.width / 2;

  return { top, left, placeAbove };
}

// ---------------------------------------------------------------------------
// CveTooltip component
// ---------------------------------------------------------------------------
export default function CveTooltip({ cveId, anchorRect, cache }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!cveId) {
      setData(null);
      setLoading(false);
      return;
    }

    // Check cache first
    if (cache.current.has(cveId)) {
      setData(cache.current.get(cveId));
      setLoading(false);
      return;
    }

    // Cache miss — fetch from API
    const controller = new AbortController();
    setLoading(true);
    setData(null);

    fetch(`${API_BASE}/cves/${encodeURIComponent(cveId)}/tooltip`, {
      credentials: 'include',
      signal: controller.signal,
    })
      .then((res) => {
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        return res.json();
      })
      .then((payload) => {
        cache.current.set(cveId, payload);
        setData(payload);
        setLoading(false);
      })
      .catch((err) => {
        if (err.name === 'AbortError') return;
        // Do not cache transient errors
        console.error('CveTooltip fetch error:', err);
        setData(null);
        setLoading(false);
      });

    return () => controller.abort();
  }, [cveId, cache]);

  // Nothing to show
  if (!cveId || !anchorRect) return null;
  if (!loading && !data) return null;
  if (data && data.exists === false) return null;

  const severity = data?.severity || '';
  const colors = SEVERITY_COLORS[severity] || SEVERITY_COLORS.Medium;

  return ReactDOM.createPortal(
    <TooltipBody
      data={data}
      loading={loading}
      anchorRect={anchorRect}
      colors={colors}
      severity={severity}
    />,
    document.body,
  );
}


// ---------------------------------------------------------------------------
// TooltipBody — inner component that measures itself for positioning
// ---------------------------------------------------------------------------
function TooltipBody({ data, loading, anchorRect, colors, severity }) {
  const tooltipRef = React.useRef(null);
  const [pos, setPos] = React.useState({ top: 0, left: 0, placeAbove: true });

  React.useLayoutEffect(() => {
    if (!tooltipRef.current || !anchorRect) return;
    const rect = tooltipRef.current.getBoundingClientRect();
    const vp = window.innerHeight;
    setPos(calcTooltipPosition(anchorRect, rect.height, vp));
  }, [anchorRect, data, loading]);

  const tooltipStyle = {
    position: 'fixed',
    zIndex: 99999,
    top: pos.top,
    left: pos.left,
    transform: 'translateX(-50%)',
    maxWidth: 320,
    minWidth: 200,
    background: 'linear-gradient(135deg, rgba(30, 41, 59, 0.98), rgba(51, 65, 85, 0.95))',
    border: `1.5px solid ${colors.border}`,
    borderRadius: '0.5rem',
    padding: '0.75rem',
    boxShadow: `0 8px 24px rgba(0, 0, 0, 0.6), 0 0 16px ${colors.border}33`,
    pointerEvents: 'none',
    transition: 'opacity 0.15s ease',
  };

  // Directional arrow
  const arrowStyle = {
    position: 'absolute',
    left: '50%',
    transform: 'translateX(-50%)',
    width: 0,
    height: 0,
    borderLeft: `${ARROW_SIZE}px solid transparent`,
    borderRight: `${ARROW_SIZE}px solid transparent`,
    ...(pos.placeAbove
      ? {
          bottom: -ARROW_SIZE,
          borderTop: `${ARROW_SIZE}px solid ${colors.border}`,
          borderBottom: 'none',
        }
      : {
          top: -ARROW_SIZE,
          borderBottom: `${ARROW_SIZE}px solid ${colors.border}`,
          borderTop: 'none',
        }),
  };

  return (
    <div ref={tooltipRef} style={tooltipStyle} data-testid="cve-tooltip">
      {/* Arrow */}
      <div style={arrowStyle} data-testid="cve-tooltip-arrow" />

      {loading ? (
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '0.5rem 0' }}>
          <Loader
            style={{ width: 18, height: 18, color: '#0EA5E9', animation: 'spin 1s linear infinite' }}
            data-testid="cve-tooltip-loader"
          />
        </div>
      ) : data && data.exists ? (
        <>
          {/* CVE ID header */}
          <div style={{
            fontFamily: "'JetBrains Mono', monospace",
            fontSize: '0.8rem',
            fontWeight: 700,
            color: '#E2E8F0',
            marginBottom: '0.4rem',
            letterSpacing: '0.02em',
          }}>
            {data.cve_id}
          </div>

          {/* Severity badge */}
          {severity && (
            <div style={{
              display: 'inline-flex',
              alignItems: 'center',
              gap: '0.35rem',
              padding: '0.2rem 0.5rem',
              borderRadius: '0.25rem',
              border: `1.5px solid ${colors.border}`,
              background: colors.bg,
              marginBottom: '0.5rem',
            }}>
              {/* Glow dot */}
              <span style={{
                width: 7,
                height: 7,
                borderRadius: '50%',
                background: colors.dot,
                boxShadow: `0 0 6px ${colors.dot}`,
                flexShrink: 0,
              }} />
              <span style={{
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: '0.65rem',
                fontWeight: 700,
                textTransform: 'uppercase',
                letterSpacing: '0.04em',
                color: colors.text,
              }}>
                {severity}
              </span>
            </div>
          )}

          {/* Description */}
          {data.description && (
            <div style={{
              fontSize: '0.75rem',
              lineHeight: 1.5,
              color: '#CBD5E1',
              wordBreak: 'break-word',
            }}>
              {data.description}
            </div>
          )}
        </>
      ) : null}
    </div>
  );
}
