/**
 * src/saudi/calendar.ts
 * Saudi-specific calendar awareness — Hijri date, prayer times, Ramadan flag,
 * Ramadan-aware working hours.
 *
 * Hijri calendar uses Intl.DateTimeFormat with the Umm al-Qura locale, which
 * is the Saudi government standard. Prayer times use adhan (Pray Times Inc)
 * with the Umm al-Qura calculation method.
 *
 * Cities ship with built-in coordinates. Tenants outside this list pass
 * lat/lng explicitly via tenants.metadata.location.
 */
import { Coordinates, CalculationMethod, PrayerTimes, Madhab } from 'adhan';
// ─── Saudi city coordinates ──────────────────────────────────────────
const SAUDI_CITIES = {
    riyadh: { lat: 24.7136, lng: 46.6753, tz: 'Asia/Riyadh' },
    jeddah: { lat: 21.4858, lng: 39.1925, tz: 'Asia/Riyadh' },
    makkah: { lat: 21.3891, lng: 39.8579, tz: 'Asia/Riyadh' },
    madinah: { lat: 24.4709, lng: 39.6122, tz: 'Asia/Riyadh' },
    dammam: { lat: 26.4207, lng: 50.0888, tz: 'Asia/Riyadh' },
    taif: { lat: 21.2854, lng: 40.4167, tz: 'Asia/Riyadh' },
    abha: { lat: 18.2164, lng: 42.5053, tz: 'Asia/Riyadh' },
    buraydah: { lat: 26.3260, lng: 43.9750, tz: 'Asia/Riyadh' },
    tabuk: { lat: 28.3835, lng: 36.5662, tz: 'Asia/Riyadh' },
    hail: { lat: 27.5219, lng: 41.6907, tz: 'Asia/Riyadh' },
};
export function citySlug(name) {
    return name.trim().toLowerCase().replace(/\s+/g, '').replace(/[ً-ٟ]/g, '');
}
export function cityCoords(name) {
    const slug = citySlug(name);
    if (slug in SAUDI_CITIES)
        return SAUDI_CITIES[slug];
    // Arabic name fallback
    const arabicMap = {
        'الرياض': 'riyadh', 'جدة': 'jeddah', 'مكة': 'makkah', 'مكةالمكرمة': 'makkah',
        'المدينة': 'madinah', 'المدينةالمنورة': 'madinah', 'الدمام': 'dammam',
        'الطائف': 'taif', 'أبها': 'abha', 'بريدة': 'buraydah', 'تبوك': 'tabuk', 'حائل': 'hail',
    };
    const en = arabicMap[name.trim().replace(/\s+/g, '')];
    return en ? SAUDI_CITIES[en] : null;
}
const HIJRI_MONTHS_AR = [
    'محرم', 'صفر', 'ربيع الأول', 'ربيع الآخر', 'جمادى الأولى', 'جمادى الآخرة',
    'رجب', 'شعبان', 'رمضان', 'شوال', 'ذو القعدة', 'ذو الحجة',
];
const HIJRI_MONTHS_EN = [
    'Muharram', 'Safar', "Rabi'-I", "Rabi'-II", 'Jumada-I', 'Jumada-II',
    'Rajab', "Sha'ban", 'Ramadan', 'Shawwal', "Dhu al-Qi'dah", "Dhu al-Hijjah",
];
export function hijriDate(date = new Date()) {
    // Intl returns parts like { year: '1447', month: '9', day: '22' }
    const fmt = new Intl.DateTimeFormat('en-u-ca-islamic-umalqura', {
        year: 'numeric',
        month: 'numeric',
        day: 'numeric',
        timeZone: 'Asia/Riyadh',
    });
    const parts = Object.fromEntries(fmt.formatToParts(date).filter(p => p.type !== 'literal').map(p => [p.type, p.value]));
    const year = parseInt(parts.year, 10);
    const monthNumber = parseInt(parts.month, 10);
    const day = parseInt(parts.day, 10);
    const monthAr = HIJRI_MONTHS_AR[monthNumber - 1] || `شهر ${monthNumber}`;
    const monthEn = HIJRI_MONTHS_EN[monthNumber - 1] || `Month ${monthNumber}`;
    return {
        year,
        monthNumber,
        monthAr,
        monthEn,
        day,
        isoLike: `${year}-${String(monthNumber).padStart(2, '0')}-${String(day).padStart(2, '0')}`,
        formattedAr: `${day} ${monthAr} ${year} هـ`,
    };
}
export function isRamadan(date = new Date()) {
    return hijriDate(date).monthNumber === 9;
}
export function isHajjSeason(date = new Date()) {
    // Hajj rituals fall in Dhu al-Hijjah days 8-13. Loosely flag the whole month.
    return hijriDate(date).monthNumber === 12;
}
function fmtTime(d, tz) {
    return new Intl.DateTimeFormat('en-GB', {
        hour: '2-digit',
        minute: '2-digit',
        hour12: false,
        timeZone: tz,
    }).format(d);
}
export function prayerTimes(cityName, date = new Date()) {
    const coords = cityCoords(cityName);
    if (!coords)
        return null;
    const params = CalculationMethod.UmmAlQura();
    // Saudi default madhab is Hanbali, which uses Shafi-equivalent Asr time.
    params.madhab = Madhab.Shafi;
    const c = new Coordinates(coords.lat, coords.lng);
    const times = new PrayerTimes(c, date, params);
    const dateStr = new Intl.DateTimeFormat('en-CA', {
        timeZone: coords.tz,
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
    }).format(date);
    return {
        city: cityName,
        date: dateStr,
        fajr: fmtTime(times.fajr, coords.tz),
        sunrise: fmtTime(times.sunrise, coords.tz),
        dhuhr: fmtTime(times.dhuhr, coords.tz),
        asr: fmtTime(times.asr, coords.tz),
        maghrib: fmtTime(times.maghrib, coords.tz),
        isha: fmtTime(times.isha, coords.tz),
        nearPrayerWindowMinutes: 15,
    };
}
/** Are we currently within `windowMinutes` of an upcoming prayer? */
export function isNearPrayer(cityName, windowMinutes = 15, now = new Date()) {
    const coords = cityCoords(cityName);
    if (!coords)
        return { near: false, prayer: null, minutesUntil: null };
    const params = CalculationMethod.UmmAlQura();
    params.madhab = Madhab.Shafi;
    const c = new Coordinates(coords.lat, coords.lng);
    const times = new PrayerTimes(c, now, params);
    const next = times.nextPrayer();
    if (!next)
        return { near: false, prayer: null, minutesUntil: null };
    const nextTime = times.timeForPrayer(next);
    if (!nextTime)
        return { near: false, prayer: null, minutesUntil: null };
    const minutesUntil = Math.round((nextTime.getTime() - now.getTime()) / 60_000);
    return {
        near: minutesUntil >= 0 && minutesUntil <= windowMinutes,
        prayer: String(next).toLowerCase(),
        minutesUntil,
    };
}
const RAMADAN_DEFAULT_HOURS = { open: '10:00', close: '15:00' };
const STANDARD_DEFAULT_HOURS = { open: '09:00', close: '17:00' };
export function workingHoursToday(configured, now = new Date()) {
    // Day of week in Asia/Riyadh, Sunday = 0, Friday = 5, Saturday = 6
    const dow = parseInt(new Intl.DateTimeFormat('en-US', { weekday: 'short', timeZone: 'Asia/Riyadh' })
        .formatToParts(now)
        .find(p => p.type === 'weekday')
        .value
        .replace('Sun', '0')
        .replace('Mon', '1')
        .replace('Tue', '2')
        .replace('Wed', '3')
        .replace('Thu', '4')
        .replace('Fri', '5')
        .replace('Sat', '6'), 10);
    const days = configured?.days ?? [0, 1, 2, 3, 4]; // Sun-Thu (Saudi work-week)
    const isWorkingDay = days.includes(dow);
    const ramadan = isRamadan(now);
    const hours = ramadan
        ? { open: RAMADAN_DEFAULT_HOURS.open, close: RAMADAN_DEFAULT_HOURS.close }
        : { open: configured?.open || STANDARD_DEFAULT_HOURS.open, close: configured?.close || STANDARD_DEFAULT_HOURS.close };
    return {
        isWorkingDay,
        open: isWorkingDay ? hours.open : null,
        close: isWorkingDay ? hours.close : null,
        ramadanAdjusted: ramadan,
        hijri: hijriDate(now),
        dayOfWeek: dow,
    };
}
//# sourceMappingURL=calendar.js.map