// =========================================================================
// KALASUTRA V3 — VIMSHOTTARI DASHA ENGINE (5-fold)
// Same math as your v2 backtest.js renderDashaTree(), extracted from the
// HTML-building code into pure data functions so background.js can call
// it silently every tick, and the side panel can render a full 120-year
// tree on demand.
// =========================================================================

import { DASHA_LORDS, DASHA_YEARS, jdToDateString, getHouseSignifications } from './kp-core.js';

const LEVEL_TAGS = ['MD', 'AD', 'PD', 'SD', 'PRD']; // Maha / Antar / Pratyantar / Sookshma / Prana

function dashaStart(jd_birth, moonLong) {
    const nak = moonLong / (360 / 27);
    const nakIdx = Math.floor(nak);
    const startLordIdx = nakIdx % 9;
    const fractionLeft = 1 - (nak - nakIdx);
    const fullMdStartJd = jd_birth - ((1 - fractionLeft) * DASHA_YEARS[startLordIdx] * 365.2425);
    return { startLordIdx, fullMdStartJd };
}

/**
 * Finds the currently active dasha lord at every one of the 5 levels for a
 * given target JD, WITHOUT building the full 120-year tree — descends only
 * the live branch at each level. Cheap enough to call every 30s in background.js.
 * Returns: [{ level:'MD', lord:'Ju', startJd, endJd }, ... x5]
 */
export function findActiveDasha(jd_birth, moonLong, targetJd) {
    const { startLordIdx, fullMdStartJd } = dashaStart(jd_birth, moonLong);
    const path = [];
    let levelStartIdx = startLordIdx;
    let levelStartJd = fullMdStartJd;
    let levelDur = DASHA_YEARS[startLordIdx] * 365.2425; // MD duration in days

    for (let level = 0; level < 5; level++) {
        let cursor = levelStartJd;
        let found = null;
        for (let i = 0; i < 9; i++) {
            const idx = (levelStartIdx + i) % 9;
            const dur = (level === 0) ? DASHA_YEARS[idx] * 365.2425 : levelDur * (DASHA_YEARS[idx] / 120);
            const end = cursor + dur;
            if (targetJd < end || i === 8) { // last iteration always closes the loop
                found = { idx, start: cursor, end, dur };
                break;
            }
            cursor = end;
        }
        if (!found) break;
        path.push({ level: LEVEL_TAGS[level], lord: DASHA_LORDS[found.idx], startJd: found.start, endJd: found.end });
        levelStartIdx = found.idx;
        levelStartJd = found.start;
        levelDur = found.dur;
    }
    return path;
}

/**
 * Builds the full 5-level, 120-year dasha tree as nested plain data
 * (for the side panel's expandable tree view). cusps/planets optional —
 * pass the current KP transitData.cusps/planets to attach house
 * significations to each dasha lord.
 */
export function generateDashaTree(jd_birth, moonLong, cusps = null, planets = null) {
    const { startLordIdx, fullMdStartJd } = dashaStart(jd_birth, moonLong);
    const sigOf = (lord) => (cusps && planets) ? getHouseSignifications(lord, cusps, planets).str : "-";

    const tree = [];
    let currentMdStartJd = fullMdStartJd;
    for (let m = 0; m < 9; m++) {
        const mdIdx = (startLordIdx + m) % 9;
        const mdDur = DASHA_YEARS[mdIdx] * 365.2425;
        const mdEndJd = currentMdStartJd + mdDur;
        const mdNode = { lord: DASHA_LORDS[mdIdx], start: jdToDateString(Math.max(currentMdStartJd, jd_birth)), end: jdToDateString(mdEndJd), sig: sigOf(DASHA_LORDS[mdIdx]), children: [] };

        let currentAdStartJd = currentMdStartJd;
        for (let a = 0; a < 9; a++) {
            const adIdx = (mdIdx + a) % 9;
            const adDur = mdDur * (DASHA_YEARS[adIdx] / 120);
            const adEndJd = currentAdStartJd + adDur;
            if (adEndJd > jd_birth) {
                const adNode = { lord: DASHA_LORDS[adIdx], start: jdToDateString(Math.max(currentAdStartJd, jd_birth)), end: jdToDateString(adEndJd), sig: sigOf(DASHA_LORDS[adIdx]), children: [] };

                let currentPdStartJd = currentAdStartJd;
                for (let p = 0; p < 9; p++) {
                    const pdIdx = (adIdx + p) % 9;
                    const pdDur = adDur * (DASHA_YEARS[pdIdx] / 120);
                    const pdEndJd = currentPdStartJd + pdDur;
                    if (pdEndJd > jd_birth) {
                        const pdNode = { lord: DASHA_LORDS[pdIdx], start: jdToDateString(Math.max(currentPdStartJd, jd_birth)), end: jdToDateString(pdEndJd), sig: sigOf(DASHA_LORDS[pdIdx]), children: [] };

                        let currentSdStartJd = currentPdStartJd;
                        for (let s = 0; s < 9; s++) {
                            const sdIdx = (pdIdx + s) % 9;
                            const sdDur = pdDur * (DASHA_YEARS[sdIdx] / 120);
                            const sdEndJd = currentSdStartJd + sdDur;
                            if (sdEndJd > jd_birth) {
                                pdNode.children.push({
                                    lord: DASHA_LORDS[sdIdx],
                                    start: jdToDateString(Math.max(currentSdStartJd, jd_birth)),
                                    end: jdToDateString(sdEndJd),
                                    sig: sigOf(DASHA_LORDS[sdIdx]),
                                    // Raw values needed to compute this node's 5th-level (Prana Dasha)
                                    // children on demand via generatePRDChildren() — not pre-expanded
                                    // here because a full 9^5-node eager tree (~59,000 leaves) would be
                                    // far too heavy to compute/serialize/render up front.
                                    _startJd: currentSdStartJd, _durDays: sdDur, _idx: sdIdx
                                });
                            }
                            currentSdStartJd = sdEndJd;
                        }
                        adNode.children.push(pdNode);
                    }
                    currentPdStartJd = pdEndJd;
                }
                mdNode.children.push(adNode);
            }
            currentAdStartJd = adEndJd;
        }
        tree.push(mdNode);
        currentMdStartJd = mdEndJd;
    }
    return tree;
}

/**
 * Computes just the 9 Prana Dasha (5th level, PRD) entries for ONE given
 * Sookshma Dasha (4th level, SD) span — called lazily when the UI expands
 * that SD node, instead of pre-building all 9^5 leaves for the whole tree.
 * @param {number} sdStartJd  the SD node's own _startJd (from generateDashaTree)
 * @param {number} sdDurDays  the SD node's own _durDays
 * @param {number} sdIdx      the SD node's own _idx (0-8, index into DASHA_LORDS)
 */
export function generatePRDChildren(sdStartJd, sdDurDays, sdIdx, jd_birth, cusps = null, planets = null) {
    const sigOf = (lord) => (cusps && planets) ? getHouseSignifications(lord, cusps, planets).str : "-";
    const children = [];
    let cursor = sdStartJd;
    for (let i = 0; i < 9; i++) {
        const idx = (sdIdx + i) % 9;
        const dur = sdDurDays * (DASHA_YEARS[idx] / 120);
        const end = cursor + dur;
        if (end > jd_birth) {
            children.push({ lord: DASHA_LORDS[idx], start: jdToDateString(Math.max(cursor, jd_birth)), end: jdToDateString(end), sig: sigOf(DASHA_LORDS[idx]) });
        }
        cursor = end;
    }
    return children;
}
