← back to Designer Wallcoverings

DW-Agents/dw-agents/marketing-agent.ts.backup-pre-theme

1989 lines

/**
 * DW-Agents: Marketing Agent
 *
 * AI-powered marketing content creation and management:
 * 1. View and manage Shopify blog posts
 * 2. Create compelling blog posts from new SKUs
 * 3. Generate social media content (Instagram, Facebook)
 * 4. Draft email campaigns (Constant Contact integration)
 * 5. Chat interface for content creation assistance
 *
 * Port: 9881
 */

import Anthropic from '@anthropic-ai/sdk';
import express from 'express';
import { requireAuth as ssoAuth, handleLogin, setSSOToken, SSO_TOKEN_NAME, SSO_TOKEN_VALUE } from './shared-auth.js';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import fetch from 'node-fetch';
import { AgentMemory } from './shared-memory-system.js';

const app = express();
const PORT = 9881;
// Initialize agent memory system
const agentMemory = new AgentMemory('marketing');
console.log('📚 Memory system initialized for marketing');


// Authentication
const AUTH_USERNAME = 'admin';
const AUTH_PASSWORD = '2025';

// Shopify configuration
const SHOPIFY_STORE = process.env.SHOPIFY_STORE_DOMAIN || 'designer-laboratory-sandbox.myshopify.com';
const SHOPIFY_TOKEN = process.env.SHOPIFY_ACCESS_TOKEN || 'shpat_REDACTED';
const API_VERSION = '2024-07';

// Constant Contact configuration (placeholder)
const CC_API_KEY = process.env.CONSTANT_CONTACT_API_KEY || '';
const CC_ACCESS_TOKEN = process.env.CONSTANT_CONTACT_ACCESS_TOKEN || '';

// Anthropic Claude
const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY || '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'
});

// Types for Shopify orders
interface OrderLineItem {
  title: string;
  sku: string;
  quantity: number;
  price?: string;
}

interface ShopifyOrder {
  id: string;
  name: string;
  createdAt: string;
  totalPriceSet: {
    shopMoney: {
      amount: string;
      currencyCode: string;
    }
  };
  displayFinancialStatus: string;
  displayFulfillmentStatus: string;
  lineItems: {
    edges: Array<{
      node: OrderLineItem;
    }>;
  };
}

// Stats tracking
let stats = {
  totalConversations: 0,
  blogPostsCreated: 0,
  socialPostsGenerated: 0,
  emailCampaignsDrafted: 0,
  lastBlogPost: null as { title: string; sku: string; timestamp: Date } | null,
  recentBlogs: [] as Array<{
    id: string;
    title: string;
    createdAt: string;
    publishedAt: string | null;
    tags: string;
  }>,
  recentProducts: [] as Array<{
    id: string;
    title: string;
    sku: string;
    vendor: string;
    handle: string;
    imageUrl: string;
  }>,
  // New order tracking stats
  recentOrders: [] as ShopifyOrder[],
  orderTrends: {
    totalRevenue: number;
    orderCount: number;
    averageOrderValue: number;
    topProducts: [] as Array<{
      title: string;
      sku: string;
      totalQuantity: number;
      revenue: number;
    }>,
    dailyRevenue: [] as Array<{
      date: string;
      revenue: number;
      orderCount: number;
    }>
  }
};

app.use(express.json());
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));

app.use(
  session({
    secret: 'dw-marketing-agent-2025',
    resave: false,
    saveUninitialized: true,
    rolling: true,
    cookie: {
      secure: false,
      httpOnly: true,
      maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days
    },
  })
);

declare module 'express-session' {
  interface SessionData {
    authenticated: boolean;
    chatHistory: Array<{ role: 'user' | 'assistant', content: string }>;
  }
}

const requireAuth = (req: express.Request, res: express.Response, next: express.NextFunction) => {
  // TEMPORARY: Auth disabled for 4 hours
  return next();

  /* Original auth:

  if (req.session.authenticated) {
    next();
  } else {
    res.redirect('/login');
  }
  */
};

// Shopify API helper
async function shopifyGraphQL(query: string, variables?: any) {
  const response = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/graphql.json`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Shopify-Access-Token': SHOPIFY_TOKEN,
    },
    body: JSON.stringify({ query, variables }),
  });
  return response.json();
}

// Fetch and analyze Shopify orders for marketing insights
async function fetchAndAnalyzeOrders() {
  const query = `
    query {
      orders(first: 50, reverse: true, sortKey: CREATED_AT) {
        edges {
          node {
            id
            name
            createdAt
            totalPriceSet {
              shopMoney {
                amount
                currencyCode
              }
            }
            displayFinancialStatus
            displayFulfillmentStatus
            lineItems(first: 20) {
              edges {
                node {
                  title
                  sku
                  quantity
                  originalUnitPriceSet {
                    shopMoney {
                      amount
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  `;

  try {
    const response = await shopifyGraphQL(query);

    if (response.data?.orders?.edges) {
      const orders = response.data.orders.edges.map((edge: any) => edge.node);
      stats.recentOrders = orders;

      // Analyze order trends
      analyzeOrderTrends(orders);

      return orders;
    }
    return [];
  } catch (error) {
    console.error('Error fetching orders:', error);
    return [];
  }
}

// Analyze order data for marketing insights
function analyzeOrderTrends(orders: ShopifyOrder[]) {
  // Reset trends
  stats.orderTrends = {
    totalRevenue: 0,
    orderCount: orders.length,
    averageOrderValue: 0,
    topProducts: [],
    dailyRevenue: []
  };

  // Product aggregation map
  const productMap = new Map<string, {
    title: string;
    sku: string;
    totalQuantity: number;
    revenue: number;
  }>();

  // Daily revenue map
  const dailyMap = new Map<string, {
    revenue: number;
    orderCount: number;
  }>();

  // Process each order
  orders.forEach(order => {
    const orderAmount = parseFloat(order.totalPriceSet.shopMoney.amount);
    stats.orderTrends.totalRevenue += orderAmount;

    // Extract date (YYYY-MM-DD)
    const orderDate = order.createdAt.split('T')[0];
    if (!dailyMap.has(orderDate)) {
      dailyMap.set(orderDate, { revenue: 0, orderCount: 0 });
    }
    const dailyData = dailyMap.get(orderDate)!;
    dailyData.revenue += orderAmount;
    dailyData.orderCount += 1;

    // Process line items
    order.lineItems.edges.forEach(edge => {
      const item = edge.node;
      const key = item.sku || item.title;

      if (!productMap.has(key)) {
        productMap.set(key, {
          title: item.title,
          sku: item.sku || 'N/A',
          totalQuantity: 0,
          revenue: 0
        });
      }

      const product = productMap.get(key)!;
      product.totalQuantity += item.quantity;
      if (item.price) {
        product.revenue += parseFloat(item.price) * item.quantity;
      }
    });
  });

  // Calculate average order value
  stats.orderTrends.averageOrderValue = orders.length > 0
    ? stats.orderTrends.totalRevenue / orders.length
    : 0;

  // Convert product map to sorted array (top 10 by quantity)
  stats.orderTrends.topProducts = Array.from(productMap.values())
    .sort((a, b) => b.totalQuantity - a.totalQuantity)
    .slice(0, 10);

  // Convert daily map to sorted array (last 7 days)
  stats.orderTrends.dailyRevenue = Array.from(dailyMap.entries())
    .map(([date, data]) => ({
      date,
      revenue: data.revenue,
      orderCount: data.orderCount
    }))
    .sort((a, b) => b.date.localeCompare(a.date))
    .slice(0, 7);
}

// Load orders on startup
fetchAndAnalyzeOrders().then(() => {
  console.log(`📊 Loaded ${stats.recentOrders.length} orders for analysis`);
});

// Refresh orders every 30 minutes
setInterval(() => {
  fetchAndAnalyzeOrders();
}, 30 * 60 * 1000);

// Login page
app.get('/login', (req, res) => {
  res.send(`
<!DOCTYPE html>
<html>
<head>
  <title>Login - Marketing Agent</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
    }
    .login-container {
      background: white;
      padding: 40px;
      border-radius: 15px;
      box-shadow: 0 15px 35px rgba(0,0,0,0.2);
      max-width: 400px;
      width: 100%;
    }
    h1 { color: #f5576c; text-align: center; margin-bottom: 30px; }
    input {
      width: 100%;
      padding: 12px;
      margin: 10px 0;
      border: 2px solid #e0e0e0;
      border-radius: 8px;
    }
    button {
      width: 100%;
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
      color: white;
      border: none;
      padding: 15px;
      border-radius: 8px;
      cursor: pointer;
      font-weight: 600;
      margin-top: 10px;
    }
    .error { color: red; text-align: center; margin-bottom: 15px; }
  </style>
</head>
<body>
  <div class="login-container">
    <h1>📢 Marketing Agent</h1>
    <p style="text-align: center; color: #666; margin-bottom: 20px;">Content Creation & Campaigns</p>
    ${req.query.error ? '<div class="error">Invalid credentials</div>' : ''}
    <form method="POST">
      <input type="text" name="username" placeholder="Username" required>
      <input type="password" name="password" placeholder="Password" required>
      <button type="submit">Login</button>
    </form>
  </div>
</body>
</html>
  `);
});

app.post('/login', (req, res) => {
  const { username, password } = req.body;
  if (username === AUTH_USERNAME && password === AUTH_PASSWORD) {
    req.session.authenticated = true;
    req.session.chatHistory = [];
    res.redirect('/');
  } else {
    res.redirect('/login?error=1');
  }
});

app.get('/logout', (req, res) => {
  req.session.destroy(() => res.redirect('/login'));
});

// Main dashboard
app.get('/', requireAuth, async (req, res) => {
  res.send(`
<!DOCTYPE html>
<html>
<head>
  <title>Marketing Agent - DW-Agents</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
      padding: 20px;
      min-height: 100vh;
    }
    .container {
      max-width: 1600px;
      margin: 0 auto;
      display: grid;
      grid-template-columns: 400px 1fr;
      gap: 20px;
    }

    /* Mobile-responsive sidebar */
    .sidebar {
      display: flex;
      flex-direction: column;
      gap: 20px;
    }
    .sidebar-toggle {
      display: none;
      position: fixed;
      top: 20px;
      left: 20px;
      z-index: 1001;
      background: white;
      border: none;
      border-radius: 50%;
      width: 50px;
      height: 50px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.2);
      cursor: pointer;
      font-size: 1.5em;
      color: #f5576c;
      transition: transform 0.3s;
    }
    .sidebar-toggle:hover {
      transform: scale(1.1);
    }
    .sidebar-toggle:focus {
      outline: 3px solid #f5576c;
      outline-offset: 2px;
    }

    .header {
      background: white;
      padding: 30px;
      border-radius: 15px;
      box-shadow: 0 5px 20px rgba(0,0,0,0.1);
    }
    .header h1 { color: #d8194e; font-size: 2em; margin-bottom: 10px; }
    .header .subtitle { color: #333; font-size: 1.1em; }
    .stats-card {
      background: white;
      padding: 20px;
      border-radius: 15px;
      box-shadow: 0 5px 20px rgba(0,0,0,0.1);
    }
    .stats-card h3 { color: #555; font-size: 0.85em; text-transform: uppercase; margin-bottom: 8px; }
    .stats-card .value { font-size: 2em; font-weight: bold; color: #d8194e; }
    .main-content {
      display: flex;
      flex-direction: column;
      gap: 20px;
    }
    .tab-container {
      background: white;
      border-radius: 15px;
      box-shadow: 0 5px 20px rgba(0,0,0,0.1);
      overflow: hidden;
    }

    /* Scrollable tabs for mobile */
    .tabs {
      display: flex;
      background: #f5f5f5;
      border-bottom: 2px solid #e0e0e0;
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
      scrollbar-width: thin;
    }
    .tabs::-webkit-scrollbar {
      height: 4px;
    }
    .tabs::-webkit-scrollbar-track {
      background: #f1f1f1;
    }
    .tabs::-webkit-scrollbar-thumb {
      background: #f5576c;
      border-radius: 4px;
    }
    .tab {
      flex: 1;
      min-width: 140px;
      padding: 15px;
      text-align: center;
      cursor: pointer;
      font-weight: 600;
      color: #333;
      transition: all 0.3s;
      white-space: nowrap;
    }
    .tab:hover {
      background: #f0f0f0;
    }
    .tab:focus {
      outline: 3px solid #f5576c;
      outline-offset: -3px;
      z-index: 1;
    }
    .tab.active {
      background: white;
      color: #d8194e;
      border-bottom: 3px solid #d8194e;
    }
    .tab-content {
      padding: 30px;
      display: none;
    }
    .tab-content.active {
      display: block;
    }

    /* Loading spinner */
    .spinner {
      display: inline-block;
      width: 20px;
      height: 20px;
      border: 3px solid rgba(255,255,255,0.3);
      border-radius: 50%;
      border-top-color: white;
      animation: spin 0.8s linear infinite;
    }
    @keyframes spin {
      to { transform: rotate(360deg); }
    }
    .loading-overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(0,0,0,0.5);
      display: none;
      justify-content: center;
      align-items: center;
      z-index: 9999;
    }
    .loading-overlay.active {
      display: flex;
    }
    .loading-content {
      background: white;
      padding: 30px 40px;
      border-radius: 15px;
      text-align: center;
      box-shadow: 0 10px 40px rgba(0,0,0,0.3);
    }
    .loading-spinner {
      width: 50px;
      height: 50px;
      border: 4px solid #f0f0f0;
      border-top-color: #f5576c;
      border-radius: 50%;
      animation: spin 0.8s linear infinite;
      margin: 0 auto 15px;
    }

    /* Toast notifications */
    .toast {
      position: fixed;
      top: 20px;
      right: 20px;
      background: white;
      padding: 16px 24px;
      border-radius: 10px;
      box-shadow: 0 8px 24px rgba(0,0,0,0.2);
      display: flex;
      align-items: center;
      gap: 12px;
      z-index: 10000;
      transform: translateX(400px);
      transition: transform 0.3s ease-out;
      max-width: 350px;
    }
    .toast.show {
      transform: translateX(0);
    }
    .toast.error {
      border-left: 4px solid #dc3545;
    }
    .toast.success {
      border-left: 4px solid #28a745;
    }
    .toast.info {
      border-left: 4px solid #17a2b8;
    }
    .toast-icon {
      font-size: 1.5em;
      flex-shrink: 0;
    }
    .toast-message {
      flex: 1;
      color: #333;
      line-height: 1.4;
    }
    .toast-close {
      background: none;
      border: none;
      color: #888;
      cursor: pointer;
      font-size: 1.2em;
      padding: 0;
      width: 24px;
      height: 24px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
      flex-shrink: 0;
    }
    .toast-close:hover {
      background: #f0f0f0;
      color: #333;
    }
    .toast-close:focus {
      outline: 2px solid #f5576c;
    }

    .chat-container {
      height: 500px;
      display: flex;
      flex-direction: column;
    }
    .chat-messages {
      flex: 1;
      overflow-y: auto;
      padding: 20px;
      background: #f5f5f5;
      border-radius: 10px;
      margin-bottom: 20px;
    }
    .message {
      margin-bottom: 15px;
      display: flex;
      gap: 10px;
    }
    .message.user {
      flex-direction: row-reverse;
    }
    .message-avatar {
      width: 40px;
      height: 40px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.2em;
      flex-shrink: 0;
    }
    .message.user .message-avatar {
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
    }
    .message.assistant .message-avatar {
      background: #e0e0e0;
    }
    .message-content {
      max-width: 70%;
      padding: 12px 16px;
      border-radius: 12px;
      line-height: 1.5;
    }
    .message.user .message-content {
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
      color: white;
      border-bottom-right-radius: 4px;
    }
    .message.assistant .message-content {
      background: white;
      color: #1a1a1a;
      border-bottom-left-radius: 4px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }
    .chat-input-container {
      display: flex;
      gap: 10px;
    }
    #chatInput {
      flex: 1;
      padding: 12px 16px;
      border: 2px solid #e0e0e0;
      border-radius: 25px;
      font-size: 1em;
      outline: none;
      color: #1a1a1a;
    }
    #chatInput:focus {
      border-color: #f5576c;
      box-shadow: 0 0 0 3px rgba(245, 87, 108, 0.1);
    }
    .send-btn {
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
      color: white;
      border: none;
      padding: 12px 30px;
      border-radius: 25px;
      cursor: pointer;
      font-weight: 600;
      transition: all 0.2s;
    }
    .send-btn:hover:not(:disabled) {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(245, 87, 108, 0.3);
    }
    .send-btn:focus {
      outline: 3px solid #f5576c;
      outline-offset: 2px;
    }
    .send-btn:active:not(:disabled) {
      transform: translateY(0);
    }
    .send-btn:disabled {
      opacity: 0.6;
      cursor: not-allowed;
    }
    .product-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
      gap: 15px;
      max-height: 400px;
      overflow-y: auto;
    }
    .product-card {
      border: 2px solid #e0e0e0;
      border-radius: 10px;
      padding: 15px;
      cursor: pointer;
      transition: all 0.3s;
    }
    .product-card:hover {
      border-color: #f5576c;
      transform: translateY(-2px);
      box-shadow: 0 5px 15px rgba(0,0,0,0.1);
    }
    .product-card:focus {
      outline: 3px solid #f5576c;
      outline-offset: 2px;
    }
    .product-card.selected {
      border-color: #f5576c;
      background: #fff5f7;
    }
    .product-image {
      width: 100%;
      height: 150px;
      object-fit: cover;
      border-radius: 8px;
      margin-bottom: 10px;
    }
    .product-title {
      font-weight: 600;
      font-size: 0.9em;
      margin-bottom: 5px;
      color: #1a1a1a;
    }
    .product-sku {
      font-size: 0.8em;
      color: #555;
    }
    .blog-list {
      max-height: 400px;
      overflow-y: auto;
    }
    .blog-item {
      padding: 15px;
      border-bottom: 1px solid #e0e0e0;
      cursor: pointer;
      transition: background 0.2s;
    }
    .blog-item:hover {
      background: #f5f5f5;
    }
    .blog-item:focus {
      outline: 2px solid #f5576c;
      outline-offset: -2px;
      background: #f5f5f5;
    }
    .blog-title {
      font-weight: 600;
      color: #1a1a1a;
      margin-bottom: 5px;
    }
    .blog-meta {
      font-size: 0.85em;
      color: #555;
    }
    .btn {
      background: linear-gradient(135deg, #36454f 0%, #708090 100%);
      color: white;
      border: none;
      padding: 12px 24px;
      border-radius: 8px;
      cursor: pointer;
      font-weight: 600;
      margin-top: 15px;
      transition: all 0.2s;
    }
    .btn:hover:not(:disabled) {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(245, 87, 108, 0.3);
    }
    .btn:focus {
      outline: 3px solid #d8194e;
      outline-offset: 2px;
    }
    .btn:active:not(:disabled) {
      transform: translateY(0);
    }
    .btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }
    .suggestions {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      margin-bottom: 15px;
    }
    .suggestion-chip {
      background: #f0f0f0;
      padding: 8px 15px;
      border-radius: 20px;
      font-size: 0.85em;
      cursor: pointer;
      transition: all 0.2s;
      color: #333;
    }
    .suggestion-chip:hover {
      background: #f5576c;
      color: white;
    }
    .suggestion-chip:focus {
      outline: 2px solid #f5576c;
      outline-offset: 2px;
    }

    /* Mobile responsive */
    @media (max-width: 1024px) {
      .container {
        grid-template-columns: 1fr;
      }
      .sidebar {
        position: fixed;
        left: 0;
        top: 0;
        bottom: 0;
        width: 300px;
        background: white;
        z-index: 1000;
        padding: 20px;
        overflow-y: auto;
        transform: translateX(-100%);
        transition: transform 0.3s ease-out;
        box-shadow: 2px 0 8px rgba(0,0,0,0.1);
      }
      .sidebar.open {
        transform: translateX(0);
      }
      .sidebar-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
      }
      .sidebar-overlay {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0,0,0,0.5);
        z-index: 999;
      }
      .sidebar-overlay.active {
        display: block;
      }
      .main-content {
        margin-top: 70px;
      }
      .tab {
        font-size: 0.9em;
        padding: 12px 10px;
      }
      .message-content {
        max-width: 85%;
      }
    }

    @media (max-width: 640px) {
      body {
        padding: 10px;
      }
      .tab-content {
        padding: 20px 15px;
      }
      .chat-container {
        height: 400px;
      }
      .product-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 10px;
      }
      .toast {
        right: 10px;
        left: 10px;
        max-width: none;
      }
    }
  </style>
</head>
<body>
  <!-- Mobile sidebar toggle -->
  <button class="sidebar-toggle" onclick="toggleSidebar()" aria-label="Toggle menu">☰</button>
  <div class="sidebar-overlay" onclick="toggleSidebar()"></div>

  <!-- Loading overlay -->
  <div class="loading-overlay" id="loadingOverlay">
    <div class="loading-content">
      <div class="loading-spinner"></div>
      <div style="color: #333; font-weight: 600;">Processing...</div>
    </div>
  </div>

  <div class="container">
    <div class="sidebar" id="sidebar">
      <div class="header">
        <h1>📢 Marketing Agent</h1>
        <div class="subtitle">Content Creation & Campaigns</div>
        <div style="margin-top: 15px;">
          <a href="/logout" style="color: #f5576c; text-decoration: none;">Logout</a>
        </div>
      </div>

      <div class="stats-card">
        <h3>Blog Posts Created</h3>
        <div class="value" id="blogPostsCreated">0</div>
      </div>

      <div class="stats-card">
        <h3>Social Posts</h3>
        <div class="value" id="socialPostsGenerated">0</div>
      </div>

      <div class="stats-card">
        <h3>Email Campaigns</h3>
        <div class="value" id="emailCampaignsDrafted">0</div>
      </div>

      <div class="stats-card">
        <h3>Conversations</h3>
        <div class="value" id="totalConversations">0</div>
      </div>
    </div>

    <div class="main-content">
      <div class="tab-container">
        <div class="tabs">
          <div class="tab active" onclick="switchTab('insights')" tabindex="0" role="tab" aria-selected="true" onkeypress="if(event.key==='Enter') switchTab('insights')">📊 Order Insights</div>
          <div class="tab" onclick="switchTab('chat')" tabindex="0" role="tab" aria-selected="false" onkeypress="if(event.key==='Enter') switchTab('chat')">💬 Chat Assistant</div>
          <div class="tab" onclick="switchTab('blogs')" tabindex="0" role="tab" aria-selected="false" onkeypress="if(event.key==='Enter') switchTab('blogs')">📝 Blog Posts</div>
          <div class="tab" onclick="switchTab('create')" tabindex="0" role="tab" aria-selected="false" onkeypress="if(event.key==='Enter') switchTab('create')">✨ Create from SKU</div>
          <div class="tab" onclick="switchTab('social')" tabindex="0" role="tab" aria-selected="false" onkeypress="if(event.key==='Enter') switchTab('social')">📱 Social Media</div>
        </div>

        <!-- Order Insights Tab -->
        <div class="tab-content active" id="insights-content">
          <h2 style="color: #f5576c; margin-bottom: 15px;">Order Insights & Marketing Metrics</h2>

          <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; margin-bottom: 30px;">
            <div style="background: #f5f5f5; padding: 20px; border-radius: 10px; border-left: 4px solid #f5576c;">
              <h3 style="color: #666; font-size: 0.9em; margin-bottom: 8px;">Total Revenue (30 days)</h3>
              <div style="font-size: 1.8em; font-weight: bold; color: #333;">$<span id="totalRevenue">0</span></div>
            </div>
            <div style="background: #f5f5f5; padding: 20px; border-radius: 10px; border-left: 4px solid #36454f;">
              <h3 style="color: #666; font-size: 0.9em; margin-bottom: 8px;">Total Orders</h3>
              <div style="font-size: 1.8em; font-weight: bold; color: #333;"><span id="orderCount">0</span></div>
            </div>
            <div style="background: #f5f5f5; padding: 20px; border-radius: 10px; border-left: 4px solid #708090;">
              <h3 style="color: #666; font-size: 0.9em; margin-bottom: 8px;">Average Order Value</h3>
              <div style="font-size: 1.8em; font-weight: bold; color: #333;">$<span id="avgOrderValue">0</span></div>
            </div>
          </div>

          <h3 style="color: #f5576c; margin-bottom: 15px;">🔥 Top Selling Products</h3>
          <div id="topProducts" style="background: #f5f5f5; border-radius: 10px; padding: 20px; margin-bottom: 30px;">
            <p style="color: #888;">Loading top products...</p>
          </div>

          <h3 style="color: #f5576c; margin-bottom: 15px;">📈 Daily Revenue Trend</h3>
          <div id="dailyRevenue" style="background: #f5f5f5; border-radius: 10px; padding: 20px; margin-bottom: 30px;">
            <p style="color: #888;">Loading revenue trends...</p>
          </div>

          <h3 style="color: #f5576c; margin-bottom: 15px;">🛍️ Recent Orders</h3>
          <button class="btn" onclick="loadOrderInsights()">🔄 Refresh Order Data</button>
          <div id="recentOrders" style="margin-top: 20px; max-height: 400px; overflow-y: auto;">
            <p style="color: #888; padding: 20px;">Click "Refresh Order Data" to load recent orders...</p>
          </div>
        </div>

        <!-- Chat Tab -->
        <div class="tab-content" id="chat-content">
          <h2 style="color: #f5576c; margin-bottom: 15px;">Chat with Marketing Agent</h2>
          <div class="suggestions">
            <div class="suggestion-chip" onclick="sendSuggestion('Create a professional blog post for product grasscloth in Architectural Digest style with images')" tabindex="0" onkeypress="if(event.key==='Enter') sendSuggestion('Create a professional blog post for product grasscloth in Architectural Digest style with images')">📰 AD-Style Blog</div>
            <div class="suggestion-chip" onclick="sendSuggestion('Make blog for vendor York with photos and details')" tabindex="0" onkeypress="if(event.key==='Enter') sendSuggestion('Make blog for vendor York with photos and details')">✨ Vendor Blog</div>
            <div class="suggestion-chip" onclick="sendSuggestion('Generate Instagram post')" tabindex="0" onkeypress="if(event.key==='Enter') sendSuggestion('Generate Instagram post')">📸 Instagram</div>
            <div class="suggestion-chip" onclick="sendSuggestion('Show me recent blog posts')" tabindex="0" onkeypress="if(event.key==='Enter') sendSuggestion('Show me recent blog posts')">📝 Recent Blogs</div>
          </div>
          <div class="chat-container">
            <div class="chat-messages" id="chatMessages">
              <div class="message assistant">
                <div class="message-avatar">🤖</div>
                <div class="message-content">
                  Hi! I'm your Marketing Agent, specialized in Architectural Digest-style editorial content.<br><br>
                  <strong>I can create:</strong><br>
                  • Professional blog posts with product images and links<br>
                  • Editorial-style content in AD magazine format<br>
                  • Social media posts (Instagram, Facebook, Pinterest)<br>
                  • Product-focused articles with full details<br>
                  <br>
                  <strong>Try asking:</strong><br>
                  "Make blog for product [name] by vendor [vendor] in professional style"<br>
                  "Create AD-style blog for SKU [sku] with photos and details"<br>
                  <br>
                  What would you like to create today?
                </div>
              </div>
            </div>
            <div class="chat-input-container">
              <input
                type="text"
                id="chatInput"
                placeholder="Ask me to create content, view blogs, or generate posts..."
                onkeypress="if(event.key === 'Enter') sendMessage()"
              >
              <button class="send-btn" onclick="sendMessage()" id="sendBtn">Send</button>
            </div>
          </div>
        </div>

        <!-- Blog Posts Tab -->
        <div class="tab-content" id="blogs-content">
          <h2 style="color: #f5576c; margin-bottom: 15px;">Recent Blog Posts from Shopify</h2>
          <button class="btn" onclick="loadBlogs()">🔄 Refresh Blog List</button>
          <div class="blog-list" id="blogList">
            <p style="color: #888; padding: 20px;">Click "Refresh Blog List" to load recent posts from Shopify...</p>
          </div>
        </div>

        <!-- Create from SKU Tab -->
        <div class="tab-content" id="create-content">
          <h2 style="color: #f5576c; margin-bottom: 15px;">Create Blog Post from Product</h2>
          <button class="btn" onclick="loadProducts()">🔄 Load Recent Products</button>
          <p style="color: #666; margin: 15px 0;">Select a product below to generate a blog post:</p>
          <div class="product-grid" id="productGrid">
            <p style="color: #888; padding: 20px; grid-column: 1/-1;">Click "Load Recent Products" to see available SKUs...</p>
          </div>
          <button class="btn" id="generateBlogBtn" style="display:none;" onclick="generateBlog()">✨ Generate Blog Post</button>
        </div>

        <!-- Social Media Tab -->
        <div class="tab-content" id="social-content">
          <h2 style="color: #f5576c; margin-bottom: 15px;">Social Media Content Generator</h2>
          <p style="color: #666; margin-bottom: 20px;">Generate social media posts for Instagram, Facebook, and more!</p>
          <button class="btn" onclick="generateSocial('instagram')">📸 Generate Instagram Post</button>
          <button class="btn" onclick="generateSocial('facebook')">👍 Generate Facebook Post</button>
          <button class="btn" onclick="generateSocial('pinterest')">📌 Generate Pinterest Description</button>
          <div id="socialOutput" style="margin-top: 20px; padding: 20px; background: #f5f5f5; border-radius: 10px; display: none;">
            <h3 style="color: #f5576c; margin-bottom: 10px;">Generated Content:</h3>
            <pre id="socialContent" style="white-space: pre-wrap; font-family: inherit; color: #333;"></pre>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script>
    let selectedProduct = null;

    // Toast notification system
    function showToast(message, type = 'info') {
      const existingToast = document.querySelector('.toast');
      if (existingToast) {
        existingToast.remove();
      }

      const toast = document.createElement('div');
      toast.className = \`toast \${type}\`;

      const icons = {
        success: '✓',
        error: '✕',
        info: 'ℹ'
      };

      toast.innerHTML = \`
        <div class="toast-icon">\${icons[type] || icons.info}</div>
        <div class="toast-message">\${message}</div>
        <button class="toast-close" onclick="this.parentElement.remove()" aria-label="Close">×</button>
      \`;

      document.body.appendChild(toast);

      setTimeout(() => toast.classList.add('show'), 10);

      setTimeout(() => {
        toast.classList.remove('show');
        setTimeout(() => toast.remove(), 300);
      }, 5000);
    }

    // Loading overlay functions
    function showLoading() {
      document.getElementById('loadingOverlay').classList.add('active');
    }

    function hideLoading() {
      document.getElementById('loadingOverlay').classList.remove('active');
    }

    // Mobile sidebar toggle
    function toggleSidebar() {
      const sidebar = document.getElementById('sidebar');
      const overlay = document.querySelector('.sidebar-overlay');
      sidebar.classList.toggle('open');
      overlay.classList.toggle('active');
    }

    function switchTab(tab) {
      // Update tab states
      document.querySelectorAll('.tab').forEach(t => {
        t.classList.remove('active');
        t.setAttribute('aria-selected', 'false');
      });
      document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));

      // Activate selected tab
      event.target.classList.add('active');
      event.target.setAttribute('aria-selected', 'true');
      document.getElementById(tab + '-content').classList.add('active');

      // Close sidebar on mobile after tab switch
      if (window.innerWidth <= 1024) {
        const sidebar = document.getElementById('sidebar');
        const overlay = document.querySelector('.sidebar-overlay');
        if (sidebar.classList.contains('open')) {
          sidebar.classList.remove('open');
          overlay.classList.remove('active');
        }
      }
    }

    function updateStats() {
      fetch('/api/stats')
        .then(r => r.json())
        .then(data => {
          document.getElementById('blogPostsCreated').textContent = data.blogPostsCreated;
          document.getElementById('socialPostsGenerated').textContent = data.socialPostsGenerated;
          document.getElementById('emailCampaignsDrafted').textContent = data.emailCampaignsDrafted;
          document.getElementById('totalConversations').textContent = data.totalConversations;
        });
    }

    function addMessage(role, content) {
      const messagesDiv = document.getElementById('chatMessages');
      const messageDiv = document.createElement('div');
      messageDiv.className = \`message \${role}\`;

      const avatar = document.createElement('div');
      avatar.className = 'message-avatar';
      avatar.textContent = role === 'user' ? '👤' : '🤖';

      const contentDiv = document.createElement('div');
      contentDiv.className = 'message-content';
      contentDiv.innerHTML = content.replace(/\\n/g, '<br>');

      messageDiv.appendChild(avatar);
      messageDiv.appendChild(contentDiv);
      messagesDiv.appendChild(messageDiv);

      messagesDiv.scrollTop = messagesDiv.scrollHeight;
    }

    async function sendMessage() {
      const input = document.getElementById('chatInput');
      const sendBtn = document.getElementById('sendBtn');
      const message = input.value.trim();

      if (!message) return;

      addMessage('user', message);
      input.value = '';
      sendBtn.disabled = true;
      sendBtn.innerHTML = '<span class="spinner"></span>';
      showLoading();

      try {
        const response = await fetch('/api/chat', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ message })
        });

        if (!response.ok) {
          throw new Error('Network response was not ok');
        }

        const data = await response.json();
        addMessage('assistant', data.response);
        updateStats();

      } catch (error) {
        console.error('Chat error:', error);
        addMessage('assistant', 'Sorry, I encountered an error. Please try again.');
        showToast('Failed to send message. Please try again.', 'error');
      } finally {
        hideLoading();
        sendBtn.disabled = false;
        sendBtn.textContent = 'Send';
      }
    }

    function sendSuggestion(text) {
      document.getElementById('chatInput').value = text;
      sendMessage();
    }

    async function loadBlogs() {
      const blogList = document.getElementById('blogList');
      blogList.innerHTML = '<p style="padding: 20px; color: #888;">Loading blog posts...</p>';
      showLoading();

      try {
        const response = await fetch('/api/shopify/blogs');

        if (!response.ok) {
          throw new Error('Failed to fetch blogs');
        }

        const data = await response.json();

        if (data.blogs && data.blogs.length > 0) {
          const shopifyDomain = 'designer-laboratory-sandbox.myshopify.com';
          blogList.innerHTML = data.blogs.map(blog => {
            const blogUrl = \`https://\${shopifyDomain}/blogs/news/\${blog.handle}\`;
            return \`
            <div class="blog-item" tabindex="0">
              <div class="blog-title">
                <a href="\${blogUrl}" target="_blank" style="color: #f5576c; text-decoration: none;">
                  \${blog.title}
                </a>
              </div>
              <div class="blog-meta">
                Created: \${new Date(blog.createdAt).toLocaleDateString()} |
                \${blog.publishedAt ? 'Published' : 'Draft'}
                \${blog.tags ? ' | Tags: ' + blog.tags : ''}
                <br>
                <a href="\${blogUrl}" target="_blank" style="color: #666; font-size: 12px; text-decoration: none;">
                  🔗 View on Shopify →
                </a>
              </div>
            </div>
          \`;
          }).join('');
          showToast(\`Loaded \${data.blogs.length} blog posts\`, 'success');
        } else {
          blogList.innerHTML = '<p style="padding: 20px; color: #888;">No blog posts found.</p>';
          showToast('No blog posts found', 'info');
        }
      } catch (error) {
        console.error('Error loading blogs:', error);
        blogList.innerHTML = '<p style="padding: 20px; color: #dc3545;">Error loading blogs. Please try again.</p>';
        showToast('Failed to load blog posts', 'error');
      } finally {
        hideLoading();
      }
    }

    async function loadProducts() {
      const productGrid = document.getElementById('productGrid');
      productGrid.innerHTML = '<p style="padding: 20px; color: #888; grid-column: 1/-1;">Loading products...</p>';
      showLoading();

      try {
        const response = await fetch('/api/shopify/products');

        if (!response.ok) {
          throw new Error('Failed to fetch products');
        }

        const data = await response.json();

        if (data.products && data.products.length > 0) {
          productGrid.innerHTML = data.products.map(product => \`
            <div class="product-card" tabindex="0" onclick="selectProduct('\${product.id}', '\${product.sku}', '\${product.title}', '\${product.imageUrl}')" onkeypress="if(event.key==='Enter') selectProduct('\${product.id}', '\${product.sku}', '\${product.title}', '\${product.imageUrl}')">
              <img src="\${product.imageUrl || 'https://via.placeholder.com/200'}" class="product-image" alt="\${product.title}">
              <div class="product-title">\${product.title}</div>
              <div class="product-sku">SKU: \${product.sku}</div>
            </div>
          \`).join('');
          showToast(\`Loaded \${data.products.length} products\`, 'success');
        } else {
          productGrid.innerHTML = '<p style="padding: 20px; color: #888; grid-column: 1/-1;">No recent products found.</p>';
          showToast('No products found', 'info');
        }
      } catch (error) {
        console.error('Error loading products:', error);
        productGrid.innerHTML = '<p style="padding: 20px; color: #dc3545; grid-column: 1/-1;">Error loading products. Please try again.</p>';
        showToast('Failed to load products', 'error');
      } finally {
        hideLoading();
      }
    }

    function selectProduct(id, sku, title, imageUrl) {
      document.querySelectorAll('.product-card').forEach(card => card.classList.remove('selected'));
      event.currentTarget.classList.add('selected');
      selectedProduct = { id, sku, title, imageUrl };
      document.getElementById('generateBlogBtn').style.display = 'block';
    }

    async function generateBlog() {
      if (!selectedProduct) return;

      const btn = document.getElementById('generateBlogBtn');
      btn.disabled = true;
      btn.innerHTML = '<span class="spinner"></span> Generating...';
      showLoading();

      try {
        const response = await fetch('/api/generate/blog', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(selectedProduct)
        });

        if (!response.ok) {
          throw new Error('Failed to generate blog');
        }

        const data = await response.json();

        if (data.success) {
          showToast(\`Blog post created: "\${data.blog.title}"\`, 'success');
          updateStats();
          setTimeout(() => {
            switchTab('blogs');
            loadBlogs();
          }, 500);
        } else {
          throw new Error(data.error || 'Unknown error');
        }

      } catch (error) {
        console.error('Error generating blog:', error);
        showToast('Failed to generate blog post. Please try again.', 'error');
      } finally {
        hideLoading();
        btn.disabled = false;
        btn.textContent = '✨ Generate Blog Post';
      }
    }

    async function generateSocial(platform) {
      const output = document.getElementById('socialOutput');
      const content = document.getElementById('socialContent');

      output.style.display = 'block';
      content.textContent = 'Generating ' + platform + ' content...';
      showLoading();

      try {
        const response = await fetch('/api/generate/social', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ platform })
        });

        if (!response.ok) {
          throw new Error('Failed to generate social content');
        }

        const data = await response.json();

        if (data.success) {
          content.textContent = data.content;
          updateStats();
          showToast(\`Generated \${platform} post successfully\`, 'success');
        } else {
          throw new Error('Generation failed');
        }

      } catch (error) {
        console.error('Error generating social content:', error);
        content.textContent = 'Error generating content. Please try again.';
        showToast('Failed to generate social content', 'error');
      } finally {
        hideLoading();
      }
    }

    // Function to load order insights
    async function loadOrderInsights() {
      showLoading();
      try {
        const response = await fetch('/api/shopify/orders');
        if (!response.ok) {
          throw new Error('Failed to fetch orders');
        }

        const data = await response.json();

        if (data.success && data.orderTrends) {
          // Update summary metrics
          document.getElementById('totalRevenue').textContent = data.orderTrends.totalRevenue.toFixed(2);
          document.getElementById('orderCount').textContent = data.orderTrends.orderCount;
          document.getElementById('avgOrderValue').textContent = data.orderTrends.averageOrderValue.toFixed(2);

          // Display top products
          const topProductsDiv = document.getElementById('topProducts');
          if (data.orderTrends.topProducts && data.orderTrends.topProducts.length > 0) {
            topProductsDiv.innerHTML = '<table style="width: 100%; border-collapse: collapse;">' +
              '<thead><tr style="border-bottom: 2px solid #ddd;">' +
              '<th style="text-align: left; padding: 8px; color: #666;">Product</th>' +
              '<th style="text-align: center; padding: 8px; color: #666;">SKU</th>' +
              '<th style="text-align: center; padding: 8px; color: #666;">Qty Sold</th>' +
              '</tr></thead><tbody>' +
              data.orderTrends.topProducts.map((p, i) =>
                `<tr style="border-bottom: 1px solid #eee;">
                  <td style="padding: 8px; color: #333;"><strong>${i+1}.</strong> ${p.title}</td>
                  <td style="text-align: center; padding: 8px; color: #666; font-size: 0.9em;">${p.sku}</td>
                  <td style="text-align: center; padding: 8px; color: #f5576c; font-weight: bold;">${p.totalQuantity}</td>
                </tr>`
              ).join('') +
              '</tbody></table>';
          } else {
            topProductsDiv.innerHTML = '<p style="color: #888;">No product data available</p>';
          }

          // Display daily revenue trend
          const dailyRevenueDiv = document.getElementById('dailyRevenue');
          if (data.orderTrends.dailyRevenue && data.orderTrends.dailyRevenue.length > 0) {
            dailyRevenueDiv.innerHTML = '<table style="width: 100%; border-collapse: collapse;">' +
              '<thead><tr style="border-bottom: 2px solid #ddd;">' +
              '<th style="text-align: left; padding: 8px; color: #666;">Date</th>' +
              '<th style="text-align: center; padding: 8px; color: #666;">Orders</th>' +
              '<th style="text-align: right; padding: 8px; color: #666;">Revenue</th>' +
              '</tr></thead><tbody>' +
              data.orderTrends.dailyRevenue.map(d => {
                const date = new Date(d.date);
                const formattedDate = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
                return `<tr style="border-bottom: 1px solid #eee;">
                  <td style="padding: 8px; color: #333;">${formattedDate}</td>
                  <td style="text-align: center; padding: 8px; color: #666;">${d.orderCount}</td>
                  <td style="text-align: right; padding: 8px; color: #28a745; font-weight: bold;">$${d.revenue.toFixed(2)}</td>
                </tr>`;
              }).join('') +
              '</tbody></table>';
          } else {
            dailyRevenueDiv.innerHTML = '<p style="color: #888;">No revenue data available</p>';
          }

          // Display recent orders
          const ordersDiv = document.getElementById('recentOrders');
          if (data.recentOrders && data.recentOrders.length > 0) {
            ordersDiv.innerHTML = data.recentOrders.map(order => {
              const orderDate = new Date(order.createdAt);
              const items = order.lineItems.edges.map(e => e.node);
              return `
                <div style="background: white; border: 1px solid #e0e0e0; border-radius: 8px; padding: 15px; margin-bottom: 10px;">
                  <div style="display: flex; justify-content: between; align-items: center; margin-bottom: 10px;">
                    <div>
                      <strong style="color: #f5576c;">${order.name}</strong>
                      <span style="color: #666; margin-left: 10px; font-size: 0.9em;">
                        ${orderDate.toLocaleDateString()} ${orderDate.toLocaleTimeString()}
                      </span>
                    </div>
                    <div style="text-align: right; margin-left: auto;">
                      <span style="font-size: 1.2em; font-weight: bold; color: #28a745;">
                        $${parseFloat(order.totalPriceSet.shopMoney.amount).toFixed(2)}
                      </span>
                    </div>
                  </div>
                  <div style="color: #666; font-size: 0.9em;">
                    ${items.slice(0, 3).map(item =>
                      `• ${item.title} ${item.sku ? `(${item.sku})` : ''} × ${item.quantity}`
                    ).join('<br>')}
                    ${items.length > 3 ? `<br>• ... and ${items.length - 3} more items` : ''}
                  </div>
                  <div style="margin-top: 8px;">
                    <span style="display: inline-block; padding: 3px 8px; border-radius: 12px; font-size: 0.8em; background: #e8f4f8; color: #0066cc;">
                      ${order.displayFinancialStatus}
                    </span>
                    ${order.displayFulfillmentStatus ?
                      `<span style="display: inline-block; padding: 3px 8px; border-radius: 12px; font-size: 0.8em; background: #f0f8e8; color: #5a8a00; margin-left: 5px;">
                        ${order.displayFulfillmentStatus}
                      </span>` : ''
                    }
                  </div>
                </div>
              `;
            }).join('');
            showToast(`Loaded ${data.recentOrders.length} recent orders`, 'success');
          } else {
            ordersDiv.innerHTML = '<p style="color: #888; padding: 20px;">No orders found</p>';
          }

        } else {
          throw new Error('Invalid response format');
        }

      } catch (error) {
        console.error('Error loading order insights:', error);
        showToast('Failed to load order insights', 'error');
        document.getElementById('topProducts').innerHTML = '<p style="color: #dc3545;">Error loading data</p>';
        document.getElementById('dailyRevenue').innerHTML = '<p style="color: #dc3545;">Error loading data</p>';
        document.getElementById('recentOrders').innerHTML = '<p style="color: #dc3545;">Error loading orders</p>';
      } finally {
        hideLoading();
      }
    }

    // Load order insights on page load
    setTimeout(() => {
      loadOrderInsights();
    }, 1000);

    // Update stats every 10 seconds
    setInterval(updateStats, 10000);
    updateStats();
  </script>
</body>
</html>
  `);
});

// API endpoints
app.get('/api/stats', requireAuth, (req, res) => {
  res.json(stats);
});

app.post('/api/chat', requireAuth, async (req, res) => {
  try {
    const { message } = req.body;

    if (!message) {
      return res.status(400).json({ error: 'Message is required' });
    }

    // Memory system commands
    if (message.toLowerCase().match(/^(remember|note|preference|learning):/i)) {
    const parts = message.split(':');
    const type = parts[0].toLowerCase();
    const content = parts.slice(1).join(':').trim();
    const memType = type === 'remember' ? 'note' : type as any;
    agentMemory.add(content, memType);
    return res.json({
      response: `✅ Memory saved: "${content}"`,
      success: true,
      memoryAdded: true
    });
  }

  if (message.toLowerCase().includes('show') && message.toLowerCase().includes('memor')) {
    const summary = agentMemory.getContextSummary();
    return res.json({ response: summary, success: true });
  }

  if (message.toLowerCase().includes('search memor')) {
    const query = message.split(/for|about/i)[1]?.trim() || '';
    const results = agentMemory.search(query);
    return res.json({
      response: results.length > 0
        ? 'Found memories:\n' + results.map(m => `- ${m.content}`).join('\n')
        : 'No matching memories found.',
      success: true
    });
  }

  if (message.toLowerCase().includes('forget') || message.toLowerCase().includes('delete memor')) {
    const query = message.split(/forget|delete/i)[1]?.trim() || '';
    const results = agentMemory.search(query);
    if (results.length > 0) {
      agentMemory.delete(results[0].id);
      return res.json({ response: `✅ Forgot: "${results[0].content}"`, success: true });
    }
    return res.json({ response: 'Nothing found to forget.', success: true });
  }

    stats.totalConversations++;

    if (!req.session.chatHistory) {
      req.session.chatHistory = [];
    }

    req.session.chatHistory.push({ role: 'user', content: message });

    // Parse the message for product-specific requests
    let productContext = '';
    const productMatch = message.match(/product\s+([^,\s]+)|vendor\s+([^,\s]+)|sku\s+([^,\s]+)/i);

    if (productMatch) {
      // Search for the product in Shopify
      const searchTerm = productMatch[1] || productMatch[2] || productMatch[3];
      try {
        const query = `query {
          products(first: 5, query: "${searchTerm}") {
            edges {
              node {
                id
                title
                handle
                vendor
                description
                variants(first: 1) {
                  edges {
                    node {
                      sku
                      price
                    }
                  }
                }
                featuredImage {
                  url
                  altText
                }
                images(first: 5) {
                  edges {
                    node {
                      url
                      altText
                    }
                  }
                }
              }
            }
          }
        }`;
        const productData = await shopifyGraphQL(query);

        if (productData.data?.products?.edges?.length > 0) {
          const products = productData.data.products.edges.map((edge: any) => ({
            title: edge.node.title,
            vendor: edge.node.vendor,
            sku: edge.node.variants.edges[0]?.node.sku || 'N/A',
            price: edge.node.variants.edges[0]?.node.price || 'N/A',
            description: edge.node.description,
            mainImage: edge.node.featuredImage?.url || '',
            images: edge.node.images.edges.map((img: any) => img.node.url),
            shopifyUrl: `https://${SHOPIFY_STORE}/products/${edge.node.handle}`
          }));

          productContext = `\n\nFOUND PRODUCTS:\n${products.map(p =>
            `- ${p.title} by ${p.vendor} (SKU: ${p.sku})
  Price: $${p.price}
  Description: ${p.description?.substring(0, 200)}...
  Main Image: ${p.mainImage}
  All Images: ${p.images.join(', ')}
  Product URL: ${p.shopifyUrl}`
          ).join('\n\n')}`;
        }
      } catch (err) {
        console.error('Error searching products:', err);
      }
    }

    const systemPrompt = `You are the Marketing Agent for Designer Wallcoverings, a specialist in creating Architectural Digest-style editorial content.

Your responsibilities:
1. Create compelling, magazine-quality blog posts from product SKUs
2. Generate social media content (Instagram, Facebook, Pinterest)
3. Draft email marketing campaigns
4. Write engaging product descriptions in professional editorial style
5. Provide marketing strategy advice

BLOG POST CREATION SKILLS:
When asked to create a blog post for a product, you should:
- Write in the sophisticated, editorial style of Architectural Digest
- Include proper HTML structure with headings, paragraphs, and semantic markup
- Reference product images with full URLs in <img> tags and proper alt text
- Link to the product page using the provided Shopify URL with descriptive anchor text
- Describe the product's design, texture, color, and styling possibilities
- Reference interior design trends and room applications
- Use designer terminology and sophisticated language
- Include multiple product images throughout the post
- Add proper meta description and SEO keywords
- Structure: Opening hook → Product details → Design applications → Styling tips → Call-to-action

PRODUCT DATA AVAILABLE:${productContext}

You have access to:
- Shopify store with products and blog posts
- Product details including images, descriptions, SKUs, prices, vendors
- Direct product URLs for linking

Current statistics:
- Blog posts created: ${stats.blogPostsCreated}
- Social posts generated: ${stats.socialPostsGenerated}
- Email campaigns: ${stats.emailCampaignsDrafted}

Recent blog posts:
${stats.recentBlogs.length > 0 ? stats.recentBlogs.slice(-3).map(blog =>
  `- "${blog.title}" (created ${new Date(blog.createdAt).toLocaleDateString()})`
).join('\n') : '- No recent blogs'}

${agentMemory.getContextSummary()}

When creating content:
1. Use sophisticated, editorial writing style
2. Include actual image URLs from the product data
3. Create proper HTML with href links to product pages
4. Reference specific product details (SKU, vendor, price)
5. Write compelling, benefit-focused copy
6. Use SEO-optimized headlines and descriptions
7. Reference stored memories and preferences when relevant

Be professional, sophisticated, and magazine-editorial in your approach.`;

    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 4096, // Increased for longer blog posts
      system: systemPrompt,
      messages: req.session.chatHistory
    });

    const assistantMessage = response.content[0].type === 'text'
      ? response.content[0].text
      : 'I apologize, but I encountered an error.';

    req.session.chatHistory.push({ role: 'assistant', content: assistantMessage });

    if (req.session.chatHistory.length > 20) {
      req.session.chatHistory = req.session.chatHistory.slice(-20);
    }

    res.json({ response: assistantMessage });

  } catch (error) {
    console.error('Chat error:', error);
    res.status(500).json({
      error: 'Failed to process message',
      response: 'I apologize, but I encountered an error. Please try again.'
    });
  }
});

// Shopify blog posts
app.get('/api/shopify/blogs', requireAuth, async (req, res) => {
  try {
    const query = `
      query {
        articles(first: 10, sortKey: CREATED_AT, reverse: true) {
          edges {
            node {
              id
              title
              createdAt
              publishedAt
              tags
              handle
            }
          }
        }
      }
    `;

    const data = await shopifyGraphQL(query);

    if (data.data && data.data.articles) {
      const blogs = data.data.articles.edges.map((edge: any) => ({
        id: edge.node.id,
        title: edge.node.title,
        createdAt: edge.node.createdAt,
        publishedAt: edge.node.publishedAt,
        tags: edge.node.tags.join(', '),
        handle: edge.node.handle
      }));

      stats.recentBlogs = blogs;
      res.json({ blogs });
    } else {
      res.json({ blogs: [] });
    }

  } catch (error) {
    console.error('Error fetching blogs:', error);
    res.status(500).json({ error: 'Failed to fetch blogs' });
  }
});

// Shopify products
app.get('/api/shopify/products', requireAuth, async (req, res) => {
  try {
    const query = `
      query {
        products(first: 20, sortKey: CREATED_AT, reverse: true) {
          edges {
            node {
              id
              title
              handle
              vendor
              variants(first: 1) {
                edges {
                  node {
                    sku
                  }
                }
              }
              featuredImage {
                url
              }
            }
          }
        }
      }
    `;

    const data = await shopifyGraphQL(query);

    if (data.data && data.data.products) {
      const products = data.data.products.edges.map((edge: any) => ({
        id: edge.node.id,
        title: edge.node.title,
        handle: edge.node.handle,
        vendor: edge.node.vendor,
        sku: edge.node.variants.edges[0]?.node.sku || 'N/A',
        imageUrl: edge.node.featuredImage?.url || ''
      }));

      stats.recentProducts = products;
      res.json({ products });
    } else {
      res.json({ products: [] });
    }

  } catch (error) {
    console.error('Error fetching products:', error);
    res.status(500).json({ error: 'Failed to fetch products' });
  }
});

// Generate blog post from product
app.post('/api/generate/blog', requireAuth, async (req, res) => {
  try {
    const { id, sku, title, imageUrl } = req.body;

    // Use Claude to generate blog content
    const prompt = `Create a compelling blog post for this wallcovering product:

Product Title: ${title}
SKU: ${sku}

Write an engaging blog post (300-500 words) that includes:
1. An attention-grabbing headline
2. Introduction highlighting the product's unique features
3. Design trends and styling suggestions
4. Room application ideas
5. Call-to-action

Make it SEO-friendly and engaging for interior designers and homeowners.`;

    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 2048,
      messages: [{ role: 'user', content: prompt }]
    });

    const blogContent = response.content[0].type === 'text' ? response.content[0].text : '';

    // Extract title (first line) and body
    const lines = blogContent.split('\n');
    const blogTitle = lines[0].replace(/^#+ /, '').trim();
    const blogBody = lines.slice(1).join('\n').trim();

    stats.blogPostsCreated++;
    stats.lastBlogPost = {
      title: blogTitle,
      sku,
      timestamp: new Date()
    };

    // In production, would create blog post via Shopify API
    res.json({
      success: true,
      blog: {
        title: blogTitle,
        content: blogBody,
        sku,
        productId: id
      }
    });

  } catch (error) {
    console.error('Error generating blog:', error);
    res.status(500).json({ error: 'Failed to generate blog post' });
  }
});

// Generate social media content
app.post('/api/generate/social', requireAuth, async (req, res) => {
  try {
    const { platform } = req.body;

    const prompts: Record<string, string> = {
      instagram: 'Write an engaging Instagram caption (150 chars) for a new designer wallcovering collection. Include emojis and 5 relevant hashtags.',
      facebook: 'Write a Facebook post (200 chars) announcing a new wallcovering line. Make it informative and include a call-to-action.',
      pinterest: 'Write a Pinterest pin description (300 chars) for wallcovering design inspiration. Focus on style and room transformation.'
    };

    const response = await anthropic.messages.create({
      model: 'claude-sonnet-4-20250514',
      max_tokens: 512,
      messages: [{ role: 'user', content: prompts[platform] || prompts.instagram }]
    });

    const content = response.content[0].type === 'text' ? response.content[0].text : '';

    stats.socialPostsGenerated++;

    res.json({
      success: true,
      platform,
      content
    });

  } catch (error) {
    console.error('Error generating social content:', error);
    res.status(500).json({ error: 'Failed to generate social content' });
  }
});

// Shopify orders endpoint for marketing insights
app.get('/api/shopify/orders', requireAuth, async (req, res) => {
  try {
    // Fetch and analyze orders
    const orders = await fetchAndAnalyzeOrders();

    res.json({
      success: true,
      recentOrders: orders,
      orderTrends: stats.orderTrends,
      summary: {
        totalOrders: orders.length,
        lastUpdated: new Date().toISOString()
      }
    });

  } catch (error) {
    console.error('Error fetching orders:', error);
    res.status(500).json({
      error: 'Failed to fetch order data',
      success: false
    });
  }
});

app.listen(PORT, '0.0.0.0', () => {
  console.log('');
  console.log('📢 Marketing Agent');
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
  console.log('🌍 External: http://45.61.58.125:' + PORT);
  console.log('🏠 Local: http://localhost:' + PORT);
  console.log('');
  console.log('💬 Chat Mode: Active');
  console.log('📝 Shopify Blog Integration: Ready');
  console.log('✨ AI Content Generation: Active');
  console.log('📱 Social Media Tools: Ready');
  console.log('📧 Email Campaigns: Ready');
  console.log('');
  console.log('✅ Marketing Agent ready for content creation...');
});