/**
 * CardOwnerTooltip — CARD ownership hover tooltip
 *
 * Shows CARD asset ownership data (confirmed/unconfirmed/candidate teams)
 * when hovering over an IP address in the findings table.
 * Interactive — stays open when you hover into it, includes an Actions button.
 * Follows the same portal + positioning pattern as CveTooltip.
 */

import React, { useState, useEffect, useRef, useLayoutEffect, useCallback } from 'react';
import ReactDOM from 'react-dom';
import { Loader, AlertCircle, ExternalLink, Copy } from 'lucide-react';

// ⚠️ CONVENTION: Use relative API path fallback, not absolute URL. Should be: process.env.REACT_APP_API_BASE || '/api'
// Other components in this project use fetch() with relative paths and credentials: 'include'
const API_BASE = process.env.REACT_APP_API_BASE || 'http://localhost:3001/api';

const TOOLTIP_GAP = 8;
const ARROW_SIZE = 6;
const BORDER_COLOR = '#7C3AED'; // purple to match CARD branding

function calcPosition(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 };
}

// ---------------------------------------------------------------------------
// Main exported component
// ---------------------------------------------------------------------------
export default function CardOwnerTooltip({ ip, hostId, anchorRect, cache, cardConfigured, onAction, onMouseEnter, onMouseLeave }) {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);

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

        if (!cardConfigured) {
            setError('CARD not configured');
            setLoading(false);
            return;
        }

        // Check cache
        if (cache.current.has(ip)) {
            const cached = cache.current.get(ip);
            if (cached.error) {
                setError(cached.error);
                setData(null);
            } else {
                setData(cached);
                setError(null);
            }
            setLoading(false);
            return;
        }

        // Fetch — include hostId for fast-path resolution when available
        const controller = new AbortController();
        setLoading(true);
        setData(null);
        setError(null);

        const hostIdParam = hostId ? `&hostId=${encodeURIComponent(hostId)}` : '';
        fetch(`${API_BASE}/card/owner-lookup/${encodeURIComponent(ip)}?quick=1${hostIdParam}`, {
            credentials: 'include',
            signal: controller.signal,
        })
            .then((res) => {
                if (res.status === 404) {
                    const result = { notFound: true };
                    cache.current.set(ip, result);
                    setData(result);
                    setLoading(false);
                    return;
                }
                if (res.status === 504) {
                    // Timeout — don't cache, can be retried
                    setError('CARD lookup timed out — try again');
                    setLoading(false);
                    return;
                }
                if (res.status === 502) {
                    // CARD unreachable — don't cache
                    setError('CARD unavailable');
                    setLoading(false);
                    return;
                }
                if (!res.ok) return res.json().then(d => { throw new Error(d.error || `HTTP ${res.status}`); });
                return res.json();
            })
            .then((payload) => {
                if (!payload) return; // 404 already handled
                cache.current.set(ip, payload);
                setData(payload);
                setLoading(false);
            })
            .catch((err) => {
                if (err.name === 'AbortError') return;
                cache.current.set(ip, { error: err.message });
                setError(err.message);
                setLoading(false);
            });

        return () => controller.abort();
    }, [ip, hostId, cache, cardConfigured]);

    if (!ip || !anchorRect) return null;
    if (!loading && !data && !error) return null;

    return ReactDOM.createPortal(
        <TooltipBody
            data={data}
            loading={loading}
            error={error}
            anchorRect={anchorRect}
            ip={ip}
            hostId={hostId}
            onAction={onAction}
            onMouseEnter={onMouseEnter}
            onMouseLeave={onMouseLeave}
        />,
        document.body,
    );
}

// ---------------------------------------------------------------------------
// TooltipBody — inner component for measurement + rendering
// ---------------------------------------------------------------------------
function TooltipBody({ data, loading, error, anchorRect, ip, hostId, onAction, onMouseEnter, onMouseLeave }) {
    const tooltipRef = useRef(null);
    const [pos, setPos] = useState({ top: 0, left: 0, placeAbove: true });

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

    const handleAction = useCallback(() => {
        if (onAction && ip) {
            onAction(ip, data);
        }
    }, [onAction, ip, data]);

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

    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 ${BORDER_COLOR}`, borderBottom: 'none' }
            : { top: -ARROW_SIZE, borderBottom: `${ARROW_SIZE}px solid ${BORDER_COLOR}`, borderTop: 'none' }),
    };

    const LABEL = { fontSize: '0.58rem', color: '#64748B', textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: '0.15rem' };
    const BADGE = (color) => ({
        display: 'inline-block', padding: '0.12rem 0.45rem', borderRadius: '0.2rem',
        fontSize: '0.68rem', fontWeight: '600', fontFamily: "'JetBrains Mono', monospace",
        background: `${color}18`, border: `1px solid ${color}50`, color,
    });

    return (
        <div ref={tooltipRef} style={tooltipStyle} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
            <div style={arrowStyle} />

            {/* Header */}
            <div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', marginBottom: '0.5rem' }}>
                <span style={{ fontSize: '0.6rem', color: '#7C3AED', fontFamily: 'monospace', fontWeight: '700', textTransform: 'uppercase', letterSpacing: '0.08em' }}>
                    CARD
                </span>
                <span style={{ fontSize: '0.72rem', color: '#E2E8F0', fontFamily: "'JetBrains Mono', monospace", fontWeight: '600' }}>
                    {ip}
                </span>
            </div>

            {/* Loading */}
            {loading && (
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '0.5rem 0' }}>
                    <Loader style={{ width: 16, height: 16, color: '#7C3AED', animation: 'spin 1s linear infinite' }} />
                </div>
            )}

            {/* Error */}
            {error && !loading && (
                <div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem' }}>
                    <AlertCircle style={{ width: 12, height: 12, color: '#EF4444', flexShrink: 0 }} />
                    <span style={{ fontSize: '0.68rem', color: '#FCA5A5' }}>{error}</span>
                </div>
            )}

            {/* Not found */}
            {data && data.notFound && !loading && (
                <div style={{ fontSize: '0.7rem', color: '#64748B', fontFamily: 'monospace' }}>
                    Not found in CARD
                </div>
            )}

            {/* Owner data */}
            {data && !data.notFound && !data.error && !loading && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
                    {/* Asset ID */}
                    {data.asset_id && (
                        <div>
                            <div style={LABEL}>Asset ID</div>
                            <div style={{ fontSize: '0.68rem', color: '#A78BFA', fontFamily: "'JetBrains Mono', monospace" }}>
                                {data.asset_id}
                            </div>
                        </div>
                    )}

                    {/* Confirmed */}
                    <div>
                        <div style={LABEL}>Confirmed Owner</div>
                        {data.confirmed ? (
                            <div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem' }}>
                                <span style={BADGE('#10B981')}>{data.confirmed.name}</span>
                                {data.confirmed.score != null && (
                                    <span style={{ fontSize: '0.58rem', color: '#64748B' }}>score: {data.confirmed.score}</span>
                                )}
                            </div>
                        ) : (
                            <span style={{ fontSize: '0.68rem', color: '#475569' }}>—</span>
                        )}
                    </div>

                    {/* Unconfirmed */}
                    {data.unconfirmed && (
                        <div>
                            <div style={LABEL}>Unconfirmed</div>
                            <div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem' }}>
                                <span style={BADGE('#F59E0B')}>{data.unconfirmed.name}</span>
                                {data.unconfirmed.score != null && (
                                    <span style={{ fontSize: '0.58rem', color: '#64748B' }}>score: {data.unconfirmed.score}</span>
                                )}
                            </div>
                        </div>
                    )}

                    {/* Candidates */}
                    {data.candidate && data.candidate.length > 0 && (
                        <div>
                            <div style={LABEL}>Candidates</div>
                            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.25rem' }}>
                                {data.candidate.filter(c => c.name !== 'CARD-UNKNOWN').map((c, i) => (
                                    <span key={i} style={BADGE('#94A3B8')}>{c.name} ({c.score})</span>
                                ))}
                            </div>
                        </div>
                    )}

                    {/* Declined */}
                    {data.declined && data.declined.length > 0 && (
                        <div>
                            <div style={LABEL}>Declined</div>
                            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.25rem' }}>
                                {data.declined.map((d, i) => (
                                    <span key={i} style={BADGE('#EF4444')}>{d.name}</span>
                                ))}
                            </div>
                        </div>
                    )}

                    {/* Actions button */}
                    {onAction && (
                        <div style={{ marginTop: '0.4rem', paddingTop: '0.4rem', borderTop: '1px solid rgba(124, 58, 237, 0.2)', display: 'flex', gap: '0.4rem', flexWrap: 'wrap' }}>
                            <button
                                onClick={handleAction}
                                style={{
                                    display: 'inline-flex', alignItems: 'center', gap: '0.35rem',
                                    padding: '0.3rem 0.65rem',
                                    background: 'rgba(124, 58, 237, 0.12)',
                                    border: '1px solid rgba(124, 58, 237, 0.4)',
                                    borderRadius: '0.3rem',
                                    color: '#A78BFA',
                                    fontSize: '0.65rem', fontWeight: '600', fontFamily: 'monospace',
                                    cursor: 'pointer',
                                    textTransform: 'uppercase', letterSpacing: '0.04em',
                                    transition: 'all 0.12s',
                                }}
                                onMouseEnter={(e) => { e.currentTarget.style.background = 'rgba(124, 58, 237, 0.25)'; e.currentTarget.style.borderColor = 'rgba(124, 58, 237, 0.6)'; }}
                                onMouseLeave={(e) => { e.currentTarget.style.background = 'rgba(124, 58, 237, 0.12)'; e.currentTarget.style.borderColor = 'rgba(124, 58, 237, 0.4)'; }}
                            >
                                <ExternalLink style={{ width: 11, height: 11 }} />
                                Actions
                            </button>
                            {hostId && (
                                <button
                                    onClick={() => {
                                        try {
                                            const ta = document.createElement('textarea');
                                            ta.value = String(hostId);
                                            ta.style.position = 'fixed';
                                            ta.style.opacity = '0';
                                            document.body.appendChild(ta);
                                            ta.select();
                                            document.execCommand('copy');
                                            document.body.removeChild(ta);
                                        } catch (_) { /* best effort */ }
                                        window.open('https://card.charter.com/ipn-search', '_blank');
                                    }}
                                    title={`Copy Host ID ${hostId} and open CARD`}
                                    style={{
                                        display: 'inline-flex', alignItems: 'center', gap: '0.35rem',
                                        padding: '0.3rem 0.65rem',
                                        background: 'rgba(14, 165, 233, 0.12)',
                                        border: '1px solid rgba(14, 165, 233, 0.4)',
                                        borderRadius: '0.3rem',
                                        color: '#7DD3FC',
                                        fontSize: '0.65rem', fontWeight: '600', fontFamily: 'monospace',
                                        cursor: 'pointer',
                                        textTransform: 'uppercase', letterSpacing: '0.04em',
                                        transition: 'all 0.12s',
                                    }}
                                    onMouseEnter={(e) => { e.currentTarget.style.background = 'rgba(14, 165, 233, 0.25)'; e.currentTarget.style.borderColor = 'rgba(14, 165, 233, 0.6)'; }}
                                    onMouseLeave={(e) => { e.currentTarget.style.background = 'rgba(14, 165, 233, 0.12)'; e.currentTarget.style.borderColor = 'rgba(14, 165, 233, 0.4)'; }}
                                >
                                    <Copy style={{ width: 11, height: 11 }} />
                                    View in CARD
                                </button>
                            )}
                        </div>
                    )}
                </div>
            )}
        </div>
    );
}
