← back to Designer Wallcoverings

DW-Agents/dw-agents/agent-legal-team/legal-agent.ts.backup

2323 lines

/**
 * DW Legal Team - Settlement Compliance Monitor
 *
 * PRIORITY #1: SETTLEMENT AGREEMENT COMPLIANCE
 *
 * This agent continuously monitors the product catalog for settlement violations
 * and provides legal guidance on tropical design patterns.
 *
 * SETTLEMENT CRITERIA (MUST BE ENFORCED):
 *
 * A product is PROHIBITED if it contains BOTH Part A AND Part B:
 *
 * Part A - Prohibited Design (ALL three must be present):
 *   1. Repeating patterns with directional variation amongst leaves/palm fronds
 *   2. Open space between leaves
 *   3. More than one ink color
 *
 * Part B - Prohibited Specific Elements (ANY of these):
 *   - Bananas (FRUIT) or banana pods (NOT leaves - banana leaves are OK)
 *   - Grapes (fruit/clusters)
 *   - Birds
 *   - Butterflies
 *
 * Acceptable Tropical Design (at least ONE must be present):
 *   1. Tree trunks
 *   2. Clearly represented branches
 *   3. Fruit or animal elements (EXCEPT prohibited ones)
 */

import 'dotenv/config';
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';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import svgCaptcha from 'svg-captcha';
import { chromium } from 'playwright';
import fetch from 'node-fetch';
import { GoogleGenerativeAI } from '@google/generative-ai';
const { getUniversalHeader } = require('../shared-ui-components.js');

const app = express();
const PORT = 9878;

// Analysis cache - stores results to avoid re-analyzing
const analysisCache = new Map<string, { compliant: boolean; analysis: string; timestamp: number }>();

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

const SHOPIFY_STORE = process.env.SHOPIFY_STORE_DOMAIN || 'designer-laboratory-sandbox.myshopify.com';
const SHOPIFY_TOKEN = process.env.SHOPIFY_ADMIN_ACCESS_TOKEN || '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';
const API_VERSION = process.env.SHOPIFY_ADMIN_API_VERSION || '2024-07';

const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});

// Settlement compliance statistics
let stats = {
  totalScanned: 0,
  violations: 0,
  compliant: 0,
  needsReview: 0,
  lastScan: null as Date | null,
  lastViolation: null as { title: string; id: string; timestamp: Date } | null,
  importsMonitored: 0,
  lastImport: null as { title: string; status: string; timestamp: Date } | null,
};

// Recent activity log for real-time monitoring
const activityLog: Array<{
  timestamp: Date;
  type: 'import' | 'violation' | 'compliant' | 'review';
  title: string;
  message: string;
}> = [];

// Violations tracking - store all detected violations
const violationsList: Array<{
  productId: string;
  sku: string;
  title: string;
  url: string;
  analysis: string;
  timestamp: Date;
}> = [];

// Function to escalate violations to needs-attention agent
async function escalateViolationToNeedsAttention(violation: {
  title: string;
  productId?: string;
  sku?: string;
  reasoning: string;
  productUrl?: string;
}) {
  try {
    console.log(`🚨 Escalating violation to needs-attention agent: ${violation.sku || violation.title}`);

    const response = await fetch('http://localhost:9900/api/webhook/task', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        title: `🚨 URGENT: Legal Violation - ${violation.sku || violation.title}`,
        description: `SETTLEMENT AGREEMENT VIOLATION DETECTED

Product: ${violation.title}
SKU: ${violation.sku || 'Unknown'}
Product ID: ${violation.productId || 'Unknown'}

VIOLATION DETAILS:
${violation.reasoning}

REQUIRED ACTIONS:
1. Immediately unpublish product from store
2. Review product images and descriptions
3. Contact legal counsel if needed
4. Document the violation in legal records

Product URL: ${violation.productUrl || `https://designer-laboratory-sandbox.myshopify.com/admin/products/${violation.productId}`}`,
        priority: 'critical',
        source: 'legal',
        metadata: {
          productId: violation.productId,
          sku: violation.sku,
          violationType: 'settlement-agreement',
          reasoning: violation.reasoning,
          agentPort: 9878,
          url: violation.productUrl || `https://designer-laboratory-sandbox.myshopify.com/admin/products/${violation.productId}`
        },
        assignedAgent: 'needs-attention'
      })
    });

    if (response.ok) {
      const result = await response.json();
      console.log(`✅ Violation escalated to needs-attention: ${result.taskId}`);
    } else {
      console.error(`❌ Failed to escalate violation: ${response.statusText}`);
    }
  } catch (error) {
    console.error(`❌ Error escalating violation: ${error}`);
  }
}

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

// Session configuration
app.use(
  session({
    secret: 'dw-legal-team-secret-key-2025',
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: false,
      httpOnly: true,
      maxAge: 24 * 60 * 60 * 1000, // 24 hours
    },
  })
);

// Extend session type
declare module 'express-session' {
  interface SessionData {
    authenticated: boolean;
    captchaText: string;
  }
}

// Authentication middleware - DISABLED FOR DEBUGGING
const requireAuth = (req: express.Request, res: express.Response, next: express.NextFunction) => {
  // TEMPORARY: Skip authentication
  next();
  return;

  if (req.session.authenticated) {
    next();
  } else {
    // For API requests, return JSON error instead of redirect
    if (req.path.startsWith('/api/')) {
      return res.status(401).json({ error: 'Authentication required' });
    }
    res.redirect('/login');
  }
};

// Settlement criteria reference
const SETTLEMENT_AGREEMENT = {
  partA: {
    description: 'Prohibited Design Pattern',
    criteria: [
      'Repeating patterns with directional variation amongst leaves/palm fronds',
      'Open space between leaves',
      'More than one ink color'
    ],
    requirement: 'ALL three conditions must be present'
  },
  partB: {
    description: 'Prohibited Specific Elements',
    criteria: [
      'Bananas (FRUIT) or banana pods (NOT leaves - banana leaves are OK)',
      'Grapes (fruit/clusters)',
      'Birds',
      'Butterflies'
    ],
    requirement: 'ANY one of these elements'
  },
  acceptable: {
    description: 'Acceptable Tropical Design Elements',
    criteria: [
      'Tree trunks',
      'Clearly represented branches',
      'Fruit or animal elements (EXCEPT prohibited ones)'
    ],
    requirement: 'At least ONE must be present for tropical designs'
  },
  violation: 'BOTH Part A (all conditions) AND Part B (any element) must be present'
};

// Login page
app.get('/login', (req, res) => {
  res.send(`
<!DOCTYPE html>
<html>
<head>
  <title>Login - DW Legal Team</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, #1a1a2e 0%, #16213e 100%);
      color: #e0e0e0;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      padding: 20px;
    }
    .login-container {
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid rgba(255, 255, 255, 0.1);
      padding: 40px;
      border-radius: 12px;
      backdrop-filter: blur(10px);
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
      max-width: 400px;
      width: 100%;
    }
    .header {
      text-align: center;
      margin-bottom: 30px;
    }
    .header h1 {
      color: #dc143c;
      font-size: 2em;
      margin-bottom: 10px;
    }
    .header p {
      color: #888;
      font-size: 0.9em;
    }
    .form-group {
      margin-bottom: 20px;
    }
    label {
      display: block;
      color: #ccc;
      margin-bottom: 8px;
      font-weight: 500;
    }
    input {
      width: 100%;
      padding: 12px;
      border: 1px solid rgba(255, 255, 255, 0.2);
      border-radius: 6px;
      background: rgba(0, 0, 0, 0.3);
      color: #fff;
      font-size: 1em;
    }
    input:focus {
      outline: none;
      border-color: #dc143c;
    }
    .captcha-container {
      display: flex;
      gap: 10px;
      align-items: center;
      margin-bottom: 20px;
    }
    .captcha-image {
      flex-shrink: 0;
      background: white;
      padding: 5px;
      border-radius: 6px;
      cursor: pointer;
    }
    .captcha-input {
      flex-grow: 1;
    }
    button {
      width: 100%;
      background: linear-gradient(135deg, #8b0000 0%, #dc143c 100%);
      color: white;
      border: none;
      padding: 15px;
      border-radius: 8px;
      font-size: 1em;
      cursor: pointer;
      font-weight: 600;
      transition: all 0.3s;
    }
    button:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 20px rgba(220, 20, 60, 0.4);
    }
    .error {
      background: rgba(255, 0, 0, 0.2);
      border: 1px solid #ff0000;
      color: #ffcccc;
      padding: 10px;
      border-radius: 6px;
      margin-bottom: 20px;
      text-align: center;
    }
    .refresh-captcha {
      font-size: 0.85em;
      color: #888;
      text-align: center;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <div class="login-container">
    <div class="header">
      <h1>⚖️ DW Legal Team</h1>
      <p>Settlement Compliance Monitor</p>
    </div>
    ${req.query.error ? '<div class="error">Invalid credentials or confirmation number</div>' : ''}
    <form method="POST" action="/login">
      <div class="form-group">
        <label>Username</label>
        <input type="text" name="username" required autocomplete="username">
      </div>
      <div class="form-group">
        <label>Password</label>
        <input type="password" name="password" required autocomplete="current-password">
      </div>
      <div class="form-group">
        <label>Confirmation: What is 7 + 3?</label>
        <input type="text" name="confirmation" required placeholder="Enter the number">
      </div>
      <button type="submit">Login</button>
    </form>
  </div>
</body>
</html>
  `);
});

// Captcha generation
app.get('/captcha', (req, res) => {
  const captcha = svgCaptcha.create({
    size: 6,
    noise: 3,
    color: true,
    background: '#f0f0f0',
  });
  req.session.captchaText = captcha.text;
  res.type('svg');
  res.send(captcha.data);
});

// Login handler
app.post('/login', (req, res) => {
  const { username, password, confirmation } = req.body;

  if (
    username === AUTH_USERNAME &&
    password === AUTH_PASSWORD &&
    confirmation === '10'
  ) {
    req.session.authenticated = true;
    res.redirect('/');
  } else {
    res.redirect('/login?error=1');
  }
});

// Logout handler
app.get('/logout', (req, res) => {
  req.session.destroy(() => {
    // Clear SSO cookie
    res.clearCookie(SSO_TOKEN_NAME);
    res.redirect('/login');
  });
});

// Main HTML interface (protected)
app.get('/', requireAuth, (req, res) => {
  res.send(`
<!DOCTYPE html>
<html>
<head>
  <title>DW Legal Team - Settlement Compliance Monitor</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, #1a1a2e 0%, #16213e 100%);
      color: #e0e0e0;
      padding: 20px;
      min-height: 100vh;
    }
    .header {
      background: linear-gradient(135deg, #8b0000 0%, #dc143c 100%);
      padding: 30px;
      border-radius: 12px;
      margin-bottom: 30px;
      box-shadow: 0 8px 32px rgba(220, 20, 60, 0.3);
    }
    .header h1 {
      color: white;
      font-size: 2.5em;
      margin-bottom: 10px;
      text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
    }
    .header .subtitle {
      color: #ffe6e6;
      font-size: 1.2em;
      font-weight: 300;
    }
    .priority-badge {
      display: inline-block;
      background: #ff0000;
      color: white;
      padding: 8px 16px;
      border-radius: 20px;
      font-weight: bold;
      margin-top: 15px;
      font-size: 0.9em;
      letter-spacing: 1px;
      animation: pulse 2s infinite;
    }
    @keyframes pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.7; }
    }
    .stats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 20px;
      margin-bottom: 30px;
    }
    .stat-card {
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid rgba(255, 255, 255, 0.1);
      padding: 20px;
      border-radius: 12px;
      backdrop-filter: blur(10px);
    }
    .stat-card h3 {
      color: #888;
      font-size: 0.9em;
      text-transform: uppercase;
      letter-spacing: 1px;
      margin-bottom: 10px;
    }
    .stat-card .value {
      font-size: 2.5em;
      font-weight: bold;
      color: #fff;
    }
    .stat-card.violations .value {
      color: #ff4444;
    }
    .stat-card.compliant .value {
      color: #4CAF50;
    }
    .stat-card.review .value {
      color: #FFA500;
    }
    .settlement-section {
      background: rgba(255, 255, 255, 0.05);
      border: 2px solid rgba(220, 20, 60, 0.5);
      padding: 30px;
      border-radius: 12px;
      margin-bottom: 30px;
      backdrop-filter: blur(10px);
    }
    .settlement-section h2 {
      color: #ff6b6b;
      margin-bottom: 20px;
      font-size: 1.8em;
      border-bottom: 2px solid rgba(220, 20, 60, 0.3);
      padding-bottom: 10px;
    }
    .criteria-box {
      background: rgba(0, 0, 0, 0.3);
      padding: 20px;
      border-radius: 8px;
      margin-bottom: 20px;
      border-left: 4px solid #dc143c;
    }
    .criteria-box h3 {
      color: #ff8888;
      margin-bottom: 15px;
      font-size: 1.3em;
    }
    .criteria-box ul {
      list-style: none;
      padding: 0;
    }
    .criteria-box li {
      padding: 10px 0;
      border-bottom: 1px solid rgba(255, 255, 255, 0.1);
      color: #ccc;
    }
    .criteria-box li:last-child {
      border-bottom: none;
    }
    .criteria-box .requirement {
      background: rgba(220, 20, 60, 0.2);
      padding: 10px;
      border-radius: 6px;
      margin-top: 15px;
      font-weight: bold;
      color: #ff9999;
    }
    .violation-rule {
      background: rgba(255, 0, 0, 0.2);
      border: 2px solid #ff0000;
      padding: 20px;
      border-radius: 8px;
      margin-top: 20px;
      font-size: 1.1em;
      font-weight: bold;
      color: #ffcccc;
      text-align: center;
    }
    .action-buttons {
      display: flex;
      gap: 15px;
      flex-wrap: wrap;
      margin-bottom: 30px;
    }
    button {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
      border: none;
      padding: 15px 30px;
      border-radius: 8px;
      font-size: 1em;
      cursor: pointer;
      transition: all 0.3s;
      font-weight: 600;
      box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
    }
    button:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
    }
    button:active {
      transform: translateY(0);
    }
    button.scan {
      background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
    }
    button.review-tool {
      background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
    }
    .log-section {
      background: rgba(0, 0, 0, 0.4);
      padding: 20px;
      border-radius: 12px;
      margin-top: 30px;
      border: 1px solid rgba(255, 255, 255, 0.1);
    }
    .log-section h2 {
      color: #fff;
      margin-bottom: 15px;
      font-size: 1.5em;
    }
    .log-entry {
      padding: 10px;
      margin: 5px 0;
      border-radius: 6px;
      font-family: 'Courier New', monospace;
      font-size: 0.9em;
    }
    .log-entry.violation {
      background: rgba(255, 68, 68, 0.2);
      border-left: 4px solid #ff4444;
      color: #ff9999;
    }
    .log-entry.compliant {
      background: rgba(76, 175, 80, 0.2);
      border-left: 4px solid #4CAF50;
      color: #a5d6a7;
    }
    .log-entry.info {
      background: rgba(100, 100, 100, 0.2);
      border-left: 4px solid #888;
      color: #ccc;
    }
    .last-violation {
      background: rgba(255, 0, 0, 0.15);
      padding: 20px;
      border-radius: 8px;
      margin-top: 20px;
      border: 2px solid rgba(255, 0, 0, 0.3);
    }
    .last-violation h3 {
      color: #ff6666;
      margin-bottom: 10px;
    }
    .last-violation p {
      color: #ffcccc;
      margin: 5px 0;
    }
    .url-checker-section {
      background: rgba(255, 255, 255, 0.05);
      border: 2px solid rgba(102, 126, 234, 0.5);
      padding: 25px;
      border-radius: 12px;
      margin-bottom: 30px;
      backdrop-filter: blur(10px);
    }
    .url-checker-section h2 {
      color: #8888ff;
      margin-bottom: 20px;
      font-size: 1.6em;
    }
    .url-input-form {
      display: flex;
      gap: 15px;
      margin-bottom: 20px;
    }
    .url-input-form input {
      flex: 1;
      padding: 15px;
      border: 2px solid rgba(102, 126, 234, 0.5);
      border-radius: 8px;
      background: rgba(0, 0, 0, 0.3);
      color: #fff;
      font-size: 1em;
    }
    .url-input-form input:focus {
      outline: none;
      border-color: #667eea;
      box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2);
    }
    .url-input-form button {
      padding: 15px 40px;
      white-space: nowrap;
    }
    .url-result {
      background: rgba(0, 0, 0, 0.4);
      padding: 20px;
      border-radius: 8px;
      border-left: 4px solid #667eea;
      display: none;
    }
    .url-result.pass {
      border-left-color: #4CAF50;
      background: rgba(76, 175, 80, 0.1);
    }
    .url-result.violation {
      border-left-color: #ff4444;
      background: rgba(255, 68, 68, 0.1);
    }
    .url-result.checking {
      border-left-color: #FFA500;
      background: rgba(255, 165, 0, 0.1);
    }
    .url-result h3 {
      margin-bottom: 15px;
      font-size: 1.3em;
    }
    .url-result pre {
      white-space: pre-wrap;
      word-wrap: break-word;
      color: #ccc;
      line-height: 1.6;
    }
  </style>
</head>
<body style="padding: 20px;">
  ${getUniversalHeader('Legal Team', PORT, 5)}

  <div class="header" style="margin-top: 20px;">
    <h1>⚖️ DW Legal Team</h1>
    <div class="subtitle">Settlement Compliance Monitor</div>
    <div class="priority-badge">🚨 PRIORITY #1: SETTLEMENT AGREEMENT</div>
    <div style="text-align: right; margin-top: 15px;">
      <a href="/logout" style="color: #ffe6e6; text-decoration: none; padding: 8px 16px; background: rgba(0,0,0,0.3); border-radius: 6px; font-size: 0.9em;">Logout</a>
    </div>
  </div>

  <div id="violationsList" class="violations-alert" style="display: none; background: rgba(255, 0, 0, 0.2); border: 4px solid #ff0000; padding: 30px; border-radius: 15px; margin-bottom: 25px; animation: pulse-red 2s infinite;">
    <h2 style="color: #ff0000; font-size: 2.2em; text-align: center; margin-bottom: 20px;">🚨 SETTLEMENT VIOLATIONS DETECTED</h2>
    <div id="violationsContent"></div>
  </div>

  <div class="settlement-section" style="background: rgba(220, 20, 60, 0.15); border: 3px solid #dc143c;">
    <h2>📋 Settlement Agreement - Quick Reference</h2>

    <div class="violation-rule" style="margin-bottom: 20px;">
      ⚠️ VIOLATION OCCURS WHEN: BOTH Part A (all conditions) AND Part B (any element) are present
    </div>

    <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
      <div class="criteria-box">
        <h3>Part A: Prohibited Design Pattern</h3>
        <ul>
          <li>✓ Repeating patterns with directional variation amongst leaves/palm fronds</li>
          <li>✓ Open space between leaves</li>
          <li>✓ More than one ink color</li>
        </ul>
        <div class="requirement">ALL three conditions must be present</div>
      </div>

      <div class="criteria-box">
        <h3>Part B: Prohibited Specific Elements</h3>
        <ul>
          <li>🚫 Bananas (FRUIT) or banana pods - <strong style="color: #90EE90;">NOTE: Banana LEAVES are OK!</strong></li>
          <li>🚫 Grapes (fruit/clusters)</li>
          <li>🚫 Birds</li>
          <li>🚫 Butterflies</li>
        </ul>
        <div class="requirement">ANY one of these elements</div>
      </div>
    </div>

    <div class="criteria-box" style="margin-top: 20px; border-left-color: #4CAF50;">
      <h3 style="color: #90EE90;">✅ Acceptable Tropical Design Elements</h3>
      <ul>
        <li>✓ Tree trunks</li>
        <li>✓ Clearly represented branches</li>
        <li>✓ Fruit or animal elements (EXCEPT prohibited ones)</li>
      </ul>
      <div class="requirement" style="background: rgba(76, 175, 80, 0.2); color: #a5d6a7;">At least ONE must be present for tropical designs</div>
    </div>
  </div>

  <div class="url-checker-section">
    <h2>🔍 Quick URL Compliance Check</h2>
    <form class="url-input-form" onsubmit="checkURL(event)">
      <input type="url" id="urlInput" placeholder="Enter product URL to check for settlement compliance..." required>
      <button type="submit">Check Now</button>
    </form>
    <div id="urlResult" class="url-result"></div>
  </div>

  <div class="stats-grid">
    <div class="stat-card">
      <h3>Imports Monitored</h3>
      <div class="value" id="importsMonitored">0</div>
    </div>
    <div class="stat-card violations">
      <h3>Violations</h3>
      <div class="value" id="violations">0</div>
    </div>
    <div class="stat-card compliant">
      <h3>Compliant</h3>
      <div class="value" id="compliant">0</div>
    </div>
    <div class="stat-card review">
      <h3>Needs Review</h3>
      <div class="value" id="needsReview">0</div>
    </div>
  </div>

  <div id="lastImport" class="last-violation" style="display:none; background: rgba(0, 100, 255, 0.15); border-color: rgba(0, 100, 255, 0.3);">
    <h3>📦 Most Recent Import</h3>
    <p id="importTitle"></p>
    <p id="importStatus"></p>
    <p id="importTime"></p>
  </div>

  <div class="settlement-section">
    <h2>📋 Settlement Agreement Criteria</h2>

    <div class="criteria-box">
      <h3>Part A: Prohibited Design Pattern</h3>
      <ul>
        <li>✓ Repeating patterns with directional variation amongst leaves/palm fronds</li>
        <li>✓ Open space between leaves</li>
        <li>✓ More than one ink color</li>
      </ul>
      <div class="requirement">ALL three conditions must be present</div>
    </div>

    <div class="criteria-box">
      <h3>Part B: Prohibited Specific Elements</h3>
      <ul>
        <li>🚫 Bananas (FRUIT) or banana pods - <strong style="color: #90EE90;">NOTE: Banana LEAVES are OK!</strong></li>
        <li>🚫 Grapes (fruit/clusters)</li>
        <li>🚫 Birds</li>
        <li>🚫 Butterflies</li>
      </ul>
      <div class="requirement">ANY one of these elements</div>
    </div>

    <div class="criteria-box">
      <h3>✅ Acceptable Tropical Design Elements</h3>
      <ul>
        <li>✓ Tree trunks</li>
        <li>✓ Clearly represented branches</li>
        <li>✓ Fruit or animal elements (EXCEPT prohibited ones)</li>
      </ul>
      <div class="requirement">At least ONE must be present for tropical designs</div>
    </div>

    <div class="violation-rule">
      ⚠️ VIOLATION OCCURS WHEN: BOTH Part A (all conditions) AND Part B (any element) are present
    </div>
  </div>

  <div class="settlement-section" style="background: rgba(220, 20, 60, 0.1); border: 2px solid #dc143c;">
    <h2>🔍 Search for Settlement Violations</h2>

    <div class="criteria-box">
      <h3>🚫 Search by Prohibited Elements (Part B)</h3>
      <div class="action-buttons" style="grid-template-columns: repeat(4, 1fr);">
        <button class="scan" onclick="searchByKeyword('banana')">🍌 Bananas</button>
        <button class="scan" onclick="searchByKeyword('grape')">🍇 Grapes</button>
        <button class="scan" onclick="searchByKeyword('bird')">🦜 Birds</button>
        <button class="scan" onclick="searchByKeyword('butterfly')">🦋 Butterflies</button>
      </div>
    </div>

    <div class="criteria-box">
      <h3>🌴 Search by Tropical Keywords</h3>
      <div class="action-buttons" style="grid-template-columns: repeat(4, 1fr);">
        <button class="scan" onclick="searchByKeyword('palm')">🌴 Palm</button>
        <button class="scan" onclick="searchByKeyword('tropical')">🏝️ Tropical</button>
        <button class="scan" onclick="searchByKeyword('leaf')">🍃 Leaf</button>
        <button class="scan" onclick="searchByKeyword('frond')">🌿 Frond</button>
        <button class="scan" onclick="searchByKeyword('jungle')">🌳 Jungle</button>
        <button class="scan" onclick="searchByKeyword('exotic')">🦎 Exotic</button>
        <button class="scan" onclick="searchByKeyword('botanical')">🌺 Botanical</button>
        <button class="scan" onclick="searchByKeyword('paradise')">🦚 Paradise</button>
      </div>
    </div>

    <div class="criteria-box">
      <h3>⚠️ Search by Fruit & Nature Keywords</h3>
      <div class="action-buttons" style="grid-template-columns: repeat(4, 1fr);">
        <button class="scan" onclick="searchByKeyword('fruit')">🍎 Fruit</button>
        <button class="scan" onclick="searchByKeyword('flower')">🌸 Flower</button>
        <button class="scan" onclick="searchByKeyword('blossom')">🌼 Blossom</button>
        <button class="scan" onclick="searchByKeyword('vine')">🍇 Vine</button>
      </div>
    </div>
  </div>

  <div class="action-buttons">
    <button class="scan" onclick="scanCatalog()">🔍 Scan Entire Catalog</button>
    <button class="scan" onclick="scanNewProducts()">🆕 Scan New Products (24h)</button>
    <button class="scan" onclick="scanTagged()">🏷️ Scan SETTLEMENT Tagged</button>
    <button class="review-tool" onclick="openReviewTool()">📊 Open Settlement Review Tool</button>
  </div>

  <div id="search-results" style="margin-top: 30px;"></div>

  <div id="lastViolation" class="last-violation" style="display:none;">
    <h3>🚨 Most Recent Violation</h3>
    <p id="violationTitle"></p>
    <p id="violationId"></p>
    <p id="violationTime"></p>
  </div>

  <div class="log-section">
    <h2>📝 Activity Log</h2>
    <div id="logs"></div>
  </div>

  <script>
    function updateStats() {
      fetch('/api/stats')
        .then(r => r.json())
        .then(data => {
          document.getElementById('importsMonitored').textContent = data.importsMonitored;
          document.getElementById('violations').textContent = data.violations;
          document.getElementById('compliant').textContent = data.compliant;
          document.getElementById('needsReview').textContent = data.needsReview;

          if (data.lastImport) {
            document.getElementById('lastImport').style.display = 'block';
            document.getElementById('importTitle').textContent = 'Product: ' + data.lastImport.title;
            document.getElementById('importStatus').textContent = 'Status: ' + data.lastImport.status;
            document.getElementById('importTime').textContent = 'Time: ' + new Date(data.lastImport.timestamp).toLocaleString();
          }
        });

      // Update violations list
      fetch('/api/violations')
        .then(r => r.json())
        .then(violations => {
          const violationsList = document.getElementById('violationsList');
          const violationsContent = document.getElementById('violationsContent');

          if (violations.length > 0) {
            violationsList.style.display = 'block';
            violationsContent.innerHTML = violations.map(function(v) {
              return '<div style="background: white; border-left: 6px solid #ff0000; padding: 20px; margin-bottom: 15px; border-radius: 8px; color: #333;">' +
                '<h3 style="color: #ff0000; margin-bottom: 10px;">' + v.title + '</h3>' +
                '<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin-bottom: 10px; font-size: 0.9em;">' +
                  '<div><strong>SKU:</strong> ' + v.sku + '</div>' +
                  '<div><strong>Product ID:</strong> ' + v.productId + '</div>' +
                  '<div><strong>Detected:</strong> ' + new Date(v.timestamp).toLocaleDateString() + '</div>' +
                '</div>' +
                '<div style="background: #fff8f8; padding: 15px; border-radius: 6px; margin: 10px 0; font-size: 0.9em; white-space: pre-wrap;">' + v.analysis + '</div>' +
                '<a href="' + v.url + '" target="_blank" style="display: inline-block; background: #dc143c; color: white; padding: 10px 20px; border-radius: 6px; text-decoration: none; font-weight: bold;">View in Shopify →</a>' +
              '</div>';
            }).join('');
          } else {
            violationsList.style.display = 'none';
          }
        });
    }

    function addLog(message, type = 'info') {
      const logsDiv = document.getElementById('logs');
      const entry = document.createElement('div');
      entry.className = 'log-entry ' + type;
      entry.textContent = new Date().toLocaleTimeString() + ' - ' + message;
      logsDiv.insertBefore(entry, logsDiv.firstChild);

      // Keep only last 50 entries
      while (logsDiv.children.length > 50) {
        logsDiv.removeChild(logsDiv.lastChild);
      }
    }

    function searchByKeyword(keyword) {
      addLog(\`Searching for products containing "\${keyword}"...\`, 'info');
      const resultsDiv = document.getElementById('search-results');
      resultsDiv.innerHTML = '<div style="color: #FFA500; text-align: center; padding: 40px;">⏳ Searching...</div>';

      fetch(\`/api/search/keyword?q=\${encodeURIComponent(keyword)}\`, {
        credentials: 'same-origin'
      })
        .then(r => {
          if (!r.ok) {
            throw new Error(\`HTTP \${r.status}: \${r.statusText}\`);
          }
          return r.json();
        })
        .then(data => {
          if (data.error) {
            throw new Error(data.error);
          }
          if (data.products && data.products.length > 0) {
            addLog(\`Found \${data.products.length} products with "\${keyword}" - Analyzing for violations...\`, 'success');
            showSearchResults(keyword, data.products);
          } else {
            addLog(\`No products found containing "\${keyword}"\`, 'info');
            resultsDiv.innerHTML = '<div style="color: #aaa; text-align: center; padding: 40px;">No products found</div>';
          }
        })
        .catch(err => {
          addLog(\`Error searching for "\${keyword}": \${err.message}\`, 'error');
          resultsDiv.innerHTML = '<div style="color: #dc143c; text-align: center; padding: 40px;">Error: ' + err.message + '</div>';
        });
    }

    function showSearchResults(keyword, products) {
      const resultsDiv = document.getElementById('search-results');
      resultsDiv.innerHTML = \`
        <h2 style="color: #dc143c; margin-bottom: 20px;">🔍 "\` + keyword + \`" - Found \` + products.length + \` Products</h2>
        <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px;">
          \` + products.map(p => \`
            <div id="product-\` + p.id + \`" style="position: relative; background: rgba(255,255,255,0.05); padding: 20px; border-radius: 12px; border-left: 4px solid #dc143c;">
              <div style="position: absolute; top: 10px; right: 10px; z-index: 10;">
                <span style="background: \` + (p.status === 'active' ? '#4CAF50' : '#FFA500') + \`; color: white; padding: 4px 12px; border-radius: 20px; font-size: 0.75em; font-weight: bold;">\` + (p.status === 'active' ? '🟢 ACTIVE' : '🟡 DRAFT') + \`</span>
              </div>
              \` + (p.image ? '<img src="' + p.image + '" alt="' + p.title + '" style="width: 100%; height: 200px; object-fit: cover; border-radius: 8px; margin-bottom: 15px;">' : '<div style="width: 100%; height: 200px; background: rgba(255,255,255,0.1); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #666; margin-bottom: 15px;">No Image</div>') + \`
              <h3 style="color: #fff; margin: 0 0 10px 0; font-size: 1.1em;">\` + p.title + \`</h3>
              <div style="color: #aaa; font-size: 0.85em; margin-bottom: 10px;">
                <div>SKU: \` + (p.sku || 'N/A') + \`</div>
                <div>ID: \` + p.id + \`</div>
                \` + (p.vendor ? '<div>Vendor: ' + p.vendor + '</div>' : '') + \`
              </div>
              <div id="compliance-\` + p.id + \`" style="margin: 10px 0;">
                <div style="color: #FFA500; font-size: 0.85em;">⏳ Analyzing...</div>
              </div>
              <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px;">
                <a href="https://admin.shopify.com/store/designer-laboratory-sandbox/products/\` + p.id + \`" target="_blank" style="background: #4CAF50; color: white; padding: 10px; border-radius: 6px; text-decoration: none; font-size: 0.85em; text-align: center; font-weight: bold;">📝 Shopify</a>
                <button onclick="setToDraft('\` + p.id + \`')" style="background: #dc143c; color: white; padding: 10px; border-radius: 6px; border: none; font-size: 0.85em; cursor: pointer; font-weight: bold;">⚠️ Set Draft</button>
              </div>
            </div>
          \`).join('') + \`
        </div>
      \`;

      // Auto-check compliance with AI for all products
      products.forEach(p => {
        if (p.image) {
          checkProductWithImage(p.image, p.title, p.tags, p.id);
        } else if (p.online_store_url) {
          checkProductCompliance(p.online_store_url, p.id);
        }
      });
    }

    function formatAnalysis(text) {
      // Format the analysis to clearly separate CRITERIA SET A and SET B
      let formatted = text;

      // Add visual separators for the sections
      formatted = formatted.replace(/CRITERIA SET A:/gi, '<div style="margin-top: 10px; padding: 8px; background: rgba(255,255,255,0.05); border-radius: 4px;"><strong style="color: #FFD700;">📋 CRITERIA SET A (Pattern Features):</strong>');
      formatted = formatted.replace(/CRITERIA SET B:/gi, '</div><div style="margin-top: 8px; padding: 8px; background: rgba(255,255,255,0.05); border-radius: 4px;"><strong style="color: #FF6B6B;">🚫 CRITERIA SET B (Prohibited Elements):</strong>');
      formatted = formatted.replace(/Final answer:/gi, '</div><div style="margin-top: 10px; padding: 8px; border-top: 2px solid rgba(255,255,255,0.2);"><strong>Final answer:</strong>');

      return formatted;
    }

    function sortProductsToTop() {
      // Move all violation cards to the top
      const resultsContainer = document.querySelector('#search-results > div');
      if (!resultsContainer) return;

      const productCards = Array.from(resultsContainer.children);
      const violations = [];
      const compliant = [];

      productCards.forEach(card => {
        const complianceDiv = card.querySelector('[id^="compliance-"]');
        if (complianceDiv && complianceDiv.innerHTML.includes('🚨 SETTLEMENT VIOLATION')) {
          violations.push(card);
        } else {
          compliant.push(card);
        }
      });

      // Clear and re-add: violations first, then compliant
      resultsContainer.innerHTML = '';
      violations.forEach(card => resultsContainer.appendChild(card));
      compliant.forEach(card => resultsContainer.appendChild(card));
    }

    function checkProductWithImage(imageUrl, title, tags, productId) {
      const complianceDiv = document.getElementById(\`compliance-\${productId}\`);
      complianceDiv.innerHTML = '<div style="color: #FFA500; font-size: 0.85em;">⏳ AI analyzing image...</div>';

      fetch('/api/check-image', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ imageUrl, title, tags, productId })
      })
      .then(r => r.json())
      .then(data => {
        const verifiedBadge = data.cached ? '<div style="display: inline-block; background: #2196F3; color: white; padding: 4px 10px; border-radius: 12px; font-size: 0.75em; margin-left: 8px;">✓ VERIFIED</div>' : '';

        if (data.compliant === false) {
          complianceDiv.innerHTML = \`
            <div style="background: rgba(220, 20, 60, 0.2); border: 2px solid #dc143c; padding: 12px; border-radius: 6px;">
              <div><strong style="color: #ff6b6b;">🚨 SETTLEMENT VIOLATION</strong>\${verifiedBadge}</div>
              <div style="color: #ffaaaa; font-size: 0.85em; margin-top: 8px; line-height: 1.6;">
                \${formatAnalysis(data.analysis || data.reason || 'Violates settlement agreement')}
              </div>
            </div>
          \`;
          // Sort violations to top after marking
          setTimeout(sortProductsToTop, 100);
        } else {
          complianceDiv.innerHTML = \`
            <div style="background: rgba(76, 175, 80, 0.15); border: 1px solid #4CAF50; padding: 10px; border-radius: 6px;">
              <div><strong style="color: #90EE90; font-size: 0.85em;">✅ COMPLIANT</strong>\${verifiedBadge}</div>
              <div style="color: #aaa; font-size: 0.8em; margin-top: 4px; line-height: 1.6;">
                \${formatAnalysis(data.analysis || 'No settlement violations detected')}
              </div>
            </div>
          \`;
        }
      })
      .catch(err => {
        complianceDiv.innerHTML = '<div style="color: #dc143c; font-size: 0.85em;">Error: ' + err.message + '</div>';
      });
    }

    function checkProductCompliance(url, productId) {
      const complianceDiv = document.getElementById(\`compliance-\${productId}\`);
      complianceDiv.innerHTML = '<div style="color: #FFA500;">⏳ Analyzing for settlement violations...</div>';

      fetch('/api/check-url', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ url })
      })
      .then(r => r.json())
      .then(data => {
        if (data.compliant === false) {
          complianceDiv.innerHTML = \`
            <div style="background: rgba(220,20,60,0.2); border: 2px solid #dc143c; padding: 15px; border-radius: 8px; margin-top: 10px;">
              <div style="color: #dc143c; font-weight: bold; font-size: 1.1em; margin-bottom: 10px;">🚨 SETTLEMENT VIOLATION DETECTED</div>
              <div style="color: #fff; margin-bottom: 8px;"><strong>Reason:</strong> \${data.reason || 'Contains prohibited elements'}</div>
              \${data.analysis ? '<div style="color: #aaa; font-size: 0.9em; margin-top: 8px;">' + data.analysis + '</div>' : ''}
            </div>
          \`;
        } else {
          complianceDiv.innerHTML = \`
            <div style="background: rgba(76,175,80,0.2); border: 2px solid #4CAF50; padding: 15px; border-radius: 8px; margin-top: 10px;">
              <div style="color: #4CAF50; font-weight: bold;">✅ COMPLIANT</div>
              <div style="color: #aaa; font-size: 0.9em; margin-top: 5px;">\${data.reason || 'No settlement violations detected'}</div>
            </div>
          \`;
        }
      })
      .catch(err => {
        complianceDiv.innerHTML = \`<div style="color: #FFA500;">⚠️ Error: \${err.message}</div>\`;
      });
    }

    function scanCatalog() {
      addLog('Starting full catalog scan...', 'info');
      fetch('/api/scan/catalog', { method: 'POST' })
        .then(r => r.json())
        .then(data => {
          addLog('Catalog scan complete: ' + data.scanned + ' products scanned', 'info');
          updateStats();
        });
    }

    function scanNewProducts() {
      addLog('Scanning products from last 24 hours...', 'info');
      fetch('/api/scan/new', { method: 'POST' })
        .then(r => r.json())
        .then(data => {
          addLog('New products scan complete: ' + data.scanned + ' products scanned', 'info');
          updateStats();
        });
    }

    function scanTagged() {
      addLog('Scanning SETTLEMENT tagged products...', 'info');
      fetch('/api/scan/tagged', { method: 'POST' })
        .then(r => r.json())
        .then(data => {
          addLog('Tagged products scan complete: ' + data.scanned + ' products scanned', 'info');
          updateStats();
        });
    }

    function openReviewTool() {
      window.open('http://45.61.58.125:9877', '_blank');
    }

    async function setToDraft(productId) {
      if (!confirm('Set this product to DRAFT status? This will hide it from the store.')) {
        return;
      }

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

        const data = await response.json();

        if (data.success) {
          addLog(\`Product \${productId} set to DRAFT\`, 'success');
          alert('✅ Product set to DRAFT successfully!');
          // Refresh the card to show new status
          location.reload();
        } else {
          throw new Error(data.error || 'Failed to set draft');
        }
      } catch (error) {
        addLog(\`Error setting product to draft: \${error.message}\`, 'error');
        alert('❌ Error: ' + error.message);
      }
    }

    async function checkURL(event) {
      event.preventDefault();

      const urlInput = document.getElementById('urlInput');
      const resultDiv = document.getElementById('urlResult');
      const url = urlInput.value.trim();

      if (!url) return;

      // Show checking state
      resultDiv.className = 'url-result checking';
      resultDiv.style.display = 'block';
      resultDiv.innerHTML = '<h3>🔄 Checking URL...</h3><p>Scraping page and analyzing for settlement compliance...</p>';

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

        const data = await response.json();

        if (data.error) {
          resultDiv.className = 'url-result violation';
          resultDiv.innerHTML = '<h3>❌ Error</h3><pre>' + data.error + '</pre>';
          return;
        }

        if (data.status === 'PASS') {
          resultDiv.className = 'url-result pass';
          resultDiv.innerHTML = '<h3>✅ PASS - Compliant</h3><pre>' + data.analysis + '</pre>';
          addLog('URL check PASSED: ' + url, 'compliant');
        } else if (data.status === 'VIOLATION') {
          resultDiv.className = 'url-result violation';
          resultDiv.innerHTML = '<h3>🚨 VIOLATION - Settlement Issue Detected</h3><pre>' + data.analysis + '</pre>';
          addLog('URL check VIOLATION: ' + url, 'violation');
        } else {
          resultDiv.className = 'url-result';
          resultDiv.innerHTML = '<h3>⚠️ Needs Review</h3><pre>' + data.analysis + '</pre>';
          addLog('URL check needs review: ' + url, 'info');
        }
      } catch (error) {
        resultDiv.className = 'url-result violation';
        resultDiv.innerHTML = '<h3>❌ Error</h3><pre>Failed to check URL: ' + error.message + '</pre>';
      }
    }

    // Update stats every 10 seconds
    setInterval(updateStats, 10000);
    updateStats();

    addLog('DW Legal Team initialized - Settlement compliance monitoring active', 'info');
  </script>
</body>
</html>
  `);
});

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

app.get('/api/activity', requireAuth, (req, res) => {
  // Return last 100 activity log entries
  res.json(activityLog.slice(-100).reverse());
});

app.get('/api/violations', requireAuth, (req, res) => {
  // Return all violations sorted by most recent first
  res.json(violationsList.slice().reverse());
});

// Shopify webhook for product updates (DRAFT → ACTIVE monitoring)
app.post('/api/webhook/product-update', async (req, res) => {
  try {
    console.log('\n📦 Product Update Webhook Received');

    const product = req.body;
    const productId = product.id?.toString().replace(/\D/g, '') || product.admin_graphql_api_id?.toString().replace(/\D/g, '');
    const title = product.title;
    const status = product.status;

    console.log(`   Product: ${title}`);
    console.log(`   Status: ${status}`);
    console.log(`   ID: ${productId}`);

    // Check if product is being activated (draft → active)
    if (status === 'active') {
      console.log(`\n🔍 PRODUCT ACTIVATED - Checking for existing analysis: ${title}`);

      // FIRST: Check Shopify metafields - DO NOT REANALYZE if already verified
      try {
        const metafieldsResponse = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}/metafields.json`, {
          headers: {
            'X-Shopify-Access-Token': SHOPIFY_TOKEN,
            'Content-Type': 'application/json'
          }
        });

        const metafields = await metafieldsResponse.json();
        const statusField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_status');
        const analysisField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_analysis');

        if (statusField && analysisField) {
          console.log(`   ✓ Already analyzed - Status: ${statusField.value} (NO API CALL MADE)`);

          // Use stored analysis - NO new API call
          const isViolation = statusField.value === 'VIOLATION';

          if (isViolation) {
            console.log(`\n🚨 EXISTING VIOLATION DETECTED ON ACTIVATION: ${title}`);

            const sku = product.variants?.[0]?.sku || 'Unknown';

            // Escalate to needs-attention
            await escalateViolationToNeedsAttention({
              title,
              productId,
              sku,
              reasoning: analysisField.value,
              productUrl: `https://admin.shopify.com/store/${SHOPIFY_STORE.replace('.myshopify.com', '')}/products/${productId}`
            });

            stats.violations++;
          } else {
            console.log(`   ✅ Product is compliant (from stored analysis)`);
            stats.compliant++;
          }

          stats.importsMonitored++;
          return res.status(200).json({ received: true, reanalyzed: false });
        }
      } catch (metafieldError) {
        console.log(`   ⚠️ No existing analysis found, will analyze now`);
      }

      // ONLY if no metafields exist: Analyze the product
      const imageUrl = product.image?.src || product.images?.[0]?.src;
      const sku = product.variants?.[0]?.sku || 'Unknown';

      if (imageUrl) {
        console.log(`   🔬 First-time analysis (will be saved for future)`);

        // Trigger compliance check
        setTimeout(async () => {
          try {
            const checkResponse = await fetch(`http://localhost:${PORT}/api/check-image`, {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                'Cookie': `${SSO_TOKEN_NAME}=${SSO_TOKEN_VALUE}`
              },
              body: JSON.stringify({
                imageUrl,
                title,
                tags: product.tags || '',
                productId,
                sku
              })
            });

            const result = await checkResponse.json();

            if (!result.compliant) {
              console.log(`\n🚨 NEW VIOLATION DETECTED ON ACTIVATION: ${title}`);

              // Escalate to needs-attention
              await escalateViolationToNeedsAttention({
                title,
                productId,
                sku,
                reasoning: result.analysis,
                productUrl: `https://admin.shopify.com/store/${SHOPIFY_STORE.replace('.myshopify.com', '')}/products/${productId}`
              });

              stats.violations++;
            } else {
              console.log(`   ✅ Product is compliant`);
              stats.compliant++;
            }

            stats.importsMonitored++;
          } catch (error) {
            console.error(`   ❌ Error checking product: ${error}`);
          }
        }, 1000);
      }
    }

    res.status(200).json({ received: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: 'Webhook processing failed' });
  }
});

// Webhook to receive import notifications
app.post('/api/webhook/import', (req, res) => {
  try {
    const { title, status, settlementCheck } = req.body;

    stats.importsMonitored++;
    stats.lastImport = {
      title,
      status: settlementCheck?.status || 'unknown',
      timestamp: new Date(),
    };

    // Log the import activity
    if (settlementCheck?.violates) {
      stats.violations++;
      stats.lastViolation = {
        title,
        id: req.body.productId || 'unknown',
        timestamp: new Date(),
      };

      activityLog.push({
        timestamp: new Date(),
        type: 'violation',
        title,
        message: `🚨 VIOLATION: ${settlementCheck.reasoning}`,
      });

      console.log(`🚨 VIOLATION DETECTED: ${title}`);

      // Escalate to needs-attention agent
      escalateViolationToNeedsAttention({
        title,
        productId: req.body.productId,
        sku: req.body.sku,
        reasoning: settlementCheck.reasoning,
        productUrl: req.body.productUrl
      }).catch(err => console.error('Failed to escalate violation:', err));
    } else if (settlementCheck?.needsReview) {
      stats.needsReview++;

      activityLog.push({
        timestamp: new Date(),
        type: 'review',
        title,
        message: `⚠️  Needs Review: ${settlementCheck.reasoning}`,
      });

      console.log(`⚠️  NEEDS REVIEW: ${title}`);
    } else {
      stats.compliant++;

      activityLog.push({
        timestamp: new Date(),
        type: 'compliant',
        title,
        message: `✅ Compliant: Settlement check passed`,
      });

      console.log(`✅ COMPLIANT: ${title}`);
    }

    // Keep only last 1000 activity entries
    if (activityLog.length > 1000) {
      activityLog.splice(0, activityLog.length - 1000);
    }

    res.json({ success: true });
  } catch (error) {
    console.error('Webhook error:', error);
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

app.get('/api/settlement-criteria', requireAuth, (req, res) => {
  res.json(SETTLEMENT_AGREEMENT);
});

app.post('/api/scan/catalog', requireAuth, async (req, res) => {
  try {
    // This would scan the entire catalog
    res.json({ success: true, scanned: 0, message: 'Full catalog scan initiated' });
  } catch (error) {
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

app.post('/api/scan/new', requireAuth, async (req, res) => {
  try {
    // This would scan products from last 24 hours
    res.json({ success: true, scanned: 0, message: 'New products scan initiated' });
  } catch (error) {
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

app.post('/api/scan/tagged', requireAuth, async (req, res) => {
  try {
    // This would scan SETTLEMENT tagged products
    res.json({ success: true, scanned: 0, message: 'Tagged products scan initiated' });
  } catch (error) {
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

// Keyword search endpoint
app.get('/api/search/keyword', requireAuth, async (req, res) => {
  try {
    const keyword = req.query.q as string;
    console.log(`🔍 SEARCH REQUEST RECEIVED: keyword="${keyword}"`);

    if (!keyword) {
      console.error('❌ No keyword provided');
      return res.status(400).json({ error: 'Query parameter required' });
    }

    console.log(`🔎 GraphQL search for keyword "${keyword}" across ALL products...`);

    // Use GraphQL to search across ALL products (not limited to 250)
    const graphqlQuery = `
      query SearchProducts($query: String!) {
        products(first: 250, query: $query) {
          edges {
            node {
              id
              legacyResourceId
              title
              vendor
              tags
              productType
              handle
              descriptionHtml
              status
              featuredImage {
                url
                altText
              }
              variants(first: 1) {
                edges {
                  node {
                    sku
                  }
                }
              }
            }
          }
          pageInfo {
            hasNextPage
            endCursor
          }
        }
      }
    `;

    // Build search query - search in title, tag, product_type, vendor, body
    const searchQuery = `title:*${keyword}* OR tag:*${keyword}* OR product_type:*${keyword}* OR vendor:*${keyword}* OR body:*${keyword}*`;

    let allProducts: any[] = [];
    let hasNextPage = true;
    let cursor = null;
    let pageCount = 0;

    while (hasNextPage && pageCount < 20) { // Max 20 pages = 5000 products
      pageCount++;

      const queryWithCursor = cursor
        ? graphqlQuery.replace('first: 250', `first: 250, after: "${cursor}"`)
        : graphqlQuery;

      const response = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/graphql.json`, {
        method: 'POST',
        headers: {
          'X-Shopify-Access-Token': SHOPIFY_TOKEN,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          query: queryWithCursor,
          variables: { query: searchQuery }
        })
      });

      if (!response.ok) {
        console.error(`Shopify GraphQL API error: ${response.status} ${response.statusText}`);
        return res.status(500).json({ error: `Shopify GraphQL API error: ${response.status}` });
      }

      const data: any = await response.json();

      if (data.errors) {
        console.error('GraphQL errors:', data.errors);
        return res.status(500).json({ error: 'GraphQL query error' });
      }

      const edges = data.data?.products?.edges || [];
      allProducts.push(...edges.map((e: any) => e.node));

      hasNextPage = data.data?.products?.pageInfo?.hasNextPage || false;
      cursor = data.data?.products?.pageInfo?.endCursor;

      console.log(`Page ${pageCount}: Found ${edges.length} products, Total: ${allProducts.length}`);
    }

    console.log(`✅ GraphQL search complete: Found ${allProducts.length} matching products for "${keyword}"`);

    const formattedProducts = allProducts.map((p: any) => ({
      id: p.legacyResourceId,
      title: p.title,
      vendor: p.vendor,
      tags: Array.isArray(p.tags) ? p.tags.join(', ') : p.tags || '',
      product_type: p.productType,
      sku: p.variants?.edges?.[0]?.node?.sku || null,
      image: p.featuredImage?.url || null,
      online_store_url: `https://www.designerwallcoverings.com/products/${p.handle}`,
      status: p.status?.toLowerCase() || 'draft'
    }));

    // Sort by status: ACTIVE first, then DRAFT
    formattedProducts.sort((a, b) => {
      if (a.status === 'active' && b.status !== 'active') return -1;
      if (a.status !== 'active' && b.status === 'active') return 1;
      return 0;
    });

    console.log(`📦 Sending ${formattedProducts.length} formatted products to frontend (sorted by status)`);
    res.json({ products: formattedProducts, keyword, count: formattedProducts.length });
  } catch (error) {
    console.error('Keyword search error:', error);
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

// Image compliance checker endpoint - STRICT analysis with Claude
app.post('/api/check-image', requireAuth, async (req, res) => {
  try {
    const { imageUrl, title, tags, productId } = req.body;

    if (!imageUrl) {
      return res.status(400).json({ error: 'Image URL is required' });
    }

    // Check cache FIRST - if product already analyzed, return cached result
    const cacheKey = productId || imageUrl;
    const cached = analysisCache.get(cacheKey);
    if (cached) {
      console.log(`✓ Cache hit for: ${title}`);
      return res.json({
        compliant: cached.compliant,
        analysis: cached.analysis,
        reason: cached.compliant ? 'No violations found' : 'Settlement violation detected',
        cached: true,
        timestamp: cached.timestamp
      });
    }

    // Check Shopify metafields - DO NOT REANALYZE if already verified
    if (productId) {
      try {
        const metafieldsResponse = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}/metafields.json`, {
          headers: {
            'X-Shopify-Access-Token': SHOPIFY_TOKEN,
            'Content-Type': 'application/json'
          }
        });

        const metafields = await metafieldsResponse.json();
        const verifiedField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_verified');
        const analysisField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_analysis');
        const statusField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_status');

        if (verifiedField && analysisField && statusField) {
          console.log(`✓ Already analyzed (${verifiedField.value}): ${title} - ${statusField.value}`);
          const isCompliant = statusField.value === 'COMPLIANT';

          // Store in cache for faster future access
          analysisCache.set(cacheKey, {
            compliant: isCompliant,
            analysis: analysisField.value,
            timestamp: new Date(verifiedField.value).getTime()
          });

          return res.json({
            compliant: isCompliant,
            analysis: analysisField.value,
            reason: isCompliant ? 'No violations found' : 'Settlement violation detected',
            cached: false,
            fromShopify: true,
            verifiedDate: verifiedField.value
          });
        }
      } catch (metafieldError) {
        console.error(`   ⚠️ Failed to check metafields:`, metafieldError);
      }
    }

    console.log(`\n🔍 STRICT analysis: ${title}`);

    // Check title FIRST for prohibited keywords
    const titleLower = title.toLowerCase();
    const hasBanana = titleLower.includes('banana');
    const hasGrape = titleLower.includes('grape');
    const hasBird = titleLower.includes('bird');
    const hasButterfly = titleLower.includes('butterfly');

    const prompt = `First, describe what you see in this wallpaper image titled "${title}" in detail.

Then determine if it matches this settlement violation criteria:

**CRITERIA SET A (Pattern Features - need ALL 3):**
- Has repeating leaves with directional variation: YES/NO
- Has open space between elements: YES/NO
- Has 2+ colors: YES/NO

**CRITERIA SET B (Prohibited Elements - need ANY 1):**
- Shows banana FRUIT or banana PODS (NOT leaves - banana leaves are OK): YES/NO
- Shows grape fruit/clusters: YES/NO
- Shows birds: YES/NO
- Shows butterflies: YES/NO

If the first 3 are ALL YES and ANY of the last 4 is YES, it's a VIOLATION.

Please respond in this exact format:

DESCRIPTION: [Detailed description of what you see]

CRITERIA SET A:
- Repeating leaves with directional variation: YES/NO
- Open space between elements: YES/NO
- Multiple colors (2+): YES/NO [list the colors you see]

CRITERIA SET B:
- Banana FRUIT or banana PODS (NOT leaves - banana leaves are OK): YES/NO
- Grape FRUIT/clusters: YES/NO
- Birds: YES/NO
- Butterflies: YES/NO

Final answer: VIOLATION or COMPLIANT`;

    const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

    const response = await anthropic.messages.create({
      model: 'claude-3-opus-20240229',
      max_tokens: 1024,
      messages: [{
        role: 'user',
        content: [
          {
            type: 'image',
            source: {
              type: 'url',
              url: imageUrl
            }
          },
          {
            type: 'text',
            text: prompt
          }
        ]
      }]
    });

    const analysisText = response.content[0].type === 'text' ? response.content[0].text : '';
    const isViolation = analysisText.includes('VIOLATION') && !analysisText.includes('COMPLIANT');

    console.log(`   ${isViolation ? '🚨 VIOLATION' : '✅ COMPLIANT'}`);
    console.log(`   Analysis: ${analysisText.substring(0, 200)}...`);

    // Store in cache for future requests
    analysisCache.set(cacheKey, {
      compliant: !isViolation,
      analysis: analysisText,
      timestamp: Date.now()
    });

    // SAVE TO SHOPIFY METAFIELDS - Legal compliance tracking
    if (productId) {
      try {
        const verificationDate = new Date().toISOString();
        const metafieldsUpdate = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}/metafields.json`, {
          method: 'POST',
          headers: {
            'X-Shopify-Access-Token': SHOPIFY_TOKEN,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            metafield: {
              namespace: 'legal',
              key: 'settlement_verified',
              value: verificationDate,
              type: 'single_line_text_field'
            }
          })
        });

        const analysisUpdate = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}/metafields.json`, {
          method: 'POST',
          headers: {
            'X-Shopify-Access-Token': SHOPIFY_TOKEN,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            metafield: {
              namespace: 'legal',
              key: 'settlement_analysis',
              value: analysisText,
              type: 'multi_line_text_field'
            }
          })
        });

        const statusUpdate = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}/metafields.json`, {
          method: 'POST',
          headers: {
            'X-Shopify-Access-Token': SHOPIFY_TOKEN,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            metafield: {
              namespace: 'legal',
              key: 'settlement_status',
              value: isViolation ? 'VIOLATION' : 'COMPLIANT',
              type: 'single_line_text_field'
            }
          })
        });

        // Also update product notes field with the analysis
        try {
          const notesContent = `🔍 LEGAL COMPLIANCE ANALYSIS - ${new Date().toLocaleDateString()}

${isViolation ? '🚨 SETTLEMENT VIOLATION' : '✅ COMPLIANT'}
${analysisText}

Last verified: ${verificationDate}`;

          const productUpdateResponse = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}.json`, {
            method: 'PUT',
            headers: {
              'X-Shopify-Access-Token': SHOPIFY_TOKEN,
              'Content-Type': 'application/json'
            },
            body: JSON.stringify({
              product: {
                id: productId,
                body_html: notesContent // Using body_html as a notes field
              }
            })
          });

          console.log(`   ✅ Saved to Shopify metafields AND product notes for product ${productId}`);
        } catch (notesError) {
          console.error(`   ⚠️ Failed to update product notes:`, notesError);
          console.log(`   ✅ Saved to Shopify metafields for product ${productId}`);
        }
      } catch (metafieldError) {
        console.error(`   ⚠️ Failed to save metafields:`, metafieldError);
      }
    }

    // Add to violations list if it's a violation
    if (isViolation && productId) {
      const violation = {
        productId: productId,
        sku: req.body.sku || 'Unknown',
        title: title,
        url: `https://${SHOPIFY_STORE}/admin/products/${productId}`,
        analysis: analysisText,
        timestamp: new Date()
      };

      // Remove old entry for this product if exists
      const existingIndex = violationsList.findIndex(v => v.productId === productId);
      if (existingIndex >= 0) {
        violationsList.splice(existingIndex, 1);
      }

      violationsList.push(violation);
      console.log(`   🚨 Added to violations list: ${title}`);
    }

    res.json({
      compliant: !isViolation,
      analysis: analysisText,
      reason: isViolation ? 'Settlement violation detected' : 'No violations found',
      cached: false
    });

  } catch (error) {
    console.error('Image check error:', error);
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

// Set product to DRAFT endpoint - for legal compliance enforcement
app.post('/api/set-draft', requireAuth, async (req, res) => {
  try {
    const { productId } = req.body;

    if (!productId) {
      return res.status(400).json({ error: 'Product ID required' });
    }

    console.log(`⚠️  Setting product ${productId} to DRAFT (legal compliance)`);

    // Use GraphQL to update product status
    const mutation = `
      mutation productUpdate($input: ProductInput!) {
        productUpdate(input: $input) {
          product {
            id
            title
            status
          }
          userErrors {
            field
            message
          }
        }
      }
    `;

    const response = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/graphql.json`, {
      method: 'POST',
      headers: {
        'X-Shopify-Access-Token': SHOPIFY_TOKEN,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        query: mutation,
        variables: {
          input: {
            id: `gid://shopify/Product/${productId}`,
            status: 'DRAFT'
          }
        }
      })
    });

    if (!response.ok) {
      throw new Error(`Shopify GraphQL API error: ${response.status}`);
    }

    const result = await response.json();

    if (result.data?.productUpdate?.userErrors?.length > 0) {
      const errors = result.data.productUpdate.userErrors.map((e: any) => e.message).join(', ');
      throw new Error(`Shopify errors: ${errors}`);
    }

    console.log(`✅ Product ${productId} set to DRAFT via GraphQL`);
    console.log(`   Title: ${result.data?.productUpdate?.product?.title}`);

    res.json({
      success: true,
      message: 'Product set to draft',
      product: result.data?.productUpdate?.product
    });
  } catch (error) {
    console.error('Set draft error:', error);
    res.status(500).json({ error: error instanceof Error ? error.message : 'Unknown error' });
  }
});

// URL compliance checker endpoint
app.post('/api/check-url', requireAuth, async (req, res) => {
  let browser;

  try {
    const { url } = req.body;

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

    console.log(`\n🔍 Checking URL: ${url}`);

    // Scrape the page with Playwright
    browser = await chromium.launch({ headless: true });
    const page = await browser.newPage();

    // Try with domcontentloaded first (faster), fallback if needed
    try {
      await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });
    } catch (e) {
      console.log(`   ⚠️  domcontentloaded failed, trying load...`);
      try {
        await page.goto(url, { waitUntil: 'load', timeout: 60000 });
      } catch (e2) {
        await browser.close();
        return res.status(500).json({
          error: 'Page failed to load within timeout period. The page may be too slow or unavailable.',
        });
      }
    }

    // Wait for body to ensure content is loaded
    try {
      await page.waitForSelector('body', { timeout: 10000 });
    } catch (e) {
      await browser.close();
      return res.status(500).json({
        error: 'Page body could not be loaded.',
      });
    }

    // Extract text content
    const textContent = await page.evaluate(() => {
      return document.body.innerText;
    });

    // Get title and meta description
    const title = await page.title();
    const description = await page.evaluate(() => {
      const meta = document.querySelector('meta[name="description"]');
      return meta ? meta.getAttribute('content') : '';
    });

    await browser.close();

    console.log(`   ✅ Page scraped successfully`);
    console.log(`   📄 Title: ${title}`);

    // Analyze with Anthropic
    console.log(`   🤖 Analyzing with Claude...`);

    const prompt = `You are a legal compliance expert analyzing a product page for settlement agreement violations.

SETTLEMENT CRITERIA (MUST BE ENFORCED):

A product is PROHIBITED if it contains BOTH Part A AND Part B:

Part A - Prohibited Design (ALL three must be present):
1. Repeating patterns with directional variation amongst leaves/palm fronds
2. Open space between leaves
3. More than one ink color

Part B - Prohibited Specific Elements (ANY of these):
- Banana FRUIT or banana PODS (NOT leaves - banana leaves are OK)
- Grape fruit/clusters
- Birds
- Butterflies

Acceptable Tropical Design (at least ONE must be present):
1. Tree trunks
2. Clearly represented branches
3. Fruit or animal elements (EXCEPT prohibited ones)

VIOLATION RULE: BOTH Part A (all conditions) AND Part B (any element) must be present

---

PAGE TITLE: ${title}

PAGE DESCRIPTION: ${description}

PAGE CONTENT:
${textContent.slice(0, 5000)}

---

Analyze this product page and determine if it violates the settlement agreement.

Respond in this exact format:

STATUS: [PASS or VIOLATION]

ANALYSIS:
[Detailed explanation of your findings]`;

    const message = await anthropic.messages.create({
      model: 'claude-sonnet-4-5-20250929',
      max_tokens: 2000,
      messages: [
        {
          role: 'user',
          content: prompt,
        },
      ],
    });

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

    // Parse response
    const statusMatch = responseText.match(/STATUS:\s*(PASS|VIOLATION)/i);
    const analysisMatch = responseText.match(/ANALYSIS:\s*([\s\S]*)/i);

    const status = statusMatch ? statusMatch[1].toUpperCase() : 'UNKNOWN';
    const analysis = analysisMatch ? analysisMatch[1].trim() : responseText;

    console.log(`   📊 Result: ${status}`);

    return res.json({
      status,
      analysis,
      url,
      title,
    });
  } catch (error) {
    console.error('   ❌ Error checking URL:', error);

    // Make sure browser is closed
    if (browser) {
      try {
        await browser.close();
      } catch (e) {
        // Ignore close errors
      }
    }

    return res.status(500).json({
      error: error instanceof Error ? error.message : 'Unknown error',
    });
  }
});

// API: Chat endpoint for universal header
app.post('/api/chat', requireAuth, async (req, res) => {
  try {
    const { message } = req.body;

    const systemPrompt = `You are the Legal Team Agent AI assistant for Designer Wallcoverings. Your primary role is settlement compliance monitoring.

You help with:
- Settlement agreement compliance checking
- Product design analysis for tropical patterns
- Legal risk assessment
- Compliance violations review
- Settlement criteria interpretation

Be professional, precise, and compliance-focused. Provide clear guidance on settlement requirements.`;

    const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY || '' });

    const response = await anthropic.messages.create({
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 1024,
      system: systemPrompt,
      messages: [{ role: 'user', content: message }],
    });

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

    res.json({
      response: assistantMessage,
      success: true
    });
  } catch (error: any) {
    res.status(500).json({ error: error.message });
  }
});

// Track last check timestamp for newly active products
let lastCheckTimestamp = new Date(Date.now() - 5 * 60 * 1000); // Start 5 minutes ago

// Scheduled job to check for newly activated products (DRAFT → ACTIVE)
async function checkForNewlyActiveProducts() {
  try {
    const now = new Date();
    console.log(`\n🔍 [${now.toLocaleTimeString()}] Checking for newly activated products since ${lastCheckTimestamp.toLocaleTimeString()}...`);

    // GraphQL query to get products updated since last check
    const graphqlQuery = `
      query GetRecentlyUpdatedProducts {
        products(first: 100, query: "status:active updated_at:>='${lastCheckTimestamp.toISOString()}'", sortKey: UPDATED_AT, reverse: true) {
          edges {
            node {
              id
              legacyResourceId
              title
              status
              updatedAt
              tags
              featuredImage {
                url
              }
              variants(first: 1) {
                edges {
                  node {
                    sku
                  }
                }
              }
            }
          }
        }
      }
    `;

    const response = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/graphql.json`, {
      method: 'POST',
      headers: {
        'X-Shopify-Access-Token': SHOPIFY_TOKEN,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query: graphqlQuery })
    });

    if (!response.ok) {
      console.error(`   ❌ GraphQL API error: ${response.status}`);
      return;
    }

    const data: any = await response.json();

    if (data.errors) {
      console.error('   ❌ GraphQL errors:', data.errors);
      return;
    }

    const products = data.data?.products?.edges || [];

    if (products.length === 0) {
      console.log(`   ✓ No newly activated products found`);
      lastCheckTimestamp = now;
      return;
    }

    console.log(`   📦 Found ${products.length} recently updated active products`);

    // Check each product for compliance
    for (const edge of products) {
      const product = edge.node;
      const productId = product.legacyResourceId;
      const title = product.title;
      const imageUrl = product.featuredImage?.url;
      const sku = product.variants?.edges?.[0]?.node?.sku || 'Unknown';

      console.log(`\n   🔬 Reviewing: ${title} (ID: ${productId})`);

      // Check if already analyzed (metafields)
      try {
        const metafieldsResponse = await fetch(`https://${SHOPIFY_STORE}/admin/api/${API_VERSION}/products/${productId}/metafields.json`, {
          headers: {
            'X-Shopify-Access-Token': SHOPIFY_TOKEN,
            'Content-Type': 'application/json'
          }
        });

        const metafields = await metafieldsResponse.json();
        const statusField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_status');
        const analysisField = metafields.metafields?.find((m: any) => m.namespace === 'legal' && m.key === 'settlement_analysis');

        if (statusField && analysisField) {
          console.log(`      ✓ Already analyzed: ${statusField.value} (NO API CALL)`);

          // If violation, escalate since it was just activated
          if (statusField.value === 'VIOLATION') {
            console.log(`      🚨 VIOLATION DETECTED - Escalating to needs-attention`);

            await escalateViolationToNeedsAttention({
              title,
              productId,
              sku,
              reasoning: analysisField.value,
              productUrl: `https://admin.shopify.com/store/${SHOPIFY_STORE.replace('.myshopify.com', '')}/products/${productId}`
            });
          }
          continue;
        }
      } catch (metafieldError) {
        console.log(`      ⚠️ No existing analysis - will analyze`);
      }

      // If not analyzed and has image, analyze it
      if (imageUrl) {
        console.log(`      🔬 First-time analysis (will be saved for future)`);

        try {
          const checkResponse = await fetch(`http://localhost:${PORT}/api/check-image`, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Cookie': `${SSO_TOKEN_NAME}=${SSO_TOKEN_VALUE}`
            },
            body: JSON.stringify({
              imageUrl,
              title,
              tags: product.tags || '',
              productId,
              sku
            })
          });

          const result = await checkResponse.json();

          if (!result.compliant) {
            console.log(`      🚨 NEW VIOLATION DETECTED - Escalating`);

            await escalateViolationToNeedsAttention({
              title,
              productId,
              sku,
              reasoning: result.analysis,
              productUrl: `https://admin.shopify.com/store/${SHOPIFY_STORE.replace('.myshopify.com', '')}/products/${productId}`
            });

            stats.violations++;
          } else {
            console.log(`      ✅ Product is compliant`);
            stats.compliant++;
          }
        } catch (error) {
          console.error(`      ❌ Error analyzing product: ${error}`);
        }
      } else {
        console.log(`      ⚠️ No image - skipping analysis`);
      }
    }

    lastCheckTimestamp = now;
    console.log(`\n   ✓ Check complete at ${now.toLocaleTimeString()}`);
  } catch (error) {
    console.error('Error checking for newly active products:', error);
  }
}

// Start server
app.listen(PORT, () => {
  console.log('');
  console.log('⚖️  DW Legal Team - Settlement Compliance Monitor');
  console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
  console.log('🚨 PRIORITY #1: SETTLEMENT AGREEMENT COMPLIANCE');
  console.log('');
  console.log(`🌍 Access at: http://45.61.58.125:${PORT}`);
  console.log(`🏠 Local: http://localhost:${PORT}`);
  console.log('');
  console.log('📋 Settlement Criteria Loaded');
  console.log('✓ Part A: Prohibited Design Pattern');
  console.log('✓ Part B: Prohibited Specific Elements');
  console.log('✓ Acceptable Elements Defined');
  console.log('');
  console.log('🔍 Monitoring active...');
  console.log('');
  console.log('⏰ DRAFT→ACTIVE Monitoring: Every 2 minutes');
  console.log('   Checking for newly activated products via GraphQL polling');
  console.log('');

  // Run check every 2 minutes for newly activated products
  setInterval(checkForNewlyActiveProducts, 2 * 60 * 1000);

  // Run initial check after 10 seconds
  setTimeout(checkForNewlyActiveProducts, 10000);
});