apiVersion: batch/v1
kind: CronJob
metadata:
  name: weather-report
  namespace: ai-agents
  labels:
    app: weather-report
spec:
  schedule: "0 11 * * *"
  timeZone: "America/New_York"   # K8s 1.27+ supports timeZone natively
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
            - name: weather-reporter
              image: node:18-alpine
              env:
                - name: GROUP_URL
                  valueFrom:
                    configMapKeyRef:
                      name: whatsapp-config
                      key: default-group-url
                - name: PERSONAL_NUMBER
                  valueFrom:
                    configMapKeyRef:
                      name: whatsapp-config
                      key: personal-number
              command:
                - "node"
                - "-e"
                - |
                  const https = require('https');
                  const http  = require('http');

                  const ZIP     = '16046';
                  const GATEWAY = 'http://whatsapp-gateway.ai-agents.svc.cluster.local:5001/send-message';
                  const CONFIG_API = 'http://hq-dashboard.ai-agents.svc.cluster.local/api/config/whatsapp';
                  const PERSONAL = process.env.PERSONAL_NUMBER;

                  function fetchConfig() {
                    return new Promise((resolve) => {
                      http.get(CONFIG_API, (res) => {
                        let d = '';
                        res.on('data', chunk => d += chunk);
                        res.on('end', () => {
                          try {
                            const parsed = JSON.parse(d);
                            if (parsed.success && parsed.data && parsed.data['default-group-url']) {
                              resolve(parsed.data['default-group-url']);
                              return;
                            }
                          } catch (e) {}
                          resolve(process.env.GROUP_URL);
                        });
                      }).on('error', () => resolve(process.env.GROUP_URL));
                    });
                  }

                  function weatherEmoji(desc) {
                    const d = desc.toLowerCase();
                    if (d.includes('sunny') || d.includes('clear'))       return '☀️';
                    if (d.includes('partly cloudy'))                       return '⛅';
                    if (d.includes('cloud') || d.includes('overcast'))    return '☁️';
                    if (d.includes('thunder') || d.includes('storm'))     return '⛈️';
                    if (d.includes('rain') || d.includes('drizzle'))      return '🌧️';
                    if (d.includes('snow') || d.includes('blizzard'))     return '❄️';
                    if (d.includes('fog') || d.includes('mist'))          return '🌫️';
                    if (d.includes('sleet') || d.includes('ice'))         return '🌨️';
                    return '🌤️';
                  }

                  function uvLabel(uv) {
                    const u = parseInt(uv);
                    if (u <= 2)  return 'Low';
                    if (u <= 5)  return 'Moderate';
                    if (u <= 7)  return 'High';
                    if (u <= 10) return 'Very High';
                    return 'Extreme';
                  }

                  function windLabel(mph) {
                    const m = parseInt(mph);
                    if (m < 5)  return 'Calm';
                    if (m < 15) return 'Breezy';
                    if (m < 25) return 'Windy';
                    if (m < 40) return 'Very Windy';
                    return 'Dangerous';
                  }

                  const url = `https://wttr.in/${ZIP}?format=j1`;
                  https.get(url, { headers: { 'User-Agent': 'WeatherBot/1.0' } }, (res) => {
                    let raw = '';
                    res.on('data', d => raw += d);
                    res.on('end', () => {
                      try {
                        const data    = JSON.parse(raw);
                        const cur     = data.current_condition[0];
                        const area    = data.nearest_area[0];
                        const today   = data.weather[0];
                        const tmrw    = data.weather[1];

                        const city    = area.areaName[0].value;
                        const state   = area.region[0].value;
                        const desc    = cur.weatherDesc[0].value;
                        const emoji   = weatherEmoji(desc);

                        const now     = new Date();
                        const etTime  = now.toLocaleString('en-US', { timeZone: 'America/New_York', hour: 'numeric', minute: '2-digit', hour12: true });
                        const etDate  = now.toLocaleDateString('en-US', { timeZone: 'America/New_York', weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' });

                        // Hourly snapshots (morning 9am, afternoon 3pm, evening 9pm)
                        const hours   = today.hourly || [];
                        const morn    = hours[2]; // index 2 = 600 (6am slot) or pick closest
                        const aftn    = hours[4]; // 1200
                        const even    = hours[6]; // 1800

                        const tmrwDesc  = tmrw ? tmrw.hourly[4]?.weatherDesc[0]?.value : '';
                        const tmrwEmoji = tmrw ? weatherEmoji(tmrwDesc) : '';

                        const msg = [
                          `${emoji} *Good Morning — Daily Weather Briefing*`,
                          `📍 *${city}, ${state}* (ZIP: ${ZIP})`,
                          `📅 ${etDate}  •  ${etTime} ET`,
                          ``,
                          `━━━━━━ 🌡️ *Current Conditions* ━━━━━━`,
                          `${emoji}  ${desc}`,
                          `🌡️  *Temp:* ${cur.temp_F}°F  (feels like ${cur.FeelsLikeF}°F)`,
                          `💧  *Humidity:* ${cur.humidity}%`,
                          `💨  *Wind:* ${cur.windspeedMiles} mph ${cur.winddir16Point}  (${windLabel(cur.windspeedMiles)})`,
                          `👁️  *Visibility:* ${cur.visibility} mi`,
                          `☀️  *UV Index:* ${cur.uvIndex} — ${uvLabel(cur.uvIndex)}`,
                          ``,
                          `━━━━━━ 📊 *Today's Forecast* ━━━━━━`,
                          `🔺 High: ${today.maxtempF}°F   🔻 Low: ${today.mintempF}°F`,
                          `🌅 Sunrise: ${today.astronomy[0].sunrise}   🌇 Sunset: ${today.astronomy[0].sunset}`,
                          morn ? `🕗 Morning (9am): ${morn.tempF}°F — ${morn.weatherDesc[0].value}  🌧️ ${morn.chanceofrain}%` : '',
                          aftn ? `🕒 Afternoon (3pm): ${aftn.tempF}°F — ${aftn.weatherDesc[0].value}  🌧️ ${aftn.chanceofrain}%` : '',
                          even ? `🕘 Evening (9pm): ${even.tempF}°F — ${even.weatherDesc[0].value}  🌧️ ${even.chanceofrain}%` : '',
                          ``,
                          tmrw ? `━━━━━━ 🔮 *Tomorrow* ━━━━━━` : '',
                          tmrw ? `${tmrwEmoji} ${tmrwDesc}` : '',
                          tmrw ? `🔺 High: ${tmrw.maxtempF}°F   🔻 Low: ${tmrw.mintempF}°F   🌧️ Rain: ${tmrw.hourly[4]?.chanceofrain || 0}%` : '',
                          ``,
                          `_Powered by Agentic OS • hq.applaude.net_ 🏠`,
                        ].filter(l => l !== null && l !== undefined).join('\n');

                        // Helper: send msg to one recipient
                        function sendTo(to, label) {
                          return new Promise((resolve) => {
                            const body = JSON.stringify({ to, message: msg });
                            const gwUrl = new URL(GATEWAY);
                            const opts  = {
                              hostname: gwUrl.hostname,
                              port:     parseInt(gwUrl.port) || 80,
                              path:     gwUrl.pathname,
                              method:   'POST',
                              headers:  { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }
                            };
                            const req = http.request(opts, (r) => {
                              let resp = '';
                              r.on('data', d => resp += d);
                              r.on('end', () => {
                                try {
                                  const parsed = JSON.parse(resp);
                                  if (parsed.success) {
                                    console.log(`[WeatherBot] ✅ Sent to ${label}. MsgID: ${parsed.messageId}`);
                                  } else {
                                    console.error(`[WeatherBot] ❌ ${label} error: ${parsed.error}`);
                                  }
                                } catch(e) { console.error(`[WeatherBot] ${label} parse error:`, e.message); }
                                resolve();
                              });
                            });
                            req.on('error', e => { console.error(`[WeatherBot] ${label} request failed:`, e.message); resolve(); });
                            req.write(body);
                            req.end();
                          });
                        }

                        // Send to group then personal number
                        fetchConfig().then(GROUP => {
                          sendTo(GROUP, 'WhatsApp Group')
                            .then(() => sendTo(PERSONAL, 'Personal (' + PERSONAL + ')'))
                            .catch(e => { console.error('[WeatherBot] Fatal:', e.message); process.exit(1); });
                        });

                      } catch (e) {
                        console.error('[WeatherBot] Parse error:', e.message);
                        process.exit(1);
                      }
                    });
                  }).on('error', e => {
                    console.error('[WeatherBot] Fetch error:', e.message);
                    process.exit(1);
                  });
              resources:
                requests:
                  cpu: 50m
                  memory: 64Mi
                limits:
                  cpu: 200m
                  memory: 128Mi
