// Shared UI primitives — ported from
// design/design_handoff_nifty_bull/prototype/ui.jsx and adapted to take
// the strategy list from props (loaded from /api/strategies) instead of
// the prototype's hardcoded STRATEGIES global.

const Icon = {
    Search: (p) => (<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="9" cy="9" r="6" /><path d="m17 17-3.5-3.5" /></svg>),
    Chevron: (p) => (<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m6 8 4 4 4-4" /></svg>),
    Close: (p) => (<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m5 5 10 10M15 5 5 15" /></svg>),
    Play: (p) => (<svg viewBox="0 0 20 20" width="14" height="14" fill="currentColor" {...p}><path d="M6 4.5v11a.5.5 0 0 0 .77.42l8.4-5.5a.5.5 0 0 0 0-.84l-8.4-5.5A.5.5 0 0 0 6 4.5Z" /></svg>),
    Back: (p) => (<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M16 10H4m4 4-4-4 4-4" /></svg>),
    Info: (p) => (<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="10" cy="10" r="7" /><path d="M10 9v5M10 6.5v.01" /></svg>),
    Bot: (p) => (<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="4" y="7" width="12" height="9" rx="2.5" /><path d="M10 4v3M8 11v.01M12 11v.01M2 12h2M16 12h2" /></svg>),
    Check: (p) => (<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m5 10 3.5 3.5L15 7" /></svg>),
    Download: (p) => (<svg viewBox="0 0 20 20" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M10 3v10m0 0 4-4m-4 4-4-4M4 16h12" /></svg>),
};

// ---------- Formatters ----------
const fmtINR = (n, opts = {}) => {
    const { compact = false, decimals = 0 } = opts;
    if (n == null || isNaN(n)) return '—';
    if (compact) {
        if (Math.abs(n) >= 1e7) return `₹${(n / 1e7).toFixed(2)}Cr`;
        if (Math.abs(n) >= 1e5) return `₹${(n / 1e5).toFixed(2)}L`;
        if (Math.abs(n) >= 1e3) return `₹${(n / 1e3).toFixed(1)}K`;
    }
    return `₹${n.toLocaleString('en-IN', { maximumFractionDigits: decimals, minimumFractionDigits: decimals })}`;
};

const fmtDate = (d, short = false) => {
    if (!(d instanceof Date)) d = new Date(d);
    return d.toLocaleDateString('en-IN', short
        ? { day: '2-digit', month: 'short' }
        : { day: '2-digit', month: 'short', year: 'numeric' });
};

const fmtPct = (n, decimals = 2) => `${n >= 0 ? '+' : ''}${n.toFixed(decimals)}%`;

// ---------- Hint (hover-tooltip) ----------
// Renders a small info icon; on hover, shows a popover with the
// supplied content. The popup is portaled to document.body and
// positioned via fixed coords from getBoundingClientRect, so it
// escapes any overflow:hidden ancestor (e.g. the trades-table card
// that intentionally clips its inner scroll area).
function Hint({ children, width = 280 }) {
    const [open, setOpen] = React.useState(false);
    const [pos, setPos] = React.useState({ top: 0, left: 0, flip: false, anchorRight: false });
    const iconRef = React.useRef(null);

    const reposition = React.useCallback(() => {
        if (!iconRef.current) return;
        const rect = iconRef.current.getBoundingClientRect();
        // Estimate popup size — actual height varies with copy length
        // and the user's font settings, but 160px covers our tooltips.
        const estHeight = 160;
        const flip = rect.top < estHeight + 16; // below if no room above
        const anchorRight = rect.left + width + 16 > window.innerWidth;
        setPos({
            top: flip ? rect.bottom + 8 : rect.top - 8,
            left: anchorRight ? rect.right : rect.left,
            flip,
            anchorRight,
        });
    }, [width]);

    const onEnter = () => { reposition(); setOpen(true); };
    const onLeave = () => setOpen(false);

    return (
        <span ref={iconRef} className="hint"
            onMouseEnter={onEnter}
            onMouseLeave={onLeave}
            onFocus={onEnter}
            onBlur={onLeave}
            tabIndex={0}>
            <Icon.Info width="13" height="13" />
            {open && ReactDOM.createPortal(
                <span className={`hint-popup${pos.flip ? ' flipped' : ''}${pos.anchorRight ? ' anchor-right' : ''}`}
                    style={{
                        position: 'fixed',
                        top: pos.top,
                        left: pos.anchorRight ? 'auto' : pos.left,
                        right: pos.anchorRight ? (window.innerWidth - pos.left) : 'auto',
                        transform: pos.flip ? 'none' : 'translateY(-100%)',
                        width,
                    }}>
                    {children}
                </span>,
                document.body
            )}
        </span>
    );
}

// ---------- Strategy Picker ----------
function StrategyPicker({ strategies, value, onChange }) {
    const [open, setOpen] = React.useState(false);
    const ref = React.useRef(null);
    const selected = strategies.find((s) => s.id === value) || strategies[0];

    React.useEffect(() => {
        const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
        document.addEventListener('mousedown', onDoc);
        return () => document.removeEventListener('mousedown', onDoc);
    }, []);

    if (!selected) return null;

    return (
        <div ref={ref} style={{ position: 'relative' }}>
            <button
                type="button"
                onClick={() => setOpen((o) => !o)}
                style={{
                    width: '100%', textAlign: 'left',
                    display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                    padding: '13px 14px',
                    background: 'var(--surface)',
                    border: `1px solid ${open ? 'var(--accent)' : 'var(--border)'}`,
                    borderRadius: 'var(--radius)',
                    boxShadow: open ? '0 0 0 3px var(--accent-ring)' : 'var(--shadow-xs)',
                    cursor: 'pointer',
                    transition: 'all 160ms ease',
                    font: 'inherit', color: 'inherit',
                }}
            >
                <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                    <div style={{
                        width: 32, height: 32, borderRadius: 8,
                        background: 'var(--accent-soft)', color: 'var(--accent-text)',
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                        fontSize: 11.5, fontWeight: 600, letterSpacing: '0.02em',
                    }}>
                        {selected.name.split(' ').map((w) => w[0]).slice(0, 2).join('')}
                    </div>
                    <div>
                        <div style={{ fontSize: 14, fontWeight: 550, letterSpacing: '-0.006em' }}>{selected.name}</div>
                        <div style={{ fontSize: 11.5, color: 'var(--text-3)', marginTop: 2 }}>{selected.category} · {selected.complexity}</div>
                    </div>
                </div>
                <div style={{ color: 'var(--text-3)', transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 160ms ease' }}><Icon.Chevron /></div>
            </button>

            {open && (
                <div className="slide-up" style={{
                    position: 'absolute', top: 'calc(100% + 6px)', left: 0, right: 0,
                    background: 'var(--surface)',
                    border: '1px solid var(--border)',
                    borderRadius: 'var(--radius-lg)',
                    boxShadow: 'var(--shadow-lg)',
                    zIndex: 20,
                    maxHeight: 420, overflow: 'auto',
                    padding: 6,
                }}>
                    {strategies.map((s) => {
                        const active = s.id === value;
                        return (
                            <button key={s.id} type="button"
                                onClick={() => { onChange(s.id); setOpen(false); }}
                                style={{
                                    width: '100%', textAlign: 'left',
                                    display: 'flex', alignItems: 'center', gap: 12,
                                    padding: '11px 10px', border: 0,
                                    background: active ? 'var(--accent-softer)' : 'transparent',
                                    borderRadius: 8,
                                    cursor: 'pointer', font: 'inherit', color: 'inherit',
                                    transition: 'background 120ms ease',
                                }}
                                onMouseEnter={(e) => { if (!active) e.currentTarget.style.background = 'var(--surface-2)'; }}
                                onMouseLeave={(e) => { if (!active) e.currentTarget.style.background = 'transparent'; }}
                            >
                                <div style={{
                                    width: 28, height: 28, borderRadius: 7,
                                    background: active ? 'var(--accent)' : 'var(--surface-3)',
                                    color: active ? 'white' : 'var(--text-2)',
                                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                                    fontSize: 10, fontWeight: 600, flex: 'none',
                                    boxShadow: active ? 'var(--shadow-selected)' : 'none',
                                    transition: 'all 160ms ease',
                                }}>
                                    {active ? <Icon.Check /> : s.name.split(' ').map((w) => w[0]).slice(0, 2).join('')}
                                </div>
                                <div style={{ flex: 1, minWidth: 0 }}>
                                    <div style={{ fontSize: 13.5, fontWeight: 550, color: active ? 'var(--accent-text)' : 'var(--text)' }}>{s.name}</div>
                                    <div style={{ fontSize: 11.5, color: 'var(--text-3)', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                                        {s.short}
                                    </div>
                                </div>
                                <span className="pill" style={{ fontSize: 10.5, padding: '3px 7px', flex: 'none' }}>{s.complexity}</span>
                            </button>
                        );
                    })}
                </div>
            )}
        </div>
    );
}

// ---------- Strategy Details Modal ----------
function StrategyModal({ strategy, onClose }) {
    if (!strategy) return null;
    const s = strategy;
    return (
        <div className="modal-backdrop" onClick={onClose}>
            <div className="modal" onClick={(e) => e.stopPropagation()}>
                <div style={{ padding: '26px 30px 22px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
                    <div>
                        <div style={{ display: 'flex', gap: 8, marginBottom: 14 }}>
                            <span className="pill accent">{s.category}</span>
                            <span className="pill">{s.complexity}</span>
                        </div>
                        <h2 style={{ margin: 0, fontSize: 24, fontWeight: 600, letterSpacing: '-0.018em' }}>{s.name}</h2>
                        <p style={{ margin: '8px 0 0', color: 'var(--text-2)', fontSize: 14.5 }}>{s.short}</p>
                    </div>
                    <button className="btn ghost" onClick={onClose} style={{ padding: 8 }}><Icon.Close /></button>
                </div>
                <hr className="hr" />
                <div style={{ padding: '22px 30px 12px' }}>
                    <div className="label">How it works</div>
                    <p style={{ margin: 0, lineHeight: 1.65, fontSize: 14, color: 'var(--text)' }}>{s.description}</p>
                </div>
                <div style={{ padding: '22px 30px', display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
                    <MetricTile label="Historical win rate" value={`${s.metrics.winRate}%`} />
                    <MetricTile label="Trade frequency" value={s.metrics.trades} />
                    <MetricTile label="Horizon" value={s.metrics.horizon} />
                </div>
                <div style={{ padding: '0 30px 26px' }}>
                    <div style={{
                        background: 'var(--bg-2)', borderRadius: 10, padding: 14,
                        fontSize: 12.5, color: 'var(--text-2)', lineHeight: 1.55,
                        border: '1px solid var(--border)',
                    }}>
                        <strong style={{ color: 'var(--text)' }}>Note —</strong> Historical metrics are illustrative,
                        computed on NIFTY 200 constituents. Live performance will vary with market regime,
                        slippage, and position sizing.
                    </div>
                </div>
            </div>
        </div>
    );
}

function MetricTile({ label, value }) {
    return (
        <div style={{
            background: 'var(--bg-2)',
            border: '1px solid var(--border)',
            borderRadius: 10, padding: '12px 14px',
        }}>
            <div style={{ fontSize: 11, color: 'var(--text-3)', letterSpacing: '0.03em', textTransform: 'uppercase' }}>{label}</div>
            <div className="mono" style={{ fontSize: 16, fontWeight: 600, marginTop: 4, letterSpacing: '-0.01em' }}>{value}</div>
        </div>
    );
}

// ---------- Running Backtest overlay ----------
function BacktestRunning({ strategy, jobStatus }) {
    const steps = [
        'Fetching historical NSE data',
        'Computing indicators & signals',
        'Simulating trades with slippage',
        'Compiling portfolio metrics',
    ];

    // Drive a smooth client-side progress bar regardless of server polling
    // cadence — the server reports QUEUED → RUNNING → COMPLETED, but the
    // user wants to see continuous motion. The bar speeds toward each
    // milestone but never claims completion until the server says so.
    const [progress, setProgress] = React.useState(0);
    React.useEffect(() => {
        if (!jobStatus) return;
        const target = jobStatus === 'COMPLETED' ? 1
            : jobStatus === 'RUNNING' ? 0.92
            : jobStatus === 'QUEUED' ? 0.18
            : 0.5;
        const interval = setInterval(() => {
            setProgress((p) => {
                if (p >= target) return p;
                return Math.min(target, p + 0.012);
            });
        }, 60);
        return () => clearInterval(interval);
    }, [jobStatus]);

    const step = Math.min(steps.length - 1, Math.floor(progress * steps.length));

    return (
        <div style={{
            position: 'fixed', inset: 0,
            background: 'oklch(0.965 0.016 80 / 0.78)',
            backdropFilter: 'blur(10px)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            zIndex: 50,
            animation: 'fade-in 200ms ease-out both',
        }}>
            <div style={{
                width: 440, background: 'var(--surface)',
                border: '1px solid var(--border)',
                borderRadius: 'var(--radius-xl)',
                boxShadow: 'var(--shadow-lg)',
                padding: 30,
            }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 20 }}>
                    <div style={{
                        width: 40, height: 40, borderRadius: 10,
                        background: 'var(--accent)', color: 'white',
                        display: 'flex', alignItems: 'center', justifyContent: 'center',
                        boxShadow: 'var(--shadow-selected)',
                    }}>
                        <Icon.Bot />
                    </div>
                    <div>
                        <div style={{ fontSize: 12.5, color: 'var(--text-3)', letterSpacing: '0.02em', textTransform: 'uppercase' }}>Running backtest</div>
                        <div style={{ fontSize: 16, fontWeight: 600, color: 'var(--text)', marginTop: 2 }}>{strategy?.name || 'Strategy'}</div>
                    </div>
                </div>

                <div style={{ height: 6, background: 'var(--surface-3)', borderRadius: 999, overflow: 'hidden', marginBottom: 24 }}>
                    <div style={{
                        width: `${progress * 100}%`, height: '100%',
                        background: 'var(--accent)',
                        borderRadius: 999,
                        transition: 'width 100ms linear',
                    }} />
                </div>

                <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                    {steps.map((label, i) => {
                        const done = i < step;
                        const active = i === step;
                        return (
                            <div key={i} style={{
                                display: 'flex', alignItems: 'center', gap: 12,
                                opacity: active || done ? 1 : 0.42,
                                transition: 'opacity 200ms ease',
                            }}>
                                <div style={{
                                    width: 20, height: 20, borderRadius: '50%',
                                    background: done ? 'var(--accent)' : active ? 'var(--accent-soft)' : 'var(--surface-3)',
                                    color: done ? 'white' : 'var(--accent)',
                                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                                    fontSize: 10,
                                    transition: 'all 200ms ease',
                                    boxShadow: done ? 'var(--shadow-sm)' : 'none',
                                }}>
                                    {done ? <Icon.Check /> : active ? <span className="dots" style={{ transform: 'scale(0.55)' }}><span /><span /><span /></span> : ''}
                                </div>
                                <div style={{
                                    fontSize: 13.5,
                                    color: active ? 'var(--text)' : done ? 'var(--text-2)' : 'var(--text-3)',
                                    fontWeight: active ? 550 : 400,
                                }}>
                                    {label}
                                </div>
                            </div>
                        );
                    })}
                </div>
            </div>
        </div>
    );
}

// ---------- KPI Tile ----------
function KPITile({ label, value, delta, deltaLabel, good, highlight, hint }) {
    const up = good === 'up';
    const down = good === 'down';
    return (
        <div className="card" style={{
            padding: '18px 20px',
            background: highlight ? 'var(--accent-softer)' : 'var(--surface)',
            borderColor: highlight ? 'var(--accent)' : 'var(--border)',
            boxShadow: highlight ? 'var(--shadow-selected)' : 'var(--shadow-xs)',
        }}>
            <div style={{
                display: 'flex', alignItems: 'center', gap: 6,
                fontSize: 11.5, color: 'var(--text-3)', letterSpacing: '0.03em',
                textTransform: 'uppercase', fontWeight: 500,
            }}>
                {label}
                {hint && <Hint>{hint}</Hint>}
            </div>
            <div className="mono" style={{
                fontSize: 26, fontWeight: 600, marginTop: 10, letterSpacing: '-0.02em', lineHeight: 1,
                color: highlight ? 'var(--accent-text)' : 'var(--text)',
            }}>
                {value}
            </div>
            {delta != null && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginTop: 12 }}>
                    <span className={`pill ${up ? 'up' : down ? 'down' : ''}`} style={{ padding: '3px 7px', fontSize: 11 }}>
                        {delta}
                    </span>
                    {deltaLabel && <span style={{ fontSize: 11.5, color: 'var(--text-3)' }}>{deltaLabel}</span>}
                </div>
            )}
        </div>
    );
}

window.UI = { Icon, fmtINR, fmtDate, fmtPct, StrategyPicker, StrategyModal, MetricTile, BacktestRunning, KPITile, Hint };
