/* ============================================================
   Skills — Knowledge Skills Card
   Extracted from components.jsx via split.py.
   Each component reaches React hooks via window.React.
   ============================================================ */
const { useState, useEffect, useRef, useMemo, useCallback, Fragment } = React;


/* ------------------------------------------------------------
   KnowledgeSkillsCard — Phase 2.75
   
   Freeform knowledge/language skills with their own point pool = (INT+LOG)×2.
   Users add rows rather than choosing from a list. Categories determine the
   linked attribute. One native language is standard; Bilingual (later phase)
   can unlock a second.
   ------------------------------------------------------------ */
window.KnowledgeSkillsCard = function KnowledgeSkillsCard({ character, onChange }) {
    const D = SR5_DATA;
    const C = SR5_CALC;

    const inCareer = C.isCareerMode(character);
    const karmaAvailable = inCareer ? C.karmaCurrent(character) : 0;
    const karmaRemaining = inCareer ? karmaAvailable - C.pendingKarmaDelta(character) : 0;

    const total = C.knowledgePointsTotal(character);
    const spent = C.knowledgePointsSpent(character);
    const rows = C.knowledgeSkills(character);
    const pendingNewKnow = inCareer ? (C.pendingChanges(character).newKnowledge || []) : [];
    const pendingKnowDeltas = inCareer ? (C.pendingChanges(character).knowledgeDeltas || {}) : {};

    const natives = rows.filter(r => r.native);
    const languages = rows.filter(r => r.category === 'language' && !r.native);
    const knowledges = rows.filter(r => r.category !== 'language');

    /* Creation handlers */
    function addKnowledge(category) {
        onChange(C.addKnowledgeSkill(character, category));
    }
    function addLanguage() {
        onChange(C.addKnowledgeSkill(character, 'language'));
    }
    function addNative() {
        onChange(C.addNativeLanguage(character, ''));
    }
    function update(id, patch) {
        onChange(C.updateKnowledgeSkill(character, id, patch));
    }
    function remove(id) {
        onChange(C.removeKnowledgeSkill(character, id));
    }

    /* Career handlers */
    function stageNewKnowledge(category) {
        const name = prompt(`Name for this new knowledge skill (2 karma, starts at rating 1):`, '');
        if (!name || !name.trim()) return;
        onChange(C.stagePendingNewKnowledge(character, { name: name.trim(), category }));
    }
    function unstageNewKnowledge(id) {
        onChange(C.unstagePendingNewKnowledge(character, id));
    }
    function raiseKnowledge(id, newRating) {
        onChange(C.stagePendingKnowledgeDelta(character, id, newRating));
    }

    /* Render a committed row. In career mode, name/category/spec/delete
       are read-only; only the rating stepper works (staged). */
    function renderRow(k) {
        const isLanguage = k.category === 'language';
        const categoryDef = isLanguage
            ? D.LANGUAGE_CATEGORY
            : D.KNOWLEDGE_CATEGORIES.find(c => c.key === k.category);
        const linkedAttrAbbr = D.ATTRIBUTES.find(a => a.key === categoryDef?.attr)?.abbr || '';
        const pool = C.knowledgeDicePool(character, k);
        const poolBase = C.knowledgeDicePoolBase(character, k);
        const hasSpec = !!(k.specialization && k.specialization.trim());

        /* Career: projected rating from pending delta */
        const committedRating = k.rating || 0;
        const pendingDelta = pendingKnowDeltas[k.id];
        const rating = (inCareer && pendingDelta) ? pendingDelta.newRating : committedRating;
        const hasPending = inCareer && pendingDelta;

        /* Career raise-affordability check */
        let canInc, canDec, incTitle;
        if (inCareer && !k.native) {
            const nextRating = rating + 1;
            let stepCumulative = 0;
            for (let r = committedRating + 1; r <= nextRating; r++) stepCumulative += C.karmaCostKnowledgeRaise(r);
            const alreadyStaged = pendingDelta?.karmaCost || 0;
            const totalIfIncreased = (C.pendingKarmaDelta(character) - alreadyStaged) + stepCumulative;
            canInc = rating < 6 && totalIfIncreased <= karmaAvailable;
            canDec = rating > committedRating;
            if (!canInc && rating < 6) incTitle = 'Not enough karma';
        } else if (k.native) {
            canInc = false;
            canDec = false;
        } else {
            /* Phase 16 — creation mode: allow karma spillover when
               knowledge-points budget is exhausted. */
            canInc = rating < 6;
            canDec = rating > 0;
            if (spent >= total) {
                const kt = C.karmaTotals(character);
                const nextRating = rating + 1;
                const costOfNext = C.karmaCostKnowledgeRaise(nextRating);
                if (kt.remaining < costOfNext) {
                    canInc = false;
                    incTitle = `Needs ${costOfNext} karma (have ${kt.remaining})`;
                }
            }
        }

        /* In career mode, disable name/category/spec/delete on committed entries. */
        const readonlyInCareer = inCareer;

        return (
            <div className={`knowledge-row ${k.native ? 'native' : ''} ${hasPending ? 'pending' : ''}`} key={k.id}>
                {k.native ? (
                    <span className="knowledge-native-badge" title="Native language — always known, rated 6 equivalent">Native Lang</span>
                ) : (
                    <select
                        className="knowledge-cat-select"
                        value={k.category}
                        onChange={e => update(k.id, { category: e.target.value })}
                        disabled={readonlyInCareer}
                        title="Category determines the linked attribute"
                    >
                        {D.KNOWLEDGE_CATEGORIES.map(c => (
                            <option key={c.key} value={c.key}>{c.label}</option>
                        ))}
                        <option value="language">Language</option>
                    </select>
                )}

                <input
                    className="knowledge-name-input"
                    type="text"
                    value={k.name}
                    onChange={e => update(k.id, { name: e.target.value })}
                    disabled={readonlyInCareer}
                    placeholder={k.native ? 'e.g. English' : (categoryDef?.hint || 'name…')}
                    list={isLanguage ? 'lang-suggestions' : undefined}
                    maxLength={60}
                />

                {k.native ? (
                    <span className="mono muted" style={{ fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase' }}>
                        free
                    </span>
                ) : (
                    <div className="skill-rating-stepper">
                        <button className="stepper-btn" style={{ width: 22, height: 22, fontSize: 13 }}
                                onClick={() => inCareer ? raiseKnowledge(k.id, rating - 1) : update(k.id, { rating: Math.max(0, rating - 1) })}
                                disabled={!canDec}>−</button>
                        <span className={`skill-rating-value ${hasPending ? 'pending-value' : ''}`}
                              style={{ fontSize: 14, minWidth: 20 }}>{rating}</span>
                        <button className="stepper-btn" style={{ width: 22, height: 22, fontSize: 13 }}
                                onClick={() => inCareer ? raiseKnowledge(k.id, rating + 1) : update(k.id, { rating: Math.min(6, rating + 1) })}
                                disabled={!canInc} title={incTitle}>+</button>
                    </div>
                )}

                <div style={{ textAlign: 'right' }}>
                    {hasSpec && !k.native && rating >= 1 ? (
                        <div className="dice-pool-with-spec">
                            <span className="base">{poolBase}</span>
                            <span className="with-spec">{pool}</span>
                        </div>
                    ) : (
                        <div className={`dice-pool ${pool === 0 ? 'zero' : ''}`}>
                            {pool === 0 ? '—' : pool}
                            {linkedAttrAbbr && pool > 0 && (
                                <span className="muted" style={{ fontSize: 9, letterSpacing: '0.1em', marginLeft: 4 }}>
                                    {linkedAttrAbbr}
                                </span>
                            )}
                        </div>
                    )}
                </div>

                <input
                    className={`spec-input ${hasSpec ? 'has-value' : ''}`}
                    type="text"
                    value={k.specialization || ''}
                    disabled={k.native || rating === 0 || readonlyInCareer}
                    onChange={e => update(k.id, { specialization: e.target.value })}
                    placeholder={k.native ? '—' : 'spec +2…'}
                    maxLength={40}
                    title={k.native ? "Natives don't take specializations"
                         : readonlyInCareer ? 'Spec edits deferred in career mode'
                         : 'Optional specialization, costs 1 point, adds +2 dice'}
                />

                <button className="knowledge-remove-btn"
                        onClick={() => { if (confirm(`Remove ${k.name || 'this row'}?`)) remove(k.id); }}
                        disabled={readonlyInCareer}
                        title={readonlyInCareer ? "Can't remove committed entries in career mode" : 'Remove this row'}>×</button>
            </div>
        );
    }

    /* Render a pending new-knowledge entry (career mode only). */
    function renderPendingNewRow(add) {
        const categoryDef = D.KNOWLEDGE_CATEGORIES.find(c => c.key === add.category);
        return (
            <div className="knowledge-row pending" key={add.id}>
                <span className="knowledge-native-badge" style={{ background: 'rgba(240, 168, 66, 0.1)', color: 'var(--accent)' }}>
                    Pending New
                </span>
                <div className="knowledge-name-input" style={{ padding: '6px 10px', fontSize: 12, color: 'var(--accent)' }}>
                    {add.name}
                </div>
                <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>
                    {categoryDef?.label || add.category} @ rating {add.rating}
                </div>
                <div style={{ textAlign: 'right', fontSize: 11, color: 'var(--accent)' }}>
                    {add.karmaCost} karma
                </div>
                <div />
                <button className="knowledge-remove-btn"
                        onClick={() => unstageNewKnowledge(add.id)}
                        title="Discard this pending new knowledge skill">×</button>
            </div>
        );
    }

    return (
        <div className="card" style={{ marginTop: 20 }}>
            <div className="card-header">
                <h3 className="card-title">Knowledge &amp; Language</h3>
                <div className="card-header-right">
                    {inCareer ? (
                        <span className="points-chip" title="Karma available">
                            <span className="pc-label">karma</span>
                            <span className="pc-value">{karmaRemaining} / {karmaAvailable}</span>
                        </span>
                    ) : (
                        <PointsChip label="free pts" spent={spent} total={total} />
                    )}
                </div>
            </div>

            {natives.length > 0 && (
                <>
                    <div className="knowledge-section-label">
                        <span>Native Languages</span>
                        <span className="hint">free — rating N (treated as 6 in rolls)</span>
                    </div>
                    {natives.map(renderRow)}
                </>
            )}

            {languages.length > 0 && (
                <>
                    <div className="knowledge-section-label">
                        <span>Languages</span>
                        <span className="hint">linked to INT, not defaultable</span>
                    </div>
                    {languages.map(renderRow)}
                </>
            )}

            {knowledges.length > 0 && (
                <>
                    <div className="knowledge-section-label">
                        <span>Knowledge</span>
                        <span className="hint">Academic/Professional → LOG · Street/Interests → INT</span>
                    </div>
                    {knowledges.map(renderRow)}
                </>
            )}

            {/* Pending new knowledge (career mode only) */}
            {pendingNewKnow.length > 0 && (
                <>
                    <div className="knowledge-section-label">
                        <span>Pending New Entries</span>
                        <span className="hint">not committed yet — 2 karma each on commit</span>
                    </div>
                    {pendingNewKnow.map(renderPendingNewRow)}
                </>
            )}

            {rows.length === 0 && !inCareer && (
                <div className="card-body muted" style={{ fontSize: 13, paddingTop: 20, paddingBottom: 16 }}>
                    No knowledge or language skills yet. Add rows below to define what your runner knows beyond the active skill list.
                    Free points available: <strong className="accent">{total}</strong> (based on INT + LOG × 2).
                </div>
            )}

            {/* Add-row controls */}
            <div className="knowledge-add-row">
                {!inCareer && natives.length < C.freeNativeLanguages(character) && (
                    <button className="add-button" onClick={addNative}
                            title={`You have ${C.freeNativeLanguages(character)} free native language${C.freeNativeLanguages(character) === 1 ? '' : 's'}${C.freeNativeLanguages(character) > 1 ? ' (Bilingual)' : ''}`}>
                        <span className="plus-icon">+</span>Native Language
                        {natives.length > 0 && ` (${natives.length}/${C.freeNativeLanguages(character)})`}
                    </button>
                )}
                {inCareer ? (
                    <>
                        {D.KNOWLEDGE_CATEGORIES.map(cat => (
                            <button key={cat.key} className="add-button" onClick={() => stageNewKnowledge(cat.key)}
                                    disabled={C.pendingKarmaDelta(character) + C.KARMA_COST_NEW_KNOWLEDGE > karmaAvailable}
                                    title={`Add new ${cat.label} knowledge skill (2 karma, staged pending)`}>
                                <span className="plus-icon">+</span>{cat.label}
                            </button>
                        ))}
                    </>
                ) : (
                    <>
                        {D.KNOWLEDGE_CATEGORIES.map(cat => (
                            <button key={cat.key} className="add-button" onClick={() => addKnowledge(cat.key)}
                                    title={cat.hint}>
                                <span className="plus-icon">+</span>{cat.label}
                            </button>
                        ))}
                        <button className="add-button" onClick={addLanguage}>
                            <span className="plus-icon">+</span>Language
                        </button>
                    </>
                )}
            </div>

            <datalist id="lang-suggestions">
                {D.COMMON_LANGUAGES.map(l => <option key={l} value={l} />)}
            </datalist>
        </div>
    );
};
