const express = require('express');
const cron    = require('node-cron');
const fs      = require('fs');
const http    = require('http');
const path    = require('path');

const app = express();
app.use(express.json());

const DATA_FILE = process.env.DATA_FILE    || '/data/reminders.json';
const GATEWAY   = process.env.GATEWAY_URL  || 'http://whatsapp-gateway.ai-agents.svc.cluster.local:5001/send-message';
const PERSONAL  = process.env.PERSONAL_NUM;
const GROUP     = process.env.GROUP_URL;
const PORT      = parseInt(process.env.PORT) || 6001;

// ── Persistence ──────────────────────────────────────────────────────────────

function load() {
  try { return JSON.parse(fs.readFileSync(DATA_FILE, 'utf8')); }
  catch { return []; }
}

function save(reminders) {
  fs.mkdirSync(path.dirname(DATA_FILE), { recursive: true });
  fs.writeFileSync(DATA_FILE, JSON.stringify(reminders, null, 2));
}

// ── WhatsApp delivery ─────────────────────────────────────────────────────────

function sendWhatsApp(to, message) {
  return new Promise((resolve) => {
    const body = JSON.stringify({ to, message });
    const url  = new URL(GATEWAY);
    const opts = {
      hostname: url.hostname,
      port:     parseInt(url.port) || 80,
      path:     url.pathname,
      method:   'POST',
      headers:  { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) }
    };
    const req = http.request(opts, r => {
      let d = '';
      r.on('data', c => d += c);
      r.on('end', () => {
        try { resolve(JSON.parse(d)); }
        catch { resolve({ success: false, error: 'parse error' }); }
      });
    });
    req.on('error', e => resolve({ success: false, error: e.message }));
    req.write(body);
    req.end();
  });
}

// ── Routes ────────────────────────────────────────────────────────────────────

// POST /reminders  — schedule a new reminder
app.post('/reminders', (req, res) => {
  const { message, sendAt, to, label } = req.body;

  if (!message || !sendAt) {
    return res.status(400).json({ error: 'message and sendAt are required' });
  }

  const sendAtDate = new Date(sendAt);
  if (isNaN(sendAtDate.getTime())) {
    return res.status(400).json({ error: 'sendAt is not a valid ISO date string' });
  }
  if (sendAtDate <= new Date()) {
    return res.status(400).json({ error: 'sendAt must be in the future' });
  }

  const reminders = load();
  const id = `rem_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;

  reminders.push({
    id,
    message,
    sendAt:    sendAtDate.toISOString(),
    to:        to || PERSONAL,
    label:     label || message.slice(0, 60),
    status:    'pending',
    createdAt: new Date().toISOString(),
  });

  save(reminders);
  console.log(`[Reminder] Scheduled ${id}: "${label || message.slice(0, 40)}" → ${sendAtDate.toISOString()}`);
  res.json({ success: true, id, sendAt: sendAtDate.toISOString() });
});

// POST /reminders/batch  — schedule multiple reminders at once
app.post('/reminders/batch', (req, res) => {
  const { items } = req.body; // [{ message, sendAt, to, label }]
  if (!Array.isArray(items) || items.length === 0) {
    return res.status(400).json({ error: 'items array is required' });
  }

  const reminders = load();
  const created   = [];
  const errors    = [];

  for (const item of items) {
    const { message, sendAt, to, label } = item;
    if (!message || !sendAt) { errors.push({ item, error: 'missing fields' }); continue; }
    const sendAtDate = new Date(sendAt);
    if (isNaN(sendAtDate.getTime()) || sendAtDate <= new Date()) {
      errors.push({ item, error: 'invalid or past sendAt' }); continue;
    }
    const id = `rem_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
    reminders.push({
      id,
      message,
      sendAt:    sendAtDate.toISOString(),
      to:        to || PERSONAL,
      label:     label || message.slice(0, 60),
      status:    'pending',
      createdAt: new Date().toISOString(),
    });
    created.push({ id, sendAt: sendAtDate.toISOString(), label: label || message.slice(0, 40) });
  }

  save(reminders);
  console.log(`[Reminder] Batch: ${created.length} scheduled, ${errors.length} failed`);
  res.json({ success: true, created, errors });
});

// GET /reminders  — list reminders
app.get('/reminders', (req, res) => {
  const all    = load();
  const status = req.query.status; // optional filter: pending|sent|cancelled|failed
  const result = status ? all.filter(r => r.status === status) : all;
  res.json(result.slice(-100)); // last 100
});

// DELETE /reminders/:id  — cancel a reminder
app.delete('/reminders/:id', (req, res) => {
  const reminders = load();
  const idx = reminders.findIndex(r => r.id === req.params.id);
  if (idx === -1) return res.status(404).json({ error: 'not found' });
  if (reminders[idx].status !== 'pending') {
    return res.status(409).json({ error: `Cannot cancel — status is "${reminders[idx].status}"` });
  }
  reminders[idx].status = 'cancelled';
  save(reminders);
  console.log(`[Reminder] Cancelled ${req.params.id}`);
  res.json({ success: true });
});

// GET /health
app.get('/health', (req, res) => res.json({ status: 'ok', time: new Date().toISOString() }));

// ── Scheduler (every minute) ──────────────────────────────────────────────────

cron.schedule('* * * * *', async () => {
  const now       = new Date();
  const reminders = load();
  let changed     = false;

  for (const r of reminders) {
    if (r.status !== 'pending') continue;
    if (new Date(r.sendAt) > now) continue;

    console.log(`[Reminder] Firing ${r.id}: "${r.label}" → ${r.to}`);
    const result = await sendWhatsApp(r.to, r.message);

    r.status = result.success ? 'sent' : 'failed';
    r.sentAt = now.toISOString();
    if (!result.success) r.error = result.error;
    changed = true;

    console.log(`[Reminder] ${result.success ? '✅' : '❌'} ${r.id} ${result.success ? result.messageId : r.error}`);
  }

  if (changed) save(reminders);
});

app.listen(PORT, () => {
  console.log(`[ReminderService] Listening on :${PORT}`);
  console.log(`[ReminderService] Data: ${DATA_FILE} | Gateway: ${GATEWAY}`);
  const pending = load().filter(r => r.status === 'pending').length;
  console.log(`[ReminderService] Loaded ${pending} pending reminder(s).`);
});
