import React, { useState, useEffect, useMemo } from 'react'; import { Tent, Calendar as CalendarIcon, ChevronLeft, ChevronRight, Loader2, Info, Languages, Sparkles, Clock, MapPin, CalendarDays, ExternalLink } from 'lucide-react'; import { CalendarService, NEPALI_MONTHS_DATA_2082 } from '../services/calendarService'; import { explainHoliday } from '../services/geminiService'; import { NepaliDate } from '../types'; import { useLanguage } from '../contexts/LanguageContext'; import { Button } from '../components/ui/Button'; // Mock data for holidays to simulate functional next festival logic // Now aligned with correct 2082 dates from service const HOLIDAYS_2082: Record = { "1-1": {en: "New Year 2082", ne: "नयाँ वर्ष २०८२"}, "1-11": {en: "Loktantra Diwas", ne: "लोकतन्त्र दिवस"}, "1-15": {en: "Matatirtha Aunsi", ne: "मातातीर्थ औंसी"}, "1-25": {en: "Buddha Jayanti", ne: "बुद्ध जयन्ती"}, "3-15": {en: "Dhan Diwas", ne: "धान दिवस"}, "6-3": {en: "Constitution Day", ne: "संविधान दिवस"}, "7-7": {en: "Vijaya Dashami", ne: "विजया दशमी"}, "7-30": {en: "Laxmi Puja", ne: "लक्ष्मी पूजा"}, "9-10": {en: "Christmas Day", ne: "क्रिसमस डे"}, "10-1": {en: "Maghe Sankranti", ne: "माघे संक्रान्ति"}, "11-15": {en: "Maha Shivaratri", ne: "महा शिवरात्री"}, "12-13": {en: "Holi", ne: "फागु पूर्णिमा"} }; const Culture: React.FC = () => { const { language, setLanguage, t } = useLanguage(); // Real-time Date Tracking const today = CalendarService.getCurrentNepaliDate(); // Calendar State const [currentYear, setCurrentYear] = useState(2082); const [currentMonth, setCurrentMonth] = useState(today.month); const [dates, setDates] = useState([]); const [loading, setLoading] = useState(false); const [monthHolidays, setMonthHolidays] = useState([]); // Holiday Info State const [selectedHoliday, setSelectedHoliday] = useState(null); const [explanation, setExplanation] = useState<{en: string, ne: string} | null>(null); const [explaining, setExplaining] = useState(false); useEffect(() => { const fetchCalendar = async () => { setLoading(true); const data = await CalendarService.getDatesForMonth(currentYear, currentMonth); setDates(data); // Filter holidays for the side list const holidays = data.filter(d => d.events.length > 0); setMonthHolidays(holidays); setLoading(false); }; fetchCalendar(); }, [currentYear, currentMonth]); const changeMonth = (delta: number) => { let nextMonth = currentMonth + delta; if (nextMonth > 12) { nextMonth = 1; } else if (nextMonth < 1) { nextMonth = 12; } setCurrentMonth(nextMonth); }; const jumpToToday = () => { setCurrentMonth(today.month); }; const handleHolidayClick = async (holidayName: string) => { setSelectedHoliday(holidayName); setExplanation(null); setExplaining(true); const cached = await CalendarService.getHolidayExplanation(holidayName); if (cached) { setExplanation(cached); } else { const aiResult = await explainHoliday(holidayName); setExplanation(aiResult); await CalendarService.saveHolidayExplanation(holidayName, aiResult.en, aiResult.ne); } setExplaining(false); }; const currentMonthNameEn = dates[0]?.bs_month_str_en || 'Loading...'; const currentMonthNameNp = dates[0]?.bs_month_str_np || ''; // Helper to localize numeric strings const convertToNepaliDigits = (value: number | string): string => { const str = value.toString(); const devanagariDigits = ['०', '१', '२', '३', '४', '५', '६', '७', '८', '९']; return str.replace(/[0-9]/g, (match) => devanagariDigits[parseInt(match)]); }; const translateWeekday = (day: string): string => { const map: Record = { 'Sun': 'आइत', 'Mon': 'सोम', 'Tue': 'मंगल', 'Wed': 'बुध', 'Thu': 'बिही', 'Fri': 'शुक्र', 'Sat': 'शनि' }; return map[day] || day; }; // Functional Next Festival Calculation const nextFestival = useMemo(() => { const currentSimulatedMonth = today.month; const currentSimulatedDay = today.day; let nearestHoliday = null; let minDiff = Infinity; Object.entries(HOLIDAYS_2082).forEach(([key, val]) => { const [m, d] = key.split('-').map(Number); // Calculate approximate days distance from "today" let diff = (m - currentSimulatedMonth) * 30 + (d - currentSimulatedDay); // Handle wrap around year if (diff < 0) diff += 365; if (diff >= 0 && diff < minDiff) { minDiff = diff; nearestHoliday = { nameEn: val.en, nameNe: val.ne, month: m, day: d, daysLeft: diff }; } }); return nearestHoliday; }, [today]); return (
{/* HEADER */}

{t("Culture Hub", "Culture Hub")}

{t("Celebrate our rich heritage, festivals, and traditions.", "Celebrate our rich heritage, festivals, and traditions.")}

{/* MAIN CALENDAR */}
{/* Calendar Header */}

{language === 'en' ? currentMonthNameEn : currentMonthNameNp}

{language === 'en' ? currentYear : convertToNepaliDigits(currentYear)}

{language === 'en' ? `${currentMonthNameNp} • Nepal Sambat 1146` : `${currentMonthNameEn} • Nepal Sambat 1146`}

{/* Calendar Grid */}
{loading ? (

Consulting Patro...

) : (
{/* Weekday Headers */} {['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'].map(d => (
{language === 'ne' ? translateWeekday(d) : d}
))} {/* Days */} {dates.map((date, idx) => { const holidayEvent = date.events?.find(e => e.isHoliday); const isToday = date.bs_month === today.month && date.bs_day === today.day; // Calculate grid column start for first day const colStart = idx === 0 ? (date.weekday_str_en === 'Sun' ? 1 : date.weekday_str_en === 'Mon' ? 2 : date.weekday_str_en === 'Tue' ? 3 : date.weekday_str_en === 'Wed' ? 4 : date.weekday_str_en === 'Thu' ? 5 : date.weekday_str_en === 'Fri' ? 6 : 7) : undefined; return (
holidayEvent && handleHolidayClick(language === 'en' ? holidayEvent.strEn : holidayEvent.strNp)} >
{language === 'ne' ? convertToNepaliDigits(date.bs_day) : date.bs_day} {date.ad_day}
{holidayEvent && (
{language === 'en' ? holidayEvent.strEn : holidayEvent.strNp}
)} {date.tithi_str_en && (
{language === 'ne' ? date.tithi_str_np : date.tithi_str_en}
)}
); })}
)}
{/* Insights Panel - COMPACTED */}

{t("Holiday Insights", "Holiday Insights")}

{selectedHoliday && ( Guru Ba AI )}
{!selectedHoliday ? (

{t("Tap a holiday for details.", "Tap a holiday for details.")}

) : (

{selectedHoliday}

{explaining ? (

Consulting ancient texts...

) : (

"{language === 'en' ? explanation?.en : explanation?.ne}"

)}
)}
{/* SIDEBAR WIDGETS */}
{/* Next Festival (Google Calendar Style) */} {nextFestival && (
Calendar
Up Next

{language === 'en' ? nextFestival.nameEn : nextFestival.nameNe}

{/* Use NEPALI_MONTHS_DATA for name */} {NEPALI_MONTHS_DATA_2082[nextFestival.month-1].nameEn.slice(0,3)} {nextFestival.day}
In {nextFestival.daysLeft} Days
)} {/* Updated Title: Month's Holidays */}

{t("Month's Holidays", "Month's Holidays")}

{monthHolidays.map((date, i) => (
handleHolidayClick(language === 'en' ? date.events[0].strEn : date.events[0].strNp)} >
{date.bs_month_str_en.slice(0, 3)} {date.bs_day}

{language === 'en' ? date.events[0].strEn : date.events[0].strNp}

{date.weekday_str_en} • Public Holiday

))} {monthHolidays.length === 0 && (
No holidays in {currentMonthNameEn}.
)}
); }; export default Culture;