// server/index.ts
import express2 from "express";
import { runMigrations } from "stripe-replit-sync";

// server/routes.ts
import { createServer } from "http";

// server/storage.ts
var MemStorage = class {
  contactSubmissions;
  newsletterSubscriptions;
  caseStudyDownloads;
  constructor() {
    this.contactSubmissions = /* @__PURE__ */ new Map();
    this.newsletterSubscriptions = /* @__PURE__ */ new Map();
    this.caseStudyDownloads = /* @__PURE__ */ new Map();
  }
  async createContactSubmission(submission) {
    const id = crypto.randomUUID();
    const contactSubmission = {
      ...submission,
      id,
      phone: submission.phone || null,
      newsletter: submission.newsletter || false,
      linkedinProfile: submission.linkedinProfile || null,
      createdAt: /* @__PURE__ */ new Date()
    };
    this.contactSubmissions.set(id, contactSubmission);
    return contactSubmission;
  }
  async createNewsletterSubscription(subscription) {
    const id = crypto.randomUUID();
    const newsletterSubscription = {
      ...subscription,
      id,
      isActive: true,
      createdAt: /* @__PURE__ */ new Date()
    };
    this.newsletterSubscriptions.set(id, newsletterSubscription);
    return newsletterSubscription;
  }
  async getNewsletterSubscriptionByEmail(email) {
    return Array.from(this.newsletterSubscriptions.values()).find(
      (subscription) => subscription.email === email
    );
  }
  async createCaseStudyDownload(download) {
    const id = crypto.randomUUID();
    const caseStudyDownload = {
      ...download,
      id,
      createdAt: /* @__PURE__ */ new Date()
    };
    this.caseStudyDownloads.set(id, caseStudyDownload);
    return caseStudyDownload;
  }
};
var storage = new MemStorage();

// shared/schema.ts
import { sql } from "drizzle-orm";
import { pgTable, text, timestamp, varchar, boolean } from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
var contactSubmissions = pgTable("contact_submissions", {
  id: text("id").primaryKey().default(sql`gen_random_uuid()`),
  firstName: varchar("first_name", { length: 255 }).notNull(),
  lastName: varchar("last_name", { length: 255 }).notNull(),
  email: varchar("email", { length: 255 }).notNull(),
  company: varchar("company", { length: 255 }).notNull(),
  phone: varchar("phone", { length: 50 }),
  projectType: varchar("project_type", { length: 100 }).notNull(),
  budget: varchar("budget", { length: 50 }).notNull(),
  timeline: varchar("timeline", { length: 50 }).notNull(),
  message: text("message").notNull(),
  newsletter: boolean("newsletter").default(false),
  linkedinProfile: varchar("linkedin_profile", { length: 255 }),
  createdAt: timestamp("created_at").defaultNow()
});
var newsletterSubscriptions = pgTable("newsletter_subscriptions", {
  id: text("id").primaryKey().default(sql`gen_random_uuid()`),
  email: varchar("email", { length: 255 }).notNull().unique(),
  firstName: varchar("first_name", { length: 255 }).notNull(),
  isActive: boolean("is_active").default(true),
  createdAt: timestamp("created_at").defaultNow()
});
var caseStudyDownloads = pgTable("case_study_downloads", {
  id: text("id").primaryKey().default(sql`gen_random_uuid()`),
  email: varchar("email", { length: 255 }).notNull(),
  firstName: varchar("first_name", { length: 255 }).notNull(),
  company: varchar("company", { length: 255 }).notNull(),
  caseStudyId: varchar("case_study_id", { length: 100 }).notNull(),
  createdAt: timestamp("created_at").defaultNow()
});
var insertContactSubmissionSchema = createInsertSchema(contactSubmissions).omit({
  id: true,
  createdAt: true
});
var insertNewsletterSubscriptionSchema = createInsertSchema(newsletterSubscriptions).omit({
  id: true,
  isActive: true,
  createdAt: true
});
var insertCaseStudyDownloadSchema = createInsertSchema(caseStudyDownloads).omit({
  id: true,
  createdAt: true
});

// server/airopsClient.ts
function getCredentials() {
  const apiKey = process.env.AIROPS_API_KEY;
  const workspaceId = process.env.AIROPS_WORKSPACE_ID;
  if (!apiKey || !workspaceId) {
    throw new Error("AirOps credentials not configured. Please set AIROPS_API_KEY and AIROPS_WORKSPACE_ID.");
  }
  return { apiKey, workspaceId };
}
async function executeAirOpsWorkflow(payload) {
  const { apiKey } = getCredentials();
  const url = `https://app.airops.com/public_api/airops_apps/${payload.appId}/execute`;
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        inputs: payload.inputs,
        version: payload.version
      })
    });
    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`AirOps API error (${response.status}): ${errorText}`);
    }
    const result = await response.json();
    return {
      success: true,
      executionId: result.id,
      status: result.status,
      output: result.output,
      executedAt: (/* @__PURE__ */ new Date()).toISOString()
    };
  } catch (error) {
    console.error("AirOps workflow execution error:", error);
    throw error;
  }
}
async function uploadToAirOpsKnowledgeBase(memoryStoreId, document) {
  const { apiKey } = getCredentials();
  const url = `https://api.airops.com/public_api/vector_stores/${memoryStoreId}/vector_store_documents`;
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Authorization": `Bearer ${apiKey}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(document)
    });
    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`AirOps Knowledge Base error (${response.status}): ${errorText}`);
    }
    const result = await response.json();
    return {
      success: true,
      documentId: result.id,
      name: result.name,
      status: result.status,
      uploadedAt: (/* @__PURE__ */ new Date()).toISOString()
    };
  } catch (error) {
    console.error("AirOps knowledge base upload error:", error);
    throw error;
  }
}

// server/routes.ts
async function registerRoutes(app2) {
  app2.post("/api/contact", async (req, res) => {
    try {
      const validatedData = insertContactSubmissionSchema.parse(req.body);
      const submission = await storage.createContactSubmission(validatedData);
      console.log("New contact submission:", submission);
      res.status(201).json({
        message: "Contact form submitted successfully",
        id: submission.id
      });
    } catch (error) {
      console.error("Contact form error:", error);
      res.status(400).json({
        message: "Invalid form data",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  app2.post("/api/newsletter", async (req, res) => {
    try {
      const validatedData = insertNewsletterSubscriptionSchema.parse(req.body);
      const existing = await storage.getNewsletterSubscriptionByEmail(validatedData.email);
      if (existing) {
        return res.status(200).json({
          message: "Email already subscribed",
          id: existing.id
        });
      }
      const subscription = await storage.createNewsletterSubscription(validatedData);
      console.log("New newsletter subscription:", subscription);
      res.status(201).json({
        message: "Successfully subscribed to newsletter",
        id: subscription.id
      });
    } catch (error) {
      console.error("Newsletter subscription error:", error);
      res.status(400).json({
        message: "Invalid subscription data",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  app2.post("/api/case-study-download", async (req, res) => {
    try {
      const validatedData = insertCaseStudyDownloadSchema.parse(req.body);
      const download = await storage.createCaseStudyDownload(validatedData);
      console.log("New case study download:", download);
      res.status(201).json({
        message: "Case study download initiated",
        id: download.id,
        downloadUrl: `/downloads/${validatedData.caseStudyId}.pdf`
      });
    } catch (error) {
      console.error("Case study download error:", error);
      res.status(400).json({
        message: "Invalid download request",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  app2.post("/api/airops/execute", async (req, res) => {
    try {
      const { appId, version, inputs } = req.body;
      if (!appId) {
        return res.status(400).json({
          message: "appId is required"
        });
      }
      const payload = {
        appId: parseInt(appId, 10),
        version: version ? parseInt(version, 10) : void 0,
        inputs: inputs || {}
      };
      const result = await executeAirOpsWorkflow(payload);
      res.status(200).json({
        message: "Workflow executed successfully",
        ...result
      });
    } catch (error) {
      console.error("AirOps workflow error:", error);
      res.status(500).json({
        message: "Failed to execute workflow",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  app2.post("/api/airops/upload", async (req, res) => {
    try {
      const { title, content, contentType, metadata, appId } = req.body;
      if (!title || !content || !contentType) {
        return res.status(400).json({
          message: "title, content, and contentType are required"
        });
      }
      if (appId) {
        const result = await executeAirOpsWorkflow({
          appId: parseInt(appId, 10),
          inputs: { title, content, contentType, metadata }
        });
        res.status(200).json({
          message: "Content uploaded and processed via AirOps workflow",
          ...result
        });
      } else {
        res.status(200).json({
          message: "Content received successfully",
          title,
          contentType,
          receivedAt: (/* @__PURE__ */ new Date()).toISOString()
        });
      }
    } catch (error) {
      console.error("AirOps upload error:", error);
      res.status(500).json({
        message: "Failed to upload content",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  app2.get("/api/airops/status", async (req, res) => {
    try {
      const hasApiKey = !!process.env.AIROPS_API_KEY;
      const hasWorkspaceId = !!process.env.AIROPS_WORKSPACE_ID;
      res.status(200).json({
        configured: hasApiKey && hasWorkspaceId,
        apiKeySet: hasApiKey,
        workspaceIdSet: hasWorkspaceId
      });
    } catch (error) {
      res.status(500).json({
        message: "Failed to check AirOps status",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  app2.post("/api/airops/knowledge-base", async (req, res) => {
    try {
      const { memoryStoreId, text: text2, name, metadata } = req.body;
      if (!memoryStoreId || !text2 || !name) {
        return res.status(400).json({
          message: "memoryStoreId, text, and name are required"
        });
      }
      const result = await uploadToAirOpsKnowledgeBase(memoryStoreId, {
        text: text2,
        name,
        metadata
      });
      res.status(200).json({
        message: "Document uploaded to knowledge base",
        ...result
      });
    } catch (error) {
      console.error("AirOps knowledge base error:", error);
      res.status(500).json({
        message: "Failed to upload to knowledge base",
        error: error instanceof Error ? error.message : "Unknown error"
      });
    }
  });
  const httpServer = createServer(app2);
  return httpServer;
}

// server/vite.ts
import express from "express";
import fs from "fs";
import path2 from "path";
import { createServer as createViteServer, createLogger } from "vite";

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";
import runtimeErrorOverlay from "@replit/vite-plugin-runtime-error-modal";
var vite_config_default = defineConfig({
  plugins: [
    react(),
    runtimeErrorOverlay(),
    ...process.env.NODE_ENV !== "production" && process.env.REPL_ID !== void 0 ? [
      await import("@replit/vite-plugin-cartographer").then(
        (m) => m.cartographer()
      )
    ] : []
  ],
  resolve: {
    alias: {
      "@": path.resolve(import.meta.dirname, "client", "src"),
      "@shared": path.resolve(import.meta.dirname, "shared"),
      "@assets": path.resolve(import.meta.dirname, "attached_assets")
    }
  },
  root: path.resolve(import.meta.dirname, "client"),
  build: {
    outDir: path.resolve(import.meta.dirname, "dist/public"),
    emptyOutDir: true
  }
});

// server/vite.ts
import { nanoid } from "nanoid";
var viteLogger = createLogger();
function log(message, source = "express") {
  const formattedTime = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", {
    hour: "numeric",
    minute: "2-digit",
    second: "2-digit",
    hour12: true
  });
  console.log(`${formattedTime} [${source}] ${message}`);
}
async function setupVite(app2, server) {
  const serverOptions = {
    middlewareMode: true,
    hmr: { server },
    allowedHosts: true
  };
  const vite = await createViteServer({
    ...vite_config_default,
    configFile: false,
    customLogger: {
      ...viteLogger,
      error: (msg, options) => {
        viteLogger.error(msg, options);
        process.exit(1);
      }
    },
    server: serverOptions,
    appType: "custom"
  });
  app2.use(vite.middlewares);
  app2.use("*", async (req, res, next) => {
    const url = req.originalUrl;
    try {
      const clientTemplate = path2.resolve(
        import.meta.dirname,
        "..",
        "client",
        "index.html"
      );
      let template = await fs.promises.readFile(clientTemplate, "utf-8");
      template = template.replace(
        `src="/src/main.tsx"`,
        `src="/src/main.tsx?v=${nanoid()}"`
      );
      const page = await vite.transformIndexHtml(url, template);
      res.status(200).set({ "Content-Type": "text/html" }).end(page);
    } catch (e) {
      vite.ssrFixStacktrace(e);
      next(e);
    }
  });
}
function serveStatic(app2) {
  const distPath = path2.resolve(import.meta.dirname, "public");
  if (!fs.existsSync(distPath)) {
    throw new Error(
      `Could not find the build directory: ${distPath}, make sure to build the client first`
    );
  }
  app2.use(express.static(distPath));
  app2.use("*", (_req, res) => {
    res.sendFile(path2.resolve(distPath, "index.html"));
  });
}

// server/stripeClient.ts
import Stripe from "stripe";
var connectionSettings;
async function getCredentials2() {
  const hostname = process.env.REPLIT_CONNECTORS_HOSTNAME;
  const xReplitToken = process.env.REPL_IDENTITY ? "repl " + process.env.REPL_IDENTITY : process.env.WEB_REPL_RENEWAL ? "depl " + process.env.WEB_REPL_RENEWAL : null;
  if (!xReplitToken) {
    throw new Error("X_REPLIT_TOKEN not found for repl/depl");
  }
  const connectorName = "stripe";
  const isProduction = process.env.REPLIT_DEPLOYMENT === "1";
  const targetEnvironment = isProduction ? "production" : "development";
  const url = new URL(`https://${hostname}/api/v2/connection`);
  url.searchParams.set("include_secrets", "true");
  url.searchParams.set("connector_names", connectorName);
  url.searchParams.set("environment", targetEnvironment);
  const response = await fetch(url.toString(), {
    headers: {
      "Accept": "application/json",
      "X_REPLIT_TOKEN": xReplitToken
    }
  });
  const data = await response.json();
  connectionSettings = data.items?.[0];
  if (!connectionSettings || (!connectionSettings.settings.publishable || !connectionSettings.settings.secret)) {
    throw new Error(`Stripe ${targetEnvironment} connection not found`);
  }
  return {
    publishableKey: connectionSettings.settings.publishable,
    secretKey: connectionSettings.settings.secret
  };
}
async function getStripeSecretKey() {
  const { secretKey } = await getCredentials2();
  return secretKey;
}
var stripeSync = null;
async function getStripeSync() {
  if (!stripeSync) {
    const { StripeSync } = await import("stripe-replit-sync");
    const secretKey = await getStripeSecretKey();
    stripeSync = new StripeSync({
      poolConfig: {
        connectionString: process.env.DATABASE_URL,
        max: 2
      },
      stripeSecretKey: secretKey
    });
  }
  return stripeSync;
}

// server/webhookHandlers.ts
var WebhookHandlers = class {
  static async processWebhook(payload, signature, uuid) {
    if (!Buffer.isBuffer(payload)) {
      throw new Error(
        "STRIPE WEBHOOK ERROR: Payload must be a Buffer. Received type: " + typeof payload + ". This usually means express.json() parsed the body before reaching this handler. FIX: Ensure webhook route is registered BEFORE app.use(express.json())."
      );
    }
    const sync = await getStripeSync();
    await sync.processWebhook(payload, signature, uuid);
  }
};

// server/index.ts
var app = express2();
async function initStripe() {
  const databaseUrl = process.env.DATABASE_URL;
  if (!databaseUrl) {
    console.log("DATABASE_URL not found, skipping Stripe initialization");
    return;
  }
  try {
    console.log("Initializing Stripe schema...");
    await runMigrations({ databaseUrl });
    console.log("Stripe schema ready");
    const stripeSync2 = await getStripeSync();
    console.log("Setting up managed webhook...");
    const webhookBaseUrl = `https://${process.env.REPLIT_DOMAINS?.split(",")[0]}`;
    const { webhook, uuid } = await stripeSync2.findOrCreateManagedWebhook(
      `${webhookBaseUrl}/api/stripe/webhook`,
      {
        enabled_events: ["*"],
        description: "Managed webhook for Stripe sync"
      }
    );
    console.log(`Webhook configured: ${webhook.url} (UUID: ${uuid})`);
    console.log("Syncing Stripe data...");
    stripeSync2.syncBackfill().then(() => {
      console.log("Stripe data synced");
    }).catch((err) => {
      console.error("Error syncing Stripe data:", err);
    });
  } catch (error) {
    console.error("Failed to initialize Stripe:", error);
  }
}
app.post(
  "/api/stripe/webhook/:uuid",
  express2.raw({ type: "application/json" }),
  async (req, res) => {
    const signature = req.headers["stripe-signature"];
    if (!signature) {
      return res.status(400).json({ error: "Missing stripe-signature" });
    }
    try {
      const sig = Array.isArray(signature) ? signature[0] : signature;
      if (!Buffer.isBuffer(req.body)) {
        console.error("STRIPE WEBHOOK ERROR: req.body is not a Buffer");
        return res.status(500).json({ error: "Webhook processing error" });
      }
      const { uuid } = req.params;
      await WebhookHandlers.processWebhook(req.body, sig, uuid);
      res.status(200).json({ received: true });
    } catch (error) {
      console.error("Webhook error:", error.message);
      res.status(400).json({ error: "Webhook processing error" });
    }
  }
);
app.use(express2.json());
app.use(express2.urlencoded({ extended: false }));
app.use((req, res, next) => {
  const start = Date.now();
  const path3 = req.path;
  let capturedJsonResponse = void 0;
  const originalResJson = res.json;
  res.json = function(bodyJson, ...args) {
    capturedJsonResponse = bodyJson;
    return originalResJson.apply(res, [bodyJson, ...args]);
  };
  res.on("finish", () => {
    const duration = Date.now() - start;
    if (path3.startsWith("/api")) {
      let logLine = `${req.method} ${path3} ${res.statusCode} in ${duration}ms`;
      if (capturedJsonResponse) {
        logLine += ` :: ${JSON.stringify(capturedJsonResponse)}`;
      }
      if (logLine.length > 80) {
        logLine = logLine.slice(0, 79) + "\u2026";
      }
      log(logLine);
    }
  });
  next();
});
(async () => {
  await initStripe();
  const server = await registerRoutes(app);
  app.use((err, _req, res, _next) => {
    const status = err.status || err.statusCode || 500;
    const message = err.message || "Internal Server Error";
    res.status(status).json({ message });
    throw err;
  });
  if (app.get("env") === "development") {
    await setupVite(app, server);
  } else {
    serveStatic(app);
  }
  const port = 5e3;
  server.listen({
    port,
    host: "0.0.0.0",
    reusePort: true
  }, () => {
    log(`serving on port ${port}`);
  });
})();
