// =========================================================================
// KALASUTRA V3 — SBC (SARVATOBHADRA CHAKRA) ENGINE
// Ported from sbc_engine.py — this is the newer/more complete version
// (directional Sammukha/Vama/Dakshina vedha classification + pada corner
// diagonals) so it supersedes the older sbc_vedha_engine.js you had.
// =========================================================================

export const OUTER_NAKSHATRAS = {
    "Krittika": [0, 1], "Rohini": [0, 2], "Mrigashira": [0, 3], "Ardra": [0, 4],
    "Punarvasu": [0, 5], "Pushya": [0, 6], "Ashlesha": [0, 7],
    "Magha": [1, 8], "P.Phalguni": [2, 8], "U.Phalguni": [3, 8], "Hasta": [4, 8],
    "Chitra": [5, 8], "Swati": [6, 8], "Vishakha": [7, 8],
    "Anuradha": [8, 7], "Jyeshtha": [8, 6], "Mula": [8, 5], "P.Ashadha": [8, 4],
    "U.Ashadha": [8, 3], "Abhijit": [8, 2], "Shravana": [8, 1],
    "Dhanishta": [7, 0], "Shatabhisha": [6, 0], "P.Bhadrapada": [5, 0],
    "U.Bhadrapada": [4, 0], "Revati": [3, 0], "Ashwini": [2, 0], "Bharani": [1, 0]
};

export const NAKSHATRA_ORDER_28 = ["Ashwini", "Bharani", "Krittika", "Rohini", "Mrigashira", "Ardra", "Punarvasu", "Pushya", "Ashlesha", "Magha", "P.Phalguni", "U.Phalguni", "Hasta", "Chitra", "Swati", "Vishakha", "Anuradha", "Jyeshtha", "Mula", "P.Ashadha", "U.Ashadha", "Abhijit", "Shravana", "Dhanishta", "Shatabhisha", "P.Bhadrapada", "U.Bhadrapada", "Revati"];
const NAKSHATRA_ORDER_27 = ["Ashwini", "Bharani", "Krittika", "Rohini", "Mrigashira", "Ardra", "Punarvasu", "Pushya", "Ashlesha", "Magha", "P.Phalguni", "U.Phalguni", "Hasta", "Chitra", "Swati", "Vishakha", "Anuradha", "Jyeshtha", "Mula", "P.Ashadha", "U.Ashadha", "Shravana", "Dhanishta", "Shatabhisha", "P.Bhadrapada", "U.Bhadrapada", "Revati"];

export const LATTA_KICKS = { Sun: 11, Mars: 2, Jupiter: 5, Saturn: 7, Moon: -21, Mercury: -6, Venus: -4, Rahu: -8, Ketu: -8 };

// Fixed-speed planets get Vedha in all 3 directions simultaneously (per Phaladeepika)
const FIXED_SPEED_PLANETS = new Set(["Sun", "Moon", "Rahu", "Ketu"]);

export function get28Nakshatra(longitude) {
    const lon = ((longitude % 360) + 360) % 360;
    if (lon >= 266.6667 && lon < 276.6667) return "U.Ashadha";
    if (lon >= 276.6667 && lon < 280.8889) return "Abhijit";
    if (lon >= 280.8889 && lon < 293.3333) return "Shravana";
    return NAKSHATRA_ORDER_27[Math.floor(lon / 13.333333)];
}

export function getPlanetCoordinates(planetLongitudes) {
    const coords = {};
    for (const [planet, lon] of Object.entries(planetLongitudes)) {
        const nak = get28Nakshatra(lon);
        const pada = (nak === "Abhijit") ? 1 : Math.floor((lon % 13.333333) / 3.333333) + 1;
        if (OUTER_NAKSHATRAS[nak]) {
            coords[planet] = { nakshatra: nak, pada, grid_pos: OUTER_NAKSHATRAS[nak], longitude: lon };
        }
    }
    return coords;
}

export function calculateLatta(planetName, currentNakshatra) {
    if (!(planetName in LATTA_KICKS) || !NAKSHATRA_ORDER_28.includes(currentNakshatra)) return null;
    const currentIdx = NAKSHATRA_ORDER_28.indexOf(currentNakshatra);
    let targetIdx = (currentIdx + LATTA_KICKS[planetName]) % 28;
    if (targetIdx < 0) targetIdx += 28;
    const targetNak = NAKSHATRA_ORDER_28[targetIdx];
    if (OUTER_NAKSHATRAS[targetNak]) return { target: targetNak, grid_pos: OUTER_NAKSHATRAS[targetNak] };
    return null;
}

/**
 * Classical Vedha direction rules (Phaladeepika):
 *  Normal/Stationary/Direct -> Sammukha (Front) ONLY
 *  Fast (Atichari)          -> Vama (Left) ONLY
 *  Retrograde (Vakri)       -> Dakshina (Right) ONLY
 *  Sun, Moon, Rahu, Ketu    -> ALL THREE simultaneously (motion="All")
 */
export function getVedhaRays(r, c, motion = "All", pada = null) {
    const rays = [];
    const isTop = r === 0, isBottom = r === 8, isLeft = c === 0, isRight = c === 8;
    const isEdge = isTop || isBottom || isLeft || isRight;

    const addRay = (tr, tc, vType) => { if (tr >= 0 && tr < 9 && tc >= 0 && tc < 9) rays.push({ r: tr, c: tc, type: vType }); };
    const traceDiag = (rStep, cStep, vType, startR = r, startC = c) => {
        let tr = startR + rStep, tc = startC + cStep;
        while (tr >= 0 && tr < 9 && tc >= 0 && tc < 9) { addRay(tr, tc, vType); tr += rStep; tc += cStep; }
    };

    if (isEdge) {
        if (["All", "Normal", "Stationary", "Direct"].includes(motion)) {
            if (isLeft || isRight) { for (let i = 0; i < 9; i++) if (i !== c) addRay(r, i, "Sammukha"); }
            else if (isTop || isBottom) { for (let i = 0; i < 9; i++) if (i !== r) addRay(i, c, "Sammukha"); }
        }
        if (["All", "Fast"].includes(motion)) {
            if (isTop) traceDiag(1, 1, "Vama");
            else if (isBottom) traceDiag(-1, -1, "Vama");
            else if (isLeft) traceDiag(-1, 1, "Vama");
            else if (isRight) traceDiag(1, -1, "Vama");
        }
        if (["All", "Retrograde"].includes(motion)) {
            if (isTop) traceDiag(1, -1, "Dakshina");
            else if (isBottom) traceDiag(-1, 1, "Dakshina");
            else if (isLeft) traceDiag(1, 1, "Dakshina");
            else if (isRight) traceDiag(-1, -1, "Dakshina");
        }
        if (pada !== null) {
            if ((r === 1 && c === 0 && pada === 4) || (r === 0 && c === 1 && pada === 1)) { addRay(0, 0, "CornerDiag"); traceDiag(1, 1, "CornerDiag", 0, 0); }
            else if ((r === 0 && c === 7 && pada === 4) || (r === 1 && c === 8 && pada === 1)) { addRay(0, 8, "CornerDiag"); traceDiag(1, -1, "CornerDiag", 0, 8); }
            else if ((r === 7 && c === 8 && pada === 4) || (r === 8 && c === 7 && pada === 1)) { addRay(8, 8, "CornerDiag"); traceDiag(-1, -1, "CornerDiag", 8, 8); }
            else if ((r === 8 && c === 1 && pada === 4) || (r === 7 && c === 0 && pada === 1)) { addRay(8, 0, "CornerDiag"); traceDiag(-1, 1, "CornerDiag", 8, 0); }
        }
    } else {
        if (["All", "Normal", "Stationary", "Direct"].includes(motion)) {
            for (let i = 0; i < 9; i++) { if (i !== c) addRay(r, i, "Sammukha"); if (i !== r) addRay(i, c, "Sammukha"); }
        }
        if (["All", "Fast"].includes(motion)) { traceDiag(1, 1, "Vama"); traceDiag(-1, -1, "Vama"); }
        if (["All", "Retrograde"].includes(motion)) { traceDiag(-1, 1, "Dakshina"); traceDiag(1, -1, "Dakshina"); }
    }
    return rays;
}

/**
 * Live "who is vedha-ing whom right now" for the transit dashboard.
 * @param {Object} planetLongitudes  { Sun: deg, Moon: deg, ... } full planet names
 * @param {Object} planetMotion      { Sun: "All", Mars: "Retrograde"|"Fast"|"Normal", ... }
 * Returns: { perPlanet: { Sun: { nakshatra, pada, vedhaTargets:[nakshatra,...], lattaTarget } }, vedhaMap: { targetNakshatra: [causingPlanet,...] } }
 */
export function getLiveVedhaAndLatta(planetLongitudes, planetMotion = {}) {
    const coords = getPlanetCoordinates(planetLongitudes);
    const gridOccupants = {}; // "r,c" -> [planetName,...] for reverse lookup of which nakshatra a ray lands on
    for (const [nak, pos] of Object.entries(OUTER_NAKSHATRAS)) gridOccupants[`${pos[0]},${pos[1]}`] = nak;

    const perPlanet = {};
    const vedhaMap = {};

    for (const [planet, c] of Object.entries(coords)) {
        const motion = FIXED_SPEED_PLANETS.has(planet) ? "All" : (planetMotion[planet] || "Normal");
        const rays = getVedhaRays(c.grid_pos[0], c.grid_pos[1], motion, c.pada);
        const vedhaTargets = [];
        rays.forEach(ray => {
            const targetNak = gridOccupants[`${ray.r},${ray.c}`];
            if (targetNak && targetNak !== c.nakshatra) {
                vedhaTargets.push({ nakshatra: targetNak, type: ray.type });
                if (!vedhaMap[targetNak]) vedhaMap[targetNak] = [];
                vedhaMap[targetNak].push({ planet, type: ray.type });
            }
        });
        const latta = calculateLatta(planet, c.nakshatra);
        perPlanet[planet] = { nakshatra: c.nakshatra, pada: c.pada, motion, vedhaTargets, latta: latta ? latta.target : null };
    }
    return { perPlanet, vedhaMap };
}
