/**
 * Helix Engage — Weekly Update (Mar 18–25, 2026)
 * Light Mode PowerPoint Generator via PptxGenJS
 */
const PptxGenJS = require("pptxgenjs");

// ── Design Tokens (Light Mode) ─────────────────────────────────────────
const C = {
  bg:         "FFFFFF",
  bgSubtle:   "F8FAFC",
  bgCard:     "F1F5F9",
  bgCardAlt:  "E2E8F0",
  text:       "1E293B",
  textSec:    "475569",
  textMuted:  "94A3B8",
  accent1:    "0EA5E9",  // Sky blue (telephony)
  accent2:    "8B5CF6",  // Violet (server/backend)
  accent3:    "10B981",  // Emerald (UX)
  accent4:    "F59E0B",  // Amber (features)
  accent5:    "EF4444",  // Rose (ops)
  accent6:    "6366F1",  // Indigo (timeline)
  white:      "FFFFFF",
  border:     "CBD5E1",
};

const FONT = {
  heading: "Arial",
  body:    "Arial",
};

// ── Helpers ──────────────────────────────────────────────────────────────
function addSlideNumber(slide, num, total) {
  slide.addText(`${num} / ${total}`, {
    x: 8.8, y: 5.2, w: 1.2, h: 0.3,
    fontSize: 8, color: C.textMuted,
    fontFace: FONT.body,
    align: "right",
  });
}

function addAccentBar(slide, color) {
  slide.addShape("rect", {
    x: 0, y: 0, w: 10, h: 0.06,
    fill: { color },
  });
}

function addLabel(slide, text, color, x, y) {
  slide.addShape("roundRect", {
    x, y, w: text.length * 0.09 + 0.4, h: 0.3,
    fill: { color, transparency: 88 },
    rectRadius: 0.15,
  });
  slide.addText(text.toUpperCase(), {
    x, y, w: text.length * 0.09 + 0.4, h: 0.3,
    fontSize: 7, fontFace: FONT.heading, bold: true,
    color, align: "center", valign: "middle",
    letterSpacing: 2,
  });
}

function addCard(slide, opts) {
  const { x, y, w, h, title, titleColor, items, badge } = opts;
  // Card background
  slide.addShape("roundRect", {
    x, y, w, h,
    fill: { color: C.bgCard },
    line: { color: C.border, width: 0.5 },
    rectRadius: 0.1,
  });
  // Title
  const titleText = badge
    ? [{ text: title + "  ", options: { bold: true, color: titleColor, fontSize: 11 } },
       { text: badge, options: { bold: true, color: C.white, fontSize: 7, highlight: titleColor } }]
    : title;
  slide.addText(titleText, {
    x: x + 0.2, y: y + 0.08, w: w - 0.4, h: 0.35,
    fontSize: 11, fontFace: FONT.heading, bold: true,
    color: titleColor,
  });
  // Items as bullet list
  if (items && items.length > 0) {
    slide.addText(
      items.map(item => ({
        text: item,
        options: {
          fontSize: 8.5, fontFace: FONT.body, color: C.textSec,
          bullet: { type: "bullet", style: "arabicPeriod" },
          paraSpaceAfter: 2,
          breakLine: true,
        },
      })),
      {
        x: x + 0.2, y: y + 0.4, w: w - 0.4, h: h - 0.5,
        valign: "top",
        bullet: { type: "bullet" },
        lineSpacingMultiple: 1.1,
      }
    );
  }
}

// ── Build Presentation ──────────────────────────────────────────────────
async function build() {
  const pptx = new PptxGenJS();
  pptx.layout = "LAYOUT_16x9";
  pptx.author = "Satya Suman Sari";
  pptx.company = "FortyTwo Platform";
  pptx.title = "Helix Engage — Weekly Update (Mar 18–25, 2026)";
  pptx.subject = "Engineering Progress Report";

  const TOTAL = 9;

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 1 — Title
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };

    // Accent bar top
    addAccentBar(slide, C.accent1);

    // Decorative side stripe
    slide.addShape("rect", {
      x: 0, y: 0, w: 0.12, h: 5.63,
      fill: { color: C.accent1 },
    });

    // Label
    addLabel(slide, "Weekly Engineering Update", C.accent1, 3.0, 1.2);

    // Title
    slide.addText("Helix Engage", {
      x: 1.0, y: 1.8, w: 8, h: 1.2,
      fontSize: 44, fontFace: FONT.heading, bold: true,
      color: C.accent1, align: "center",
    });

    // Subtitle
    slide.addText("Contact Center CRM  ·  Real-time Telephony  ·  AI Copilot", {
      x: 1.5, y: 2.9, w: 7, h: 0.5,
      fontSize: 14, fontFace: FONT.body,
      color: C.textSec, align: "center",
    });

    // Date
    slide.addText("March 18 – 25, 2026", {
      x: 3, y: 3.6, w: 4, h: 0.4,
      fontSize: 12, fontFace: FONT.heading, bold: true,
      color: C.textMuted, align: "center",
      letterSpacing: 3,
    });

    // Bottom decoration
    slide.addShape("rect", {
      x: 3.5, y: 4.2, w: 3, h: 0.04,
      fill: { color: C.accent2 },
    });

    // Author
    slide.addText("Satya Suman Sari  ·  FortyTwo Platform", {
      x: 2, y: 4.5, w: 6, h: 0.35,
      fontSize: 9, fontFace: FONT.body,
      color: C.textMuted, align: "center",
    });

    addSlideNumber(slide, 1, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 2 — At a Glance
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent2);

    addLabel(slide, "At a Glance", C.accent2, 0.5, 0.3);

    slide.addText("Week in Numbers", {
      x: 0.5, y: 0.65, w: 5, h: 0.5,
      fontSize: 24, fontFace: FONT.heading, bold: true,
      color: C.text,
    });

    // Stat cards
    const stats = [
      { value: "78",  label: "Total Commits",    color: C.accent1 },
      { value: "3",   label: "Repositories",      color: C.accent2 },
      { value: "8",   label: "Days Active",        color: C.accent3 },
      { value: "50",  label: "Frontend Commits",   color: C.accent4 },
    ];

    stats.forEach((s, i) => {
      const x = 0.5 + i * 2.35;
      // Card bg
      slide.addShape("roundRect", {
        x, y: 1.3, w: 2.1, h: 1.7,
        fill: { color: C.bgCard },
        line: { color: C.border, width: 0.5 },
        rectRadius: 0.12,
      });
      // Accent top line
      slide.addShape("rect", {
        x: x + 0.2, y: 1.35, w: 1.7, h: 0.035,
        fill: { color: s.color },
      });
      // Number
      slide.addText(s.value, {
        x, y: 1.5, w: 2.1, h: 0.9,
        fontSize: 36, fontFace: FONT.heading, bold: true,
        color: s.color, align: "center", valign: "middle",
      });
      // Label
      slide.addText(s.label, {
        x, y: 2.4, w: 2.1, h: 0.4,
        fontSize: 9, fontFace: FONT.body,
        color: C.textSec, align: "center",
      });
    });

    // Repo breakdown pills
    const repos = [
      { name: "helix-engage", count: "50", clr: C.accent1 },
      { name: "helix-engage-server", count: "27", clr: C.accent2 },
      { name: "FortyTwoApps/SDK", count: "1", clr: C.accent3 },
    ];
    repos.forEach((r, i) => {
      const x = 1.5 + i * 2.8;
      slide.addShape("roundRect", {
        x, y: 3.4, w: 2.5, h: 0.4,
        fill: { color: C.bgCard },
        line: { color: r.clr, width: 1 },
        rectRadius: 0.2,
      });
      slide.addText(`${r.name}  ${r.count}`, {
        x, y: 3.4, w: 2.5, h: 0.4,
        fontSize: 9, fontFace: FONT.heading, bold: true,
        color: r.clr, align: "center", valign: "middle",
      });
    });

    // Summary text
    slide.addText("3 repos ·  7 working days ·  78 commits shipped to production", {
      x: 1, y: 4.2, w: 8, h: 0.35,
      fontSize: 10, fontFace: FONT.body, italic: true,
      color: C.textMuted, align: "center",
    });

    addSlideNumber(slide, 2, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 3 — Telephony & SIP
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent1);

    addLabel(slide, "Core Infrastructure", C.accent1, 0.5, 0.3);

    slide.addText([
      { text: "☎  ", options: { fontSize: 22 } },
      { text: "Telephony & SIP Overhaul", options: { fontSize: 22, bold: true, color: C.text } },
    ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading });

    addCard(slide, {
      x: 0.3, y: 1.35, w: 4.5, h: 2.0,
      title: "Outbound Calling", titleColor: C.accent1, badge: "Frontend",
      items: [
        "Direct SIP call from browser — no Kookoo bridge",
        "Immediate call card UI with auto-answer SIP bridge",
        "End Call label fix, force active state after auto-answer",
        "Reset outboundPending on call end",
      ],
    });

    addCard(slide, {
      x: 5.2, y: 1.35, w: 4.5, h: 2.0,
      title: "Ozonetel Integration", titleColor: C.accent2, badge: "Server",
      items: [
        "Ozonetel V3 dial endpoint + webhook handler",
        "Set Disposition API for ACW release",
        "Force Ready endpoint for agent state mgmt",
        "Token: 10-min cache, 401 invalidation, refresh on login",
      ],
    });

    addCard(slide, {
      x: 0.3, y: 3.55, w: 4.5, h: 1.8,
      title: "SIP & Agent State", titleColor: C.accent1, badge: "Frontend",
      items: [
        "SIP driven by Agent entity with token refresh",
        "Centralised outbound dial into useSip().dialOutbound()",
        "UCID tracking from SIP headers for disposition",
        "Network indicator for connection health",
      ],
    });

    addCard(slide, {
      x: 5.2, y: 3.55, w: 4.5, h: 1.8,
      title: "Multi-Agent & Sessions", titleColor: C.accent2, badge: "Server",
      items: [
        "Multi-agent SIP with Redis session lockout",
        "Strict duplicate login — one device per agent",
        "Session lock stores IP + timestamp for debugging",
        "SSE agent state broadcast for supervisor view",
      ],
    });

    addSlideNumber(slide, 3, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 4 — Call Desk & Agent UX
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent3);

    addLabel(slide, "User Experience", C.accent3, 0.5, 0.3);

    slide.addText([
      { text: "🖥  ", options: { fontSize: 22 } },
      { text: "Call Desk & Agent UX", options: { fontSize: 22, bold: true, color: C.text } },
    ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading });

    addCard(slide, {
      x: 0.3, y: 1.35, w: 3.05, h: 2.6,
      title: "Call Desk Redesign", titleColor: C.accent3,
      items: [
        "2-panel layout with collapsible sidebar & inline AI",
        "Collapsible context panel, worklist/calls tabs",
        "Pinned header & chat input, numpad dialler",
        "Ringtone support for incoming calls",
      ],
    });

    addCard(slide, {
      x: 3.55, y: 1.35, w: 3.05, h: 2.6,
      title: "Post-Call Workflow", titleColor: C.accent3,
      items: [
        "Disposition → appointment booking → follow-up",
        "Disposition returns straight to worklist",
        "Send disposition to sidecar with UCID for ACW",
        "Enquiry in post-call, appointment skip button",
      ],
    });

    addCard(slide, {
      x: 6.8, y: 1.35, w: 2.9, h: 2.6,
      title: "UI Polish", titleColor: C.accent3,
      items: [
        "FontAwesome Pro Duotone icon migration",
        "Tooltips, sticky headers, roles, search",
        "Fix React error #520 in prod tables",
        "AI scroll containment, brand tokens refresh",
      ],
    });

    addSlideNumber(slide, 4, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 5 — Features Shipped
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent4);

    addLabel(slide, "Features Shipped", C.accent4, 0.5, 0.3);

    slide.addText([
      { text: "🚀  ", options: { fontSize: 22 } },
      { text: "Major Features", options: { fontSize: 22, bold: true, color: C.text } },
    ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading });

    addCard(slide, {
      x: 0.3, y: 1.35, w: 4.5, h: 2.0,
      title: "Supervisor Module", titleColor: C.accent4,
      items: [
        "Team performance analytics page",
        "Live monitor with active calls visibility",
        "Master data management pages",
        "Server: team perf + active calls endpoints",
      ],
    });

    addCard(slide, {
      x: 5.2, y: 1.35, w: 4.5, h: 2.0,
      title: "Missed Call Queue (Phase 2)", titleColor: C.accent4,
      items: [
        "Missed call queue ingestion & worklist",
        "Auto-assignment engine for agents",
        "Login redesign with role-based routing",
        "Lead lookup for missed callers",
      ],
    });

    addCard(slide, {
      x: 0.3, y: 3.55, w: 4.5, h: 1.8,
      title: "Agent Features (Phase 1)", titleColor: C.accent4,
      items: [
        "Agent status toggle (Ready / Not Ready / Break)",
        "Global search across patients, leads, calls",
        "Enquiry form for new patient intake",
        "My Performance page + logout modal",
      ],
    });

    addCard(slide, {
      x: 5.2, y: 3.55, w: 4.5, h: 1.8,
      title: "Recording Analysis", titleColor: C.accent4,
      items: [
        "Deepgram diarization + AI insights",
        "Redis caching layer for analysis results",
        "Full-stack: frontend player + server module",
      ],
    });

    addSlideNumber(slide, 5, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 6 — Backend & Data
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent2);

    addLabel(slide, "Backend & Data", C.accent2, 0.5, 0.3);

    slide.addText([
      { text: "⚙  ", options: { fontSize: 22 } },
      { text: "Backend & Data Layer", options: { fontSize: 22, bold: true, color: C.text } },
    ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading });

    addCard(slide, {
      x: 0.3, y: 1.35, w: 4.5, h: 2.0,
      title: "Platform Data Wiring", titleColor: C.accent2,
      items: [
        "Migrated frontend to Jotai + Vercel AI SDK",
        "Corrected all 7 GraphQL queries (fields, LINKS/PHONES)",
        "Webhook handler for Ozonetel call records",
        "Complete seeder: 5 doctors, appointments linked",
      ],
    });

    addCard(slide, {
      x: 5.2, y: 1.35, w: 4.5, h: 2.0,
      title: "Server Endpoints", titleColor: C.accent2,
      items: [
        "Call control, recording, CDR, missed calls, live assist",
        "Agent summary, AHT, performance aggregation",
        "Token refresh endpoint for auto-renewal",
        "Search module with full-text capabilities",
      ],
    });

    addCard(slide, {
      x: 0.3, y: 3.55, w: 4.5, h: 1.8,
      title: "Data Pages Built", titleColor: C.accent2,
      items: [
        "Worklist table, call history, patients, dashboard",
        "Reports, team dashboard, campaigns, settings",
        "Agent detail page, campaign edit slideout",
        "Appointments page with data refresh on login",
      ],
    });

    addCard(slide, {
      x: 5.2, y: 3.55, w: 4.5, h: 1.8,
      title: "SDK App", titleColor: C.accent3, badge: "FortyTwoApps",
      items: [
        "Helix Engage SDK app entity definitions",
        "Call center CRM object model for platform",
        "Foundation for platform-native data integration",
      ],
    });

    addSlideNumber(slide, 6, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 7 — Deployment & Ops
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent5);

    addLabel(slide, "Operations", C.accent5, 0.5, 0.3);

    slide.addText([
      { text: "🛠  ", options: { fontSize: 22 } },
      { text: "Deployment & DevOps", options: { fontSize: 22, bold: true, color: C.text } },
    ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading });

    addCard(slide, {
      x: 0.3, y: 1.35, w: 3.05, h: 2.2,
      title: "Deployment", titleColor: C.accent5,
      items: [
        "Deployed to Hostinger VPS with Docker",
        "Switched to global_healthx Ozonetel account",
        "Dockerfile for server-side containerization",
      ],
    });

    addCard(slide, {
      x: 3.55, y: 1.35, w: 3.05, h: 2.2,
      title: "AI & Testing", titleColor: C.accent5,
      items: [
        "Migrated AI to Vercel AI SDK + OpenAI provider",
        "AI flow test script — validates full pipeline",
        "Live call assist integration",
      ],
    });

    addCard(slide, {
      x: 6.8, y: 1.35, w: 2.9, h: 2.2,
      title: "Documentation", titleColor: C.accent5,
      items: [
        "Team onboarding README with arch guide",
        "Supervisor module spec + plan",
        "Multi-agent spec + plan",
        "Next session plans in commits",
      ],
    });

    addSlideNumber(slide, 7, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 8 — Timeline
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent6);

    addLabel(slide, "Day by Day", C.accent6, 0.5, 0.3);

    slide.addText([
      { text: "📅  ", options: { fontSize: 22 } },
      { text: "Development Timeline", options: { fontSize: 22, bold: true, color: C.text } },
    ], { x: 0.5, y: 0.65, w: 9, h: 0.5, fontFace: FONT.heading });

    const timeline = [
      { date: "MAR 18 (Tue)", title: "Foundation Day", desc: "Call desk redesign, Jotai + AI SDK migration, seeder, AI flow test, VPS deploy" },
      { date: "MAR 19 (Wed)", title: "Data Layer Sprint", desc: "All data pages, post-call workflow, GraphQL fixes, Kookoo IVR, outbound UI" },
      { date: "MAR 20 (Thu)", title: "Telephony Breakthrough", desc: "Direct SIP replacing Kookoo, UCID tracking, Force Ready, Set Disposition" },
      { date: "MAR 21 (Fri)", title: "Agent Experience", desc: "Phase 1: status toggle, search, enquiry form, My Performance, FA icons, AHT" },
      { date: "MAR 23 (Sun)", title: "Scale & Reliability", desc: "Phase 2: missed call queue, auto-assign, Redis lockout, Patient 360, SDK defs" },
      { date: "MAR 24 (Mon)", title: "Supervisor Module", desc: "Team perf, live monitor, master data, SSE, UUID fix, maintenance, QA sweep" },
      { date: "MAR 25 (Tue)", title: "Intelligence Layer", desc: "Deepgram diarization, AI insights, SIP via Agent entity, token refresh, network" },
    ];

    // Vertical line
    slide.addShape("rect", {
      x: 1.4, y: 1.3, w: 0.025, h: 4.0,
      fill: { color: C.accent6, transparency: 60 },
    });

    timeline.forEach((entry, i) => {
      const y = 1.3 + i * 0.56;

      // Dot
      slide.addShape("ellipse", {
        x: 1.32, y: y + 0.08, w: 0.18, h: 0.18,
        fill: { color: C.accent6 },
        line: { color: C.bg, width: 2 },
      });

      // Date
      slide.addText(entry.date, {
        x: 1.7, y: y, w: 1.6, h: 0.22,
        fontSize: 7, fontFace: FONT.heading, bold: true,
        color: C.accent6,
      });

      // Title
      slide.addText(entry.title, {
        x: 3.3, y: y, w: 2.0, h: 0.22,
        fontSize: 9, fontFace: FONT.heading, bold: true,
        color: C.text,
      });

      // Description
      slide.addText(entry.desc, {
        x: 5.3, y: y, w: 4.2, h: 0.45,
        fontSize: 8, fontFace: FONT.body,
        color: C.textSec,
        valign: "top",
      });
    });

    addSlideNumber(slide, 8, TOTAL);
  }

  // ═══════════════════════════════════════════════════════════════════════
  // SLIDE 9 — Closing
  // ═══════════════════════════════════════════════════════════════════════
  {
    const slide = pptx.addSlide();
    slide.background = { color: C.bg };
    addAccentBar(slide, C.accent3);

    // Big headline
    slide.addText("78 commits.  8 days.  Ship mode.", {
      x: 0.5, y: 1.4, w: 9, h: 0.8,
      fontSize: 32, fontFace: FONT.heading, bold: true,
      color: C.accent3, align: "center",
    });

    // Ship emoji
    slide.addText("🚢", {
      x: 4.2, y: 2.3, w: 1.6, h: 0.6,
      fontSize: 28, align: "center",
    });

    // Description
    slide.addText(
      "From browser-native SIP calling to AI-powered recording analysis — Helix Engage is becoming a production contact center platform.",
      {
        x: 1.5, y: 3.0, w: 7, h: 0.6,
        fontSize: 11, fontFace: FONT.body,
        color: C.textSec, align: "center",
        lineSpacingMultiple: 1.3,
      }
    );

    // Achievement pills
    const achievements = [
      { text: "SIP Calling  ✓", color: C.accent1 },
      { text: "Multi-Agent  ✓", color: C.accent2 },
      { text: "Supervisor  ✓", color: C.accent3 },
      { text: "AI Copilot  ✓", color: C.accent4 },
      { text: "Recording Analysis  ✓", color: C.accent5 },
    ];

    achievements.forEach((a, i) => {
      const x = 0.8 + i * 1.8;
      slide.addShape("roundRect", {
        x, y: 3.9, w: 1.6, h: 0.35,
        fill: { color: C.bgCard },
        line: { color: a.color, width: 1 },
        rectRadius: 0.17,
      });
      slide.addText(a.text, {
        x, y: 3.9, w: 1.6, h: 0.35,
        fontSize: 8, fontFace: FONT.heading, bold: true,
        color: a.color, align: "center", valign: "middle",
      });
    });

    // Author
    slide.addText("Satya Suman Sari  ·  FortyTwo Platform", {
      x: 2, y: 4.7, w: 6, h: 0.3,
      fontSize: 9, fontFace: FONT.body,
      color: C.textMuted, align: "center",
    });

    addSlideNumber(slide, 9, TOTAL);
  }

  // ── Save ──────────────────────────────────────────────────────────────
  const outPath = "weekly-update-mar18-25.pptx";
  await pptx.writeFile({ fileName: outPath });
  console.log(`✅ Presentation saved: ${outPath}`);
}

build().catch(err => {
  console.error("❌ Failed:", err.message);
  process.exit(1);
});
