/* ============================================================
   Matrix — Echoes Section (Phase 6c)
   
   Technomancer-only. Shown below Sprites in the Matrix tab.
   Uses EntityPicker for browsing the full list of 17 echoes,
   filtered by CRB vs. splatbook source.
   ============================================================ */
const { useState, useEffect, useRef, useMemo, useCallback, Fragment } = React;

window.EchoesSection = function EchoesSection({ character, onChange }) {
    const C = SR5_CALC;
    const M = SR5_MATRIX;

    const [pickerOpen, setPickerOpen] = useState(false);
    const echoes = C.characterEchoes(character);
    const bonuses = C.echoStatBonuses(character);

    const inCareer = C.isCareerMode(character);
    const pendingEchoes = inCareer ? C.pendingNewEchoes(character) : [];
    const earned = C.echoesEarned(character);
    const available = C.echoesAvailable(character);

    const hasBonus = bonuses.attack || bonuses.sleaze || bonuses.dataProcessing || bonuses.firewall;

    function onPick(tpl, opts) {
        if (inCareer) {
            if (available < 1) {
                alert(`No echo slots available. Submerge to a higher grade to earn more.`);
                return;
            }
            onChange(C.stagePendingNewEcho(character, tpl.key, opts || {}));
        } else {
            /* Creation-mode echoes shouldn't exist per RAW (can't submerge at
               creation) but the app doesn't currently block it — preserve
               that for backward compatibility. Future cleanup candidate. */
            onChange(C.addEchoFromTemplate(character, tpl.key, opts || {}));
        }
        setPickerOpen(false);
    }
    function onRemove(id) {
        if (inCareer) { alert("Committed echoes are permanent — they can't be unlearned in career mode."); return; }
        onChange(C.removeEcho(character, id));
    }
    function onUnstage(tempId) {
        onChange(C.unstagePendingNewEcho(character, tempId));
    }
    function onUpdateNotes(id, notes) {
        if (inCareer) return;
        onChange(C.updateEcho(character, id, { notes }));
    }
    function onUpdateSelection(id, selection) {
        if (inCareer) return;
        onChange(C.updateEcho(character, id, { selection }));
    }

    const browseDisabled = inCareer && available < 1 && pendingEchoes.length === 0;
    const browseTooltip = browseDisabled
        ? 'No echo slots available — submerge to a higher grade first.'
        : (inCareer ? `${available} echo slot${available === 1 ? '' : 's'} available` : 'Browse all echoes');

    return (
        <>
            <div className="card" style={{ marginTop: 12 }}>
                <div className="card-header">
                    <h3 className="card-title">Echoes</h3>
                    <div className="card-actions">
                        <span className="muted" style={{ fontSize: 12 }}>
                            {echoes.length} taken{pendingEchoes.length > 0 ? ` + ${pendingEchoes.length} pending` : ''}
                            {inCareer && (
                                <span className="muted" style={{ marginLeft: 6 }}>
                                    · {available} slot{available === 1 ? '' : 's'} available
                                </span>
                            )}
                            {hasBonus && (
                                <span className="accent" style={{ marginLeft: 8 }}>
                                    (+{bonuses.attack || 0}A +{bonuses.sleaze || 0}S +{bonuses.dataProcessing || 0}D +{bonuses.firewall || 0}F)
                                </span>
                            )}
                        </span>
                        <button className="btn btn-primary"
                                onClick={() => setPickerOpen(true)}
                                disabled={browseDisabled}
                                title={browseTooltip}>
                            + Browse Echoes
                        </button>
                    </div>
                </div>
                <div className="card-body" style={{ padding: 0 }}>
                    {echoes.length === 0 && pendingEchoes.length === 0 ? (
                        <div className="spell-empty">
                            No echoes learned yet. Echoes are technomancer metamagics gained by submerging —
                            they enhance your Living Persona or grant new Matrix tricks. Some can be taken multiple
                            times. Most are from the Core Rulebook; a few are from Data Trails.
                            {inCareer && available < 1 && ' Submerge first to earn an echo slot.'}
                        </div>
                    ) : (
                        <>
                            <div className="echo-head">
                                <span>Name</span>
                                <span>Effect</span>
                                <span>Source</span>
                                <span></span>
                            </div>
                            {echoes.map(e => {
                                const tpl = M.findEcho(e.key);
                                if (!tpl) return null;
                                const isDataTrails = tpl.source.startsWith('DT');
                                return (
                                    <div key={e.id} className={`echo-row ${isDataTrails ? 'echo-splat' : 'echo-core'}`}>
                                        <div className="echo-name">
                                            {tpl.name}
                                            {e.selection && (
                                                <span className="echo-selection mono">({e.selection})</span>
                                            )}
                                            {tpl.submersionRequired && (
                                                <span className="linked-badge">submersion</span>
                                            )}
                                        </div>
                                        <div className="echo-summary">{tpl.summary}</div>
                                        <div className="echo-source mono">{tpl.source}</div>
                                        <button className="btn-row-remove"
                                                onClick={() => onRemove(e.id)}
                                                title={inCareer ? "Echoes are permanent in career mode" : "Remove"}>×</button>
                                        {tpl.requiresSelection === 'program_name' && (
                                            <div className="echo-extra">
                                                <span className="muted mono">Program:</span>
                                                <TextInput
                                                    value={e.selection || ''}
                                                    onChange={v => onUpdateSelection(e.id, v)}
                                                    placeholder="e.g. Stealth, Exploit, Armor"
                                                    maxLength={40}
                                                    disabled={inCareer}
                                                />
                                            </div>
                                        )}
                                        <div className="echo-description">{tpl.description}</div>
                                    </div>
                                );
                            })}
                            {pendingEchoes.map(pe => {
                                const tpl = M.findEcho(pe.key);
                                if (!tpl) return null;
                                return (
                                    <div key={pe.tempId} className="echo-row pending-new">
                                        <div className="echo-name">
                                            {tpl.name}
                                            {pe.selection && (
                                                <span className="echo-selection mono">({pe.selection})</span>
                                            )}
                                            <span className="gear-pending-tag">pending</span>
                                        </div>
                                        <div className="echo-summary">{tpl.summary}</div>
                                        <div className="echo-source mono">{tpl.source}</div>
                                        <button className="btn-row-remove"
                                                onClick={() => onUnstage(pe.tempId)}
                                                title="Discard pending echo">×</button>
                                        <div className="echo-description">{tpl.description}</div>
                                    </div>
                                );
                            })}
                        </>
                    )}
                </div>
            </div>

            {pickerOpen && (
                <EchoPickerModal
                    character={character}
                    onPick={onPick}
                    onClose={() => setPickerOpen(false)}
                />
            )}
        </>
    );
};

/* ============================================================
   EchoPickerModal — browse all 17 echoes via EntityPicker
   ============================================================ */
window.EchoPickerModal = function EchoPickerModal({ character, onPick, onClose }) {
    const M = SR5_MATRIX;
    const C = SR5_CALC;

    const [selectionByKey, setSelectionByKey] = useState({});

    /* Filter chips: Core vs Data Trails */
    const filters = [
        { key: 'core',        label: 'Core Rulebook' },
        { key: 'data_trails', label: 'Data Trails' },
    ];

    return (
        <EntityPicker
            title="Browse Echoes"
            items={M.ECHOES}
            getItemKey={e => e.key}
            filters={filters}
            filterBy={(e, query, activeFilter) => {
                if (activeFilter === 'core' && !e.source.startsWith('CRB')) return false;
                if (activeFilter === 'data_trails' && !e.source.startsWith('DT')) return false;
                if (query) {
                    const q = query.toLowerCase();
                    const blob = (e.name + ' ' + e.summary + ' ' + e.description).toLowerCase();
                    if (!blob.includes(q)) return false;
                }
                return true;
            }}
            isAlreadyTaken={(e) => {
                const can = C.canTakeEcho(character, e.key);
                return !can.canTake;
            }}
            itemRenderer={(e, { selected, onClick }) => {
                const can = C.canTakeEcho(character, e.key);
                const taken = C.echoTakenCount(character, e.key);
                return (
                    <div key={e.key}
                         className={`picker-item ${selected ? 'selected' : ''} ${!can.canTake ? 'already-taken' : ''}`}
                         onClick={onClick}>
                        <span className="pi-name">{e.name}</span>
                        <span className="pi-cost">{e.source.startsWith('CRB') ? 'Core' : 'DT'}</span>
                        <div className="pi-meta">
                            {e.summary}
                            {taken > 0 && <span className="muted"> · taken {taken}×</span>}
                        </div>
                    </div>
                );
            }}
            renderDetails={(e) => {
                const can = C.canTakeEcho(character, e.key);
                const needsSelection = e.requiresSelection === 'program_name';
                const selection = selectionByKey[e.key] || '';
                return (
                    <>
                        <h3 className="picker-details-title">{e.name}</h3>
                        <div className="weapon-stat-grid">
                            <div className="ws"><span className="ws-label">Source</span><span className="ws-value">{e.source}</span></div>
                            <div className="ws">
                                <span className="ws-label">Max takes</span>
                                <span className="ws-value">
                                    {e.repeatable ? 'unlimited (different program each time)'
                                                  : (e.takes || 1)}
                                </span>
                            </div>
                            {e.submersionRequired && (
                                <div className="ws" style={{ gridColumn: '1 / -1' }}>
                                    <span className="ws-label">Prerequisite</span>
                                    <span className="ws-value" style={{ color: 'var(--accent)' }}>Must have submerged at least once</span>
                                </div>
                            )}
                        </div>

                        <div className="picker-details-section">
                            <div className="picker-details-label">Effect</div>
                            <div className="picker-details-text">{e.description}</div>
                        </div>

                        {e.modifies && (
                            <div className="picker-details-section">
                                <div className="picker-details-label">Persona stat bonus</div>
                                <div className="picker-details-text">
                                    {Object.entries(e.modifies).map(([k, v]) => {
                                        const label = { attack: 'Attack', sleaze: 'Sleaze',
                                                        dataProcessing: 'Data Processing', firewall: 'Firewall' }[k];
                                        return `+${v} ${label}`;
                                    }).join(', ')} per time taken
                                </div>
                            </div>
                        )}

                        {needsSelection && (
                            <div className="picker-details-section">
                                <div className="picker-details-label">Program name</div>
                                <TextInput
                                    value={selection}
                                    onChange={v => setSelectionByKey(s => ({ ...s, [e.key]: v }))}
                                    placeholder="e.g. Stealth, Exploit, Armor"
                                    maxLength={40}
                                />
                                <div className="muted" style={{ fontSize: 11, marginTop: 6 }}>
                                    Each instance of Resonance [Program] must mimic a different common or hacking program.
                                </div>
                            </div>
                        )}

                        {!can.canTake && (
                            <div className="picker-details-section">
                                <div className="picker-details-label" style={{ color: 'var(--bad)' }}>Unavailable</div>
                                <div className="picker-details-text muted">{can.reason}</div>
                            </div>
                        )}
                    </>
                );
            }}
            onPick={(e) => {
                const opts = {};
                if (e.requiresSelection === 'program_name') {
                    opts.selection = selectionByKey[e.key] || '';
                }
                onPick(e, opts);
            }}
            onClose={onClose}
        />
    );
};
