import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; import api from '../api/axios'; const SettingsContext = createContext(); export const useSettings = () => useContext(SettingsContext); export const SettingsProvider = ({ children }) => { // --- State Initialization --- // Load from local storage or set defaults const [currency, setCurrency] = useState(localStorage.getItem('app_currency') || 'INR'); const [theme, setTheme] = useState(localStorage.getItem('app_theme') || 'cosmic'); const [privacyMode, setPrivacyMode] = useState(localStorage.getItem('app_privacy') === 'true'); // Pro Features (Realistic) const [savingsGoal, setSavingsGoal] = useState(parseInt(localStorage.getItem('app_savings_goal')) || 20); // % Target const [notifications, setNotifications] = useState(JSON.parse(localStorage.getItem('app_notifications')) || { email: true, push: false, budget_alerts: true, monthly_reports: true }); // --- Currency Logic --- const getSymbol = (curr) => { switch (curr) { case 'INR': return '₹'; case 'USD': return '$'; case 'EUR': return '€'; case 'GBP': return '£'; default: return '$'; } }; const [currencySymbol, setCurrencySymbol] = useState(getSymbol(currency)); useEffect(() => { setCurrencySymbol(getSymbol(currency)); localStorage.setItem('app_currency', currency); }, [currency]); // --- Theme Logic --- const themes = { cosmic: { primary: '#6366f1', secondary: '#ec4899', name: 'Cosmic Indigo' }, emerald: { primary: '#10b981', secondary: '#34d399', name: 'Emerald Forest' }, rose: { primary: '#f43f5e', secondary: '#fb7185', name: 'Rose Gold' }, amber: { primary: '#f59e0b', secondary: '#fbbf24', name: 'Amber Sunset' }, azure: { primary: '#0ea5e9', secondary: '#38bdf8', name: 'Azure Sky' } }; useEffect(() => { const root = document.documentElement; const selectedTheme = themes[theme] || themes.cosmic; // Update CSS Variables root.style.setProperty('--primary-color', selectedTheme.primary); root.style.setProperty('--secondary-color', selectedTheme.secondary); localStorage.setItem('app_theme', theme); }, [theme]); // --- Privacy & Notifications Persistence --- useEffect(() => { localStorage.setItem('app_privacy', privacyMode); }, [privacyMode]); useEffect(() => { localStorage.setItem('app_savings_goal', savingsGoal); }, [savingsGoal]); useEffect(() => { localStorage.setItem('app_notifications', JSON.stringify(notifications)); }, [notifications]); // --- Actions --- const updateNotification = (key) => { setNotifications(prev => ({ ...prev, [key]: !prev[key] })); }; // --- Background Reporting States --- const [generatingPDF, setGeneratingPDF] = useState(false); const [sendingEmail, setSendingEmail] = useState(false); const handleDownloadReport = useCallback(async (format, type, provider) => { if (generatingPDF) return; setGeneratingPDF(true); try { const payload = provider && provider !== 'Auto Mode' ? { provider } : {}; const initRes = await api.post(`finance/generate-report/?type=${type}`, payload); const { task_id } = initRes.data; let pollCount = 0; const pollInterval = setInterval(async () => { try { pollCount++; const statusRes = await api.get(`finance/generate-report/?task_id=${task_id}`); if (statusRes.data.status === 'completed') { clearInterval(pollInterval); const fileRes = await api.get(`finance/generate-report/?task_id=${task_id}&download=true`, { responseType: 'blob' }); const url = window.URL.createObjectURL(new Blob([fileRes.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', `Pro_Financial_Report_${new Date().toISOString().split('T')[0]}.pdf`); document.body.appendChild(link); link.click(); link.remove(); setGeneratingPDF(false); alert("PDF Report Generated Successfully!"); } else if (statusRes.data.status === 'failed') { clearInterval(pollInterval); setGeneratingPDF(false); alert(`Generation Failed: ${statusRes.data.error || 'Unknown error'}`); } else { if (pollCount > 60) { clearInterval(pollInterval); setGeneratingPDF(false); alert("Report generation is taking longer than expected. It will continue in the background."); } } } catch (pollErr) { console.error("Polling error:", pollErr); } }, 5000); } catch (err) { alert(`Report Initiation Failed: ${err.message}`); setGeneratingPDF(false); } }, [generatingPDF]); const handleSendEmailReport = useCallback(async (recipient, provider) => { if (!recipient) { alert("Please enter an email address."); return false; } setSendingEmail(true); try { const payload = { email: recipient }; if (provider && provider !== 'Auto Mode') { payload.provider = provider; } const initRes = await api.post('finance/send-email-report/', payload); const { task_id } = initRes.data; (async () => { let pollCount = 0; const pollInterval = setInterval(async () => { try { pollCount++; const statusRes = await api.get(`finance/generate-report/?task_id=${task_id}`); if (statusRes.data.status === 'completed') { clearInterval(pollInterval); setSendingEmail(false); alert("Email Report Sent Successfully!"); } else if (statusRes.data.status === 'failed') { clearInterval(pollInterval); setSendingEmail(false); alert(`Email Failed: ${statusRes.data.error || 'Unknown error'}`); } else { if (pollCount > 120) { clearInterval(pollInterval); setSendingEmail(false); alert("Email report is taking longer than expected. It will continue in the background."); } } } catch (pollErr) { console.error("Polling error:", pollErr); } }, 5000); })(); return true; } catch (err) { alert(`Email Initiation Failed: ${err.message}`); setSendingEmail(false); return false; } }, []); const value = { currency, setCurrency, currencySymbol, theme, setTheme, themes, privacyMode, setPrivacyMode, savingsGoal, setSavingsGoal, notifications, updateNotification, generatingPDF, sendingEmail, handleDownloadReport, handleSendEmailReport }; return ( {children} ); };