// =========================================================================
// KALASUTRA V3 — PANCHANG ENGINE
// Ported from your v2 backtest.js computePanchang()/getTrueCenterSunTimes()
// logic (same math, same results) — refactored into pure functions so it
// can run silently in background.js on every alarm tick, not just on a
// button click inside the popup DOM.
// =========================================================================

const VARA = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
const TITHI_PREFIX = ["Shukla", "Krishna"];
const TITHI_NAMES = ["Prathama", "Dwitiya", "Tritiya", "Chaturthi", "Panchami", "Shashti", "Saptami", "Ashtami", "Navami", "Dashami", "Ekadashi", "Dwadashi", "Trayodashi", "Chaturdashi", "Purnima", "Prathama", "Dwitiya", "Tritiya", "Chaturthi", "Panchami", "Shashti", "Saptami", "Ashtami", "Navami", "Dashami", "Ekadashi", "Dwadashi", "Trayodashi", "Chaturdashi", "Amavasya"];
const YOGAS = ["Vishkambha", "Priti", "Ayushman", "Saubhagya", "Shobhana", "Atiganda", "Sukarma", "Dhriti", "Shula", "Ganda", "Vriddhi", "Dhruva", "Vyaghata", "Harshana", "Vajra", "Siddhi", "Vyatipata", "Variyan", "Parigha", "Shiva", "Siddha", "Sadhya", "Shubha", "Shukla", "Brahma", "Indra", "Vaidhriti"];
const KARANAS = ["Bava", "Balava", "Kaulava", "Taitila", "Gara", "Vanija", "Vishti"];
const HORA_LORDS = ["Sun", "Venus", "Mercury", "Moon", "Saturn", "Jupiter", "Mars"];
const DAY_TO_CHALDEAN = [0, 3, 6, 2, 5, 1, 4];

const DAY_CHOGHADIYA = {
    0: ["Udveg (Sun)", "Chal (Ven)", "Labh (Mer)", "Amrit (Mon)", "Kaal (Sat)", "Shubh (Jup)", "Rog (Mar)", "Udveg (Sun)"],
    1: ["Amrit (Mon)", "Kaal (Sat)", "Shubh (Jup)", "Rog (Mar)", "Udveg (Sun)", "Chal (Ven)", "Labh (Mer)", "Amrit (Mon)"],
    2: ["Rog (Mar)", "Udveg (Sun)", "Chal (Ven)", "Labh (Mer)", "Amrit (Mon)", "Kaal (Sat)", "Shubh (Jup)", "Rog (Mar)"],
    3: ["Labh (Mer)", "Amrit (Mon)", "Kaal (Sat)", "Shubh (Jup)", "Rog (Mar)", "Udveg (Sun)", "Chal (Ven)", "Labh (Mer)"],
    4: ["Shubh (Jup)", "Rog (Mar)", "Udveg (Sun)", "Chal (Ven)", "Labh (Mer)", "Amrit (Mon)", "Kaal (Sat)", "Shubh (Jup)"],
    5: ["Chal (Ven)", "Labh (Mer)", "Amrit (Mon)", "Kaal (Sat)", "Shubh (Jup)", "Rog (Mar)", "Udveg (Sun)", "Chal (Ven)"],
    6: ["Kaal (Sat)", "Shubh (Jup)", "Rog (Mar)", "Udveg (Sun)", "Chal (Ven)", "Labh (Mer)", "Amrit (Mon)", "Kaal (Sat)"]
};
const NIGHT_CHOGHADIYA = {
    0: ["Shubh (Jup)", "Amrit (Mon)", "Chal (Ven)", "Rog (Mar)", "Kaal (Sat)", "Labh (Mer)", "Udveg (Sun)", "Shubh (Jup)"],
    1: ["Kaal (Sat)", "Labh (Mer)", "Udveg (Sun)", "Shubh (Jup)", "Amrit (Mon)", "Chal (Ven)", "Rog (Mar)", "Kaal (Sat)"],
    2: ["Chal (Ven)", "Rog (Mar)", "Kaal (Sat)", "Labh (Mer)", "Udveg (Sun)", "Shubh (Jup)", "Amrit (Mon)", "Chal (Ven)"],
    3: ["Rog (Mar)", "Kaal (Sat)", "Labh (Mer)", "Udveg (Sun)", "Shubh (Jup)", "Amrit (Mon)", "Chal (Ven)", "Rog (Mar)"],
    4: ["Labh (Mer)", "Udveg (Sun)", "Shubh (Jup)", "Amrit (Mon)", "Chal (Ven)", "Rog (Mar)", "Kaal (Sat)", "Labh (Mer)"],
    5: ["Udveg (Sun)", "Shubh (Jup)", "Amrit (Mon)", "Chal (Ven)", "Rog (Mar)", "Kaal (Sat)", "Labh (Mer)", "Udveg (Sun)"],
    6: ["Amrit (Mon)", "Chal (Ven)", "Rog (Mar)", "Kaal (Sat)", "Labh (Mer)", "Udveg (Sun)", "Shubh (Jup)", "Amrit (Mon)"]
};
const RAHU_KALAM_SEGMENTS = [8, 2, 7, 5, 6, 4, 3]; // segment (1-8) of the day ruled by Rahu, indexed by weekday

// True (center-disc) sunrise/sunset — same NOAA-style approximation as v2.
export function getTrueCenterSunTimes(y, m, d, lat, lng, tzOffset) {
    const jd = (Date.UTC(y, m - 1, d, 12, 0, 0) / 86400000) + 2440587.5;
    const n = jd - 2451545.0 + 0.0008;
    const jStar = n - (lng / 360);
    const M = (357.5291 + 0.98560028 * jStar) % 360;
    const M_rad = M * Math.PI / 180;
    const C = 1.9148 * Math.sin(M_rad) + 0.0200 * Math.sin(2 * M_rad) + 0.0003 * Math.sin(3 * M_rad);
    const lambda = (M + C + 180 + 102.9372) % 360;
    const lambda_rad = lambda * Math.PI / 180;
    const jTransit = 2451545.0 + jStar + 0.0053 * Math.sin(M_rad) - 0.0069 * Math.sin(2 * lambda_rad);
    const dec_rad = Math.asin(Math.sin(lambda_rad) * Math.sin(23.4397 * Math.PI / 180));
    const zenith_rad = 90.0 * Math.PI / 180;
    const lat_rad = lat * Math.PI / 180;
    let cosOmega = (Math.cos(zenith_rad) - Math.sin(lat_rad) * Math.sin(dec_rad)) / (Math.cos(lat_rad) * Math.cos(dec_rad));
    if (cosOmega > 1) cosOmega = 1;
    if (cosOmega < -1) cosOmega = -1;
    const omega = Math.acos(cosOmega) * 180 / Math.PI;
    const jRise = jTransit - omega / 360;
    const jSet = jTransit + omega / 360;

    const formatTime = (j) => {
        let utHours = (j - Math.floor(j) + 0.5) * 24;
        if (utHours >= 24) utHours -= 24;
        let localHours = utHours + tzOffset;
        if (localHours < 0) localHours += 24;
        if (localHours >= 24) localHours -= 24;
        let h = Math.floor(localHours);
        let mins = Math.floor((localHours - h) * 60);
        let ampm = h >= 12 ? 'PM' : 'AM';
        h = h % 12; h = h ? h : 12;
        return `${h.toString().padStart(2, '0')}:${mins.toString().padStart(2, '0')} ${ampm}`;
    };
    return { jRise, jSet, sunrise: formatTime(jRise), sunset: formatTime(jSet), formatTime };
}

/**
 * Computes the full Panchang for a given moment.
 * @param {number} tjd_ut  Julian Day (UT) of the moment to evaluate
 * @param {Date}   nowLocal JS Date used only to get y/m/d/local-timezone for sun times
 * @param {number} sunLong  sidereal Sun longitude at tjd_ut
 * @param {number} moonLong sidereal Moon longitude at tjd_ut
 * @param {number} lat/lng  observer location
 * @param {number} tzOffset e.g. 5.5 for IST
 */
export function computePanchang({ tjd_ut, y, m, d, sunLong, moonLong, lat, lng, tzOffset }) {
    const sunData = getTrueCenterSunTimes(y, m, d, lat, lng, tzOffset);
    const jd_local = tjd_ut + (tzOffset / 24.0);
    const weekdayIdx = Math.floor(jd_local + 1.5) % 7;

    // Rahu Kalam
    const dayDuration = sunData.jSet - sunData.jRise;
    const rkDur = dayDuration / 8;
    const rkStart = sunData.jRise + (RAHU_KALAM_SEGMENTS[weekdayIdx] - 1) * rkDur;
    const rkEnd = sunData.jRise + RAHU_KALAM_SEGMENTS[weekdayIdx] * rkDur;
    const rahuKalam = `${sunData.formatTime(rkStart)} - ${sunData.formatTime(rkEnd)}`;

    // Hora / Sub-Hora / Choghadiya need the active sunrise-to-sunrise window
    const nextSunData = getTrueCenterSunTimes(y, m, d + 1, lat, lng, tzOffset);
    const prevSunData = getTrueCenterSunTimes(y, m, d - 1, lat, lng, tzOffset);

    let activeRise, activeSet, activeNextRise;
    if (tjd_ut >= sunData.jRise) { activeRise = sunData.jRise; activeSet = sunData.jSet; activeNextRise = nextSunData.jRise; }
    else { activeRise = prevSunData.jRise; activeSet = prevSunData.jSet; activeNextRise = sunData.jRise; }

    const isDay = (tjd_ut >= activeRise && tjd_ut < activeSet);
    let hIdx, hDur;
    if (isDay) {
        hDur = (activeSet - activeRise) / 12;
        hIdx = Math.min(11, Math.floor((tjd_ut - activeRise) / hDur));
    } else {
        hDur = (activeNextRise - activeSet) / 12;
        hIdx = 12 + Math.min(11, Math.floor((tjd_ut - activeSet) / hDur));
    }

    const startChaldeanIdx = DAY_TO_CHALDEAN[weekdayIdx];
    const currentHoraIdx = (startChaldeanIdx + hIdx) % 7;
    const currentHora = HORA_LORDS[currentHoraIdx];

    const horaStartJd = isDay ? (activeRise + hIdx * hDur) : (activeSet + (hIdx - 12) * hDur);
    const subHoraDur = hDur / 12;
    let subHoraIdx = Math.floor((tjd_ut - horaStartJd) / subHoraDur);
    if (subHoraIdx > 11) subHoraIdx = 11;
    const currentSubHora = HORA_LORDS[(currentHoraIdx + subHoraIdx) % 7];

    let currentChoghadiya;
    if (isDay) {
        const cDur = (activeSet - activeRise) / 8;
        let cIdx = Math.min(7, Math.floor((tjd_ut - activeRise) / cDur));
        currentChoghadiya = DAY_CHOGHADIYA[weekdayIdx][cIdx] + " (Day)";
    } else {
        const cDur = (activeNextRise - activeSet) / 8;
        let cIdx = Math.min(7, Math.floor((tjd_ut - activeSet) / cDur));
        currentChoghadiya = NIGHT_CHOGHADIYA[weekdayIdx][cIdx] + " (Night)";
    }

    const tithiDiff = ((moonLong - sunLong) % 360 + 360) % 360;
    const tithiIdx = Math.floor(tithiDiff / 12);
    let tithiPrefix = tithiIdx < 15 ? TITHI_PREFIX[0] + " " : TITHI_PREFIX[1] + " ";
    if (tithiIdx === 14 || tithiIdx === 29) tithiPrefix = "";
    const tithi = tithiPrefix + TITHI_NAMES[tithiIdx];

    const yoga = YOGAS[Math.floor(((moonLong + sunLong) % 360) / (40 / 3)) % 27];

    const karanaIdx = Math.floor(tithiDiff / 6);
    const karana = (karanaIdx === 0) ? "Kintughna" : (karanaIdx === 59) ? "Shakuni" : (karanaIdx === 60) ? "Chatushpada" : (karanaIdx === 61) ? "Naga" : KARANAS[(karanaIdx - 1) % 7];

    return {
        weekday: VARA[weekdayIdx],
        weekdayIdx,
        tithi, tithiIdx,
        yoga,
        karana,
        hora: currentHora,
        subHora: currentSubHora,
        choghadiya: currentChoghadiya,
        rahuKalam,
        sunrise: sunData.sunrise,
        sunset: sunData.sunset,
        isDay
    };
}
