import crypto from "crypto";
import http from "http";
import { mkdir, readFile, writeFile } from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";
import dotenv from "dotenv";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
dotenv.config({ path: path.join(__dirname, "..", ".env") });
const port = Number(process.env.PORT || 5000);
const dataDir = path.join(__dirname, "..", "data");
const quotesPath = path.join(dataDir, "quotes.json");
const dbPath = path.join(dataDir, "marketplace.json");
const mysqlSchemaPath = path.join(__dirname, "db", "mysql-schema.sql");
const jwtSecret = process.env.JWT_SECRET || "omosala-local-secret";
const rateLimitHits = new Map();

const integrations = {
  google: Boolean(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET),
  facebook: Boolean(process.env.FACEBOOK_APP_ID && process.env.FACEBOOK_APP_SECRET),
  apple: Boolean(process.env.APPLE_CLIENT_ID && process.env.APPLE_TEAM_ID && process.env.APPLE_KEY_ID),
  mysql: Boolean(process.env.MYSQL_DATABASE_URL || process.env.MYSQL_HOST),
  whatsapp: Boolean(process.env.WHATSAPP_ACCESS_TOKEN && process.env.WHATSAPP_PHONE_NUMBER_ID),
  paystack: Boolean(process.env.PAYSTACK_SECRET_KEY),
  flutterwave: Boolean(process.env.FLUTTERWAVE_SECRET_KEY),
  cloudinary: Boolean(process.env.CLOUDINARY_CLOUD_NAME && process.env.CLOUDINARY_API_KEY && process.env.CLOUDINARY_API_SECRET),
  email: Boolean(process.env.SMTP_HOST && process.env.SMTP_USER)
};

const defaultDesignPrices = { regular: 5000, standard: 10000, premium: 15000 };
const defaultProducts = [
  { id: "mach-001", name: "Digital Production Printer - A3 Color Press", category: "Printing Machines", vendor: "OMOSALA PRINT Machines", price: 4850000, stock: 6, status: "Approved", sku: "OMS-MACH-001", requiresDesign: false, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "mach-002", name: "Large Format Eco-Solvent Printer", category: "Printing Machines", vendor: "OMOSALA PRINT Machines", price: 7200000, stock: 4, status: "Approved", sku: "OMS-MACH-002", requiresDesign: false, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "bc-001", name: "Premium Business Cards - Matte Finish", category: "Business Printing", vendor: "OMOSALA PRINT Studio", price: 18500, stock: 420, status: "Approved", sku: "OMS-BC-001", requiresDesign: true, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "fly-005", name: "A5 Flyers - Full Color", category: "Business Printing", vendor: "OMOSALA PRINT Studio", price: 42000, stock: 5000, status: "Approved", sku: "OMS-FLY-005", requiresDesign: true, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "lf-006", name: "Large Format Flex Banner Print", category: "Large Format Printing", vendor: "OMOSALA PRINT Studio", price: 1800, stock: 5000, status: "Approved", sku: "OMS-LF-006", requiresDesign: true, pricingUnit: "per_sqft", designPrices: defaultDesignPrices },
  { id: "mat-011", name: "Glossy Photo Paper Pack", category: "Printing Materials", vendor: "OMOSALA PRINT Supplies", price: 18500, stock: 260, status: "Approved", sku: "OMS-MAT-011", requiresDesign: false, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "mat-012", name: "Eco-Solvent Ink Set", category: "Printing Materials", vendor: "OMOSALA PRINT Supplies", price: 145000, stock: 80, status: "Approved", sku: "OMS-MAT-012", requiresDesign: false, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "jot-008", name: "Custom Branded Jotters - Corporate Pack", category: "Jotters", vendor: "OMOSALA PRINT Studio", price: 78000, stock: 1200, status: "Approved", sku: "OMS-JOT-008", requiresDesign: true, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "sou-009", name: "Party Souvenirs - Custom Mug & Gift Set", category: "Party Souvenirs", vendor: "OMOSALA PRINT Souvenirs", price: 125000, stock: 650, status: "Approved", sku: "OMS-SOU-009", requiresDesign: true, pricingUnit: "unit", designPrices: defaultDesignPrices },
  { id: "int-010", name: "Interior Wall Graphics & Wallpaper Prints", category: "Interior Decoration", vendor: "OMOSALA Interior Prints", price: 185000, stock: 90, status: "Approved", sku: "OMS-INT-010", requiresDesign: true, pricingUnit: "per_sqft", designPrices: defaultDesignPrices }
];

let quotes = await loadJson(quotesPath, []);
let db = await loadJson(dbPath, {
  users: [
    {
      id: "usr-admin",
      name: "OMOSALA Super Admin",
      email: "admin@omosalaprints.ng",
      phone: "08030572418",
      role: "super_admin",
      passwordHash: hashPassword("admin123"),
      createdAt: new Date().toISOString()
    }
  ],
  products: defaultProducts,
  orders: [],
  uploads: [],
  payments: [],
  notifications: [],
  settings: {
    whatsappSupportNumber: "2348030572418",
    whatsappSupportMessage: "Hello OMOSALA PRINTS, I need help with an order.",
    oauth: { googleClientId: "", facebookAppId: "", appleClientId: "" },
    designPrices: defaultDesignPrices,
    orderStatuses: ["Pending Payment", "Payment Confirmed", "Designing", "Printing", "Ready for Delivery", "Delivered"]
  },
  bankAccounts: [
    { id: "bank-moniepoint", bankName: "Moniepoint", accountNumber: "5060390464", accountName: "OMOSALA PRINTS AND TECHNOLOGY", active: true }
  ],
  deliveryZones: [
    { id: "zone-ado-ekiti", name: "Ado Ekiti", fee: 2500, eta: "Same day / 24 hours" },
    { id: "zone-ikere-ekiti", name: "Ikere Ekiti", fee: 2000, eta: "Same day / 24 hours" },
    { id: "zone-lagos-main", name: "Lagos Mainland", fee: 3500, eta: "24-48 hours" },
    { id: "zone-lagos-island", name: "Lagos Island", fee: 5000, eta: "24-48 hours" },
    { id: "zone-ogun", name: "Ogun State", fee: 7000, eta: "2-3 days" },
    { id: "zone-nationwide", name: "Nationwide Delivery", fee: 12000, eta: "3-7 days" }
  ],
  riders: [
    { id: "rider-001", name: "OMOSALA Dispatch 1", phone: "08030572418", status: "Available" },
    { id: "rider-002", name: "OMOSALA Dispatch 2", phone: "08030572418", status: "Available" }
  ],
  addresses: [],
  wishlists: [],
  tickets: [],
  coupons: [],
  banners: [],
  vendors: [
    { id: "vendor-main", name: "OMOSALA PRINT Studio", status: "Approved", payoutStatus: "Active", sales: 0 },
    { id: "vendor-machines", name: "OMOSALA PRINT Machines", status: "Approved", payoutStatus: "Active", sales: 0 }
  ],
  refunds: [],
  auditLogs: []
});
db.products ||= defaultProducts;
for (const product of defaultProducts) {
  if (!db.products.some((item) => item.id === product.id)) db.products.push(product);
}
db.products = db.products.map((product) => ({
  ...product,
  requiresDesign: product.requiresDesign ?? !["Printing Machines", "Printing Materials"].includes(product.category),
  pricingUnit: product.pricingUnit || (["Large Format Printing", "Interior Decoration"].includes(product.category) ? "per_sqft" : "unit"),
  designPrices: {
    ...defaultDesignPrices,
    ...(product.designPrices || {}),
    regular: product.designPrices?.regular ?? product.designPrices?.basic ?? defaultDesignPrices.regular
  }
}));
db.orders ||= [];
db.uploads ||= [];
db.payments ||= [];
db.notifications ||= [];
db.settings ||= {
  whatsappSupportNumber: "2348030572418",
  whatsappSupportMessage: "Hello OMOSALA PRINTS, I need help with an order.",
  oauth: { googleClientId: "", facebookAppId: "", appleClientId: "" },
  designPrices: defaultDesignPrices,
  orderStatuses: ["Pending Payment", "Payment Confirmed", "Designing", "Printing", "Ready for Delivery", "Delivered"]
};
db.settings.designPrices ||= defaultDesignPrices;
if (db.settings.designPrices.basic && !db.settings.designPrices.regular) db.settings.designPrices.regular = db.settings.designPrices.basic;
db.settings.orderStatuses ||= ["Pending Payment", "Payment Confirmed", "Designing", "Printing", "Ready for Delivery", "Delivered"];
db.bankAccounts ||= [
  { id: "bank-moniepoint", bankName: "Moniepoint", accountNumber: "5060390464", accountName: "OMOSALA PRINTS AND TECHNOLOGY", active: true }
];
db.deliveryZones ||= [
  { id: "zone-ado-ekiti", name: "Ado Ekiti", fee: 2500, eta: "Same day / 24 hours" },
  { id: "zone-ikere-ekiti", name: "Ikere Ekiti", fee: 2000, eta: "Same day / 24 hours" },
  { id: "zone-lagos-main", name: "Lagos Mainland", fee: 3500, eta: "24-48 hours" },
  { id: "zone-lagos-island", name: "Lagos Island", fee: 5000, eta: "24-48 hours" },
  { id: "zone-ogun", name: "Ogun State", fee: 7000, eta: "2-3 days" },
  { id: "zone-nationwide", name: "Nationwide Delivery", fee: 12000, eta: "3-7 days" }
];
ensureDeliveryZone({ id: "zone-ado-ekiti", name: "Ado Ekiti", fee: 2500, eta: "Same day / 24 hours" });
ensureDeliveryZone({ id: "zone-ikere-ekiti", name: "Ikere Ekiti", fee: 2000, eta: "Same day / 24 hours" });
db.riders ||= [
  { id: "rider-001", name: "OMOSALA Dispatch 1", phone: "08030572418", status: "Available" },
  { id: "rider-002", name: "OMOSALA Dispatch 2", phone: "08030572418", status: "Available" }
];
db.addresses ||= [];
db.wishlists ||= [];
db.tickets ||= [];
db.coupons ||= [];
db.banners ||= [];
db.vendors ||= [
  { id: "vendor-main", name: "OMOSALA PRINT Studio", status: "Approved", payoutStatus: "Active", sales: 0 },
  { id: "vendor-machines", name: "OMOSALA PRINT Machines", status: "Approved", payoutStatus: "Active", sales: 0 }
];
db.refunds ||= [];
db.auditLogs ||= [];
await saveDb();

async function loadJson(filePath, fallback) {
  try {
    await mkdir(dataDir, { recursive: true });
    return JSON.parse(await readFile(filePath, "utf8"));
  } catch {
    return fallback;
  }
}

async function saveJson(filePath, value) {
  await mkdir(dataDir, { recursive: true });
  await writeFile(filePath, JSON.stringify(value, null, 2));
}

async function saveQuotes() {
  await saveJson(quotesPath, quotes);
}

async function saveDb() {
  await saveJson(dbPath, db);
}

function hashPassword(password) {
  return crypto.createHash("sha256").update(`${password}:${jwtSecret}`).digest("hex");
}

function signToken(user) {
  const payload = Buffer.from(JSON.stringify({ id: user.id, role: user.role, exp: Date.now() + 1000 * 60 * 60 * 24 })).toString("base64url");
  const signature = crypto.createHmac("sha256", jwtSecret).update(payload).digest("base64url");
  return `${payload}.${signature}`;
}

function verifyToken(request) {
  const token = (request.headers.authorization || "").replace("Bearer ", "");
  if (!token.includes(".")) return null;
  const [payload, signature] = token.split(".");
  const expected = crypto.createHmac("sha256", jwtSecret).update(payload).digest("base64url");
  if (signature !== expected) return null;
  const parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
  if (parsed.exp < Date.now()) return null;
  return db.users.find((user) => user.id === parsed.id) || null;
}

function publicUser(user) {
  if (!user) return null;
  const { passwordHash, ...safeUser } = user;
  return safeUser;
}

function send(response, status, body) {
  const origin = response.req?.headers?.origin || "*";
  response.writeHead(status, {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": origin,
    "Access-Control-Allow-Methods": "GET,POST,PATCH,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Paystack-Signature, Verif-Hash",
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "DENY",
    "Referrer-Policy": "strict-origin-when-cross-origin"
  });
  response.end(JSON.stringify(body));
}

function isRateLimited(request) {
  const key = request.socket.remoteAddress || "local";
  const now = Date.now();
  const windowMs = 60 * 1000;
  const bucket = (rateLimitHits.get(key) || []).filter((time) => now - time < windowMs);
  bucket.push(now);
  rateLimitHits.set(key, bucket);
  return bucket.length > 180;
}

function requireAdmin(request, response) {
  const user = verifyToken(request);
  if (!user || !["super_admin", "admin", "seller"].includes(user.role)) {
    send(response, 401, { message: "Admin login required" });
    return null;
  }
  return user;
}

function requireUser(request, response) {
  const user = verifyToken(request);
  if (!user) {
    send(response, 401, { message: "Login required" });
    return null;
  }
  return user;
}

function readBody(request) {
  return new Promise((resolve, reject) => {
    let data = "";
    request.on("data", (chunk) => {
      data += chunk;
      if (data.length > 8_000_000) reject(new Error("Request is too large"));
    });
    request.on("end", () => {
      try {
        resolve(data ? JSON.parse(data) : {});
      } catch (error) {
        reject(error);
      }
    });
    request.on("error", reject);
  });
}

function createId(prefix) {
  return `${prefix}-${Date.now()}-${Math.random().toString(16).slice(2, 8)}`;
}

function createOrderNumber() {
  return `OMS-${String(Date.now()).slice(-6)}`;
}

function ensureDeliveryZone(zone) {
  if (!db.deliveryZones.some((item) => item.name.toLowerCase() === zone.name.toLowerCase())) {
    db.deliveryZones.unshift(zone);
  }
}

function isPayOnDeliveryLocation(address = "", deliveryZone = "") {
  const location = `${address} ${deliveryZone}`.toLowerCase();
  return location.includes("ado ekiti") || location.includes("ikere ekiti");
}

function successfulTransactionsForPhone(phone = "") {
  const normalized = String(phone).replace(/\D/g, "");
  return db.orders.filter((order) => {
    const samePhone = String(order.phone || "").replace(/\D/g, "") === normalized;
    const paid = ["Paid", "Verified"].includes(order.paymentStatus);
    const delivered = ["Delivered", "Completed"].includes(order.status) || ["Delivered", "Completed"].includes(order.deliveryStatus);
    return samePhone && paid && delivered;
  }).length;
}

function payOnDeliveryEligibility({ phone = "", address = "", deliveryZone = "" }) {
  const successfulTransactions = successfulTransactionsForPhone(phone);
  if (!isPayOnDeliveryLocation(address, deliveryZone)) {
    return {
      eligible: false,
      successfulTransactions,
      reason: "Pay on delivery is not yet available in your location. It is available only in Ado Ekiti and Ikere Ekiti."
    };
  }

  if (successfulTransactions < 5) {
    return {
      eligible: false,
      successfulTransactions,
      reason: "Pay on delivery is not available yet. You need 5 or more successful delivered transactions to qualify."
    };
  }

  return { eligible: true, successfulTransactions, reason: "Qualified for pay on delivery." };
}

function whatsappLink(phone, message) {
  const target = normalizeWhatsappPhone(phone);
  return `https://wa.me/${target}?text=${encodeURIComponent(message)}`;
}

function normalizeWhatsappPhone(phone) {
  return String(phone || process.env.WHATSAPP_BUSINESS_NUMBER || "08030572418").replace(/\D/g, "").replace(/^0/, "234");
}

async function sendWhatsappMessage(phone, message) {
  if (!integrations.whatsapp) {
    return { sent: false, status: "manual-link", reason: "WhatsApp API keys are not configured" };
  }

  const payload = {
    messaging_product: "whatsapp",
    recipient_type: "individual",
    to: normalizeWhatsappPhone(phone),
    type: "text",
    text: { preview_url: false, body: message }
  };

  try {
    const metaResponse = await fetch(`https://graph.facebook.com/v20.0/${process.env.WHATSAPP_PHONE_NUMBER_ID}/messages`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.WHATSAPP_ACCESS_TOKEN}`,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(payload)
    });
    const result = await metaResponse.json().catch(() => ({}));
    return {
      sent: metaResponse.ok,
      status: metaResponse.ok ? "sent" : "failed",
      provider: "meta-whatsapp-cloud-api",
      result
    };
  } catch (error) {
    return { sent: false, status: "failed", provider: "meta-whatsapp-cloud-api", reason: error.message };
  }
}

function setupStatus(name) {
  return integrations[name] ? "live-ready" : "demo - add API keys";
}

function buildSocialAuthUrl(provider) {
  const base = process.env.PUBLIC_APP_URL || "http://localhost:3001";
  const callback = encodeURIComponent(`${base}/api/auth/${provider}/callback`);
  if (provider === "google" && integrations.google) {
    return `https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.GOOGLE_CLIENT_ID}&redirect_uri=${callback}&response_type=code&scope=openid%20email%20profile`;
  }
  if (provider === "facebook" && integrations.facebook) {
    return `https://www.facebook.com/v20.0/dialog/oauth?client_id=${process.env.FACEBOOK_APP_ID}&redirect_uri=${callback}&scope=email,public_profile`;
  }
  if (provider === "apple" && integrations.apple) {
    return `https://appleid.apple.com/auth/authorize?client_id=${process.env.APPLE_CLIENT_ID}&redirect_uri=${callback}&response_type=code&scope=name%20email`;
  }
  return "";
}

function getSummary() {
  const revenue = db.orders.reduce((sum, order) => sum + Number(order.total || 0), 0);
  return {
    revenue,
    products: db.products.length,
    orders: db.orders.length,
    quotes: quotes.length,
    uploads: db.uploads.length,
    payments: db.payments.length,
    pendingOrders: db.orders.filter((order) => ["Pending", "Processing", "Packed"].includes(order.status)).length
  };
}

function addAudit(action, userId = "system") {
  db.auditLogs.unshift({ id: createId("audit"), action, userId, createdAt: new Date().toISOString() });
  db.auditLogs = db.auditLogs.slice(0, 300);
}

const server = http.createServer(async (request, response) => {
  try {
    const url = new URL(request.url || "/", `http://${request.headers.host}`);

    if (request.method === "OPTIONS") return send(response, 200, { ok: true });
    if (isRateLimited(request)) return send(response, 429, { message: "Too many requests. Please wait a minute." });
    if (url.pathname === "/api/health") return send(response, 200, { status: "ok", service: "omosala-simple-api", database: integrations.mysql ? "mysql-ready" : "local-json", mysqlReady: integrations.mysql });
    if (url.pathname === "/api/database/status") return send(response, 200, { selected: "mysql", mode: integrations.mysql ? "mysql configured" : "local-json fallback", mysqlReady: integrations.mysql, needsDriver: "mysql2 package required for live MySQL runtime" });
    if (url.pathname === "/api/database/mysql-schema" && request.method === "GET") {
      const schema = await readFile(mysqlSchemaPath, "utf8");
      return send(response, 200, { database: "omosala_marketplace", schema });
    }
    if (url.pathname === "/api/integrations/status") {
      return send(response, 200, {
        google: setupStatus("google"),
        facebook: setupStatus("facebook"),
        apple: setupStatus("apple"),
        mysql: setupStatus("mysql"),
        whatsapp: setupStatus("whatsapp"),
        paystack: setupStatus("paystack"),
        flutterwave: setupStatus("flutterwave"),
        cloudinary: setupStatus("cloudinary"),
        email: setupStatus("email")
      });
    }

    if (url.pathname === "/api/settings/public" && request.method === "GET") {
      return send(response, 200, {
        whatsappSupportNumber: db.settings.whatsappSupportNumber || "2348030572418",
        whatsappSupportMessage: db.settings.whatsappSupportMessage || "Hello OMOSALA PRINTS, I need help with an order.",
        bankAccounts: db.bankAccounts.filter((account) => account.active !== false),
        designPrices: db.settings.designPrices || defaultDesignPrices,
        orderStatuses: db.settings.orderStatuses
      });
    }

    if (url.pathname === "/api/admin/settings" && request.method === "GET") {
      if (!requireAdmin(request, response)) return;
      return send(response, 200, { settings: db.settings, bankAccounts: db.bankAccounts, deliveryZones: db.deliveryZones });
    }

    if (url.pathname === "/api/admin/settings" && request.method === "PATCH") {
      if (!requireAdmin(request, response)) return;
      const body = await readBody(request);
      db.settings = {
        ...db.settings,
        ...body.settings,
        oauth: { ...db.settings.oauth, ...(body.settings?.oauth || {}) },
        designPrices: { ...db.settings.designPrices, ...(body.settings?.designPrices || {}) }
      };
      if (Array.isArray(body.bankAccounts)) db.bankAccounts = body.bankAccounts;
      if (Array.isArray(body.deliveryZones)) db.deliveryZones = body.deliveryZones.map((zone) => ({ ...zone, fee: Number(zone.fee || 0) }));
      await saveDb();
      return send(response, 200, { settings: db.settings, bankAccounts: db.bankAccounts, deliveryZones: db.deliveryZones });
    }

    if (url.pathname === "/api/auth/login" && request.method === "POST") {
      const body = await readBody(request);
      const identifier = String(body.email || body.identifier || "").toLowerCase();
      const cleanPhone = String(body.phone || body.identifier || "").replace(/\D/g, "");
      const user = db.users.find((item) => item.email.toLowerCase() === identifier || String(item.phone || "").replace(/\D/g, "") === cleanPhone);
      if (!user || user.passwordHash !== hashPassword(body.password || "")) return send(response, 401, { message: "Invalid email or password" });
      return send(response, 200, { token: signToken(user), user: publicUser(user) });
    }

    if (url.pathname === "/api/auth/identify" && request.method === "POST") {
      const body = await readBody(request);
      const identifier = String(body.identifier || body.email || "").toLowerCase();
      const cleanPhone = String(body.phone || body.identifier || "").replace(/\D/g, "");
      const user = db.users.find((item) => item.email.toLowerCase() === identifier || String(item.phone || "").replace(/\D/g, "") === cleanPhone);
      return send(response, 200, { exists: Boolean(user), user: user ? { name: user.name, phone: user.phone || "" } : null });
    }

    if (url.pathname === "/api/auth/register" && request.method === "POST") {
      const body = await readBody(request);
      if (!body.email || !body.password) return send(response, 400, { message: "Email and password are required" });
      if (String(body.password).length < 6) return send(response, 400, { message: "Password must be at least 6 characters" });
      if (db.users.some((user) => user.email.toLowerCase() === String(body.email).toLowerCase())) return send(response, 409, { message: "Account already exists" });
      const user = {
        id: createId("usr"),
        name: body.name || "OMOSALA Customer",
        email: body.email,
        phone: body.phone || "",
        role: body.role || "customer",
        passwordHash: hashPassword(body.password),
        createdAt: new Date().toISOString()
      };
      db.users.push(user);
      if (body.address) {
        db.addresses.unshift({
          id: createId("addr"),
          userId: user.id,
          name: "Default delivery address",
          phone: user.phone || "",
          address: body.address,
          city: "",
          state: "",
          createdAt: new Date().toISOString()
        });
      }
      await saveDb();
      return send(response, 201, { token: signToken(user), user: publicUser(user) });
    }

    if (url.pathname === "/api/auth/social" && request.method === "POST") {
      const body = await readBody(request);
      const provider = String(body.provider || "social").toLowerCase();
      const email = body.email || `${provider}.customer@omosala.local`;
      let user = db.users.find((item) => item.email.toLowerCase() === String(email).toLowerCase());
      if (!user) {
        user = {
          id: createId("usr"),
          name: body.name || `${provider[0].toUpperCase()}${provider.slice(1)} Customer`,
          email,
          phone: body.phone || "",
          role: "customer",
          provider,
          passwordHash: hashPassword(createId("social")),
          createdAt: new Date().toISOString()
        };
        db.users.push(user);
        await saveDb();
      }
      return send(response, 200, { token: signToken(user), user: publicUser(user) });
    }

    if (url.pathname === "/api/auth/social/start" && request.method === "POST") {
      const body = await readBody(request);
      const provider = String(body.provider || "").toLowerCase();
      if (!["google", "facebook", "apple"].includes(provider)) return send(response, 400, { message: "Unsupported provider" });
      const authUrl = buildSocialAuthUrl(provider);
      return send(response, 200, {
        provider,
        mode: authUrl ? "live" : "demo",
        setupRequired: !authUrl,
        authUrl,
        message: authUrl ? "Redirect customer to provider" : `Add ${provider} OAuth keys to enable real login.`
      });
    }

    if (url.pathname === "/api/auth/request-otp" && request.method === "POST") {
      return send(response, 410, { message: "OTP is disabled. OMOSALA PRINTS uses password login and WhatsApp notifications." });
    }

    if (url.pathname === "/api/auth/verify-otp" && request.method === "POST") {
      return send(response, 410, { message: "OTP is disabled. Use password login." });
    }

    if (url.pathname === "/api/auth/me" && request.method === "GET") {
      return send(response, 200, { user: publicUser(verifyToken(request)) });
    }

    if (url.pathname === "/api/dashboard/summary" && request.method === "GET") {
      return send(response, 200, getSummary());
    }

    if (url.pathname === "/api/products" && request.method === "GET") {
      const category = url.searchParams.get("category");
      const search = String(url.searchParams.get("search") || "").toLowerCase();
      const products = db.products.filter((product) => (!category || product.category === category) && (!search || product.name.toLowerCase().includes(search)));
      return send(response, 200, products);
    }

    const productDetailMatch = url.pathname.match(/^\/api\/products\/([^/]+)$/);
    if (productDetailMatch && request.method === "GET") {
      const product = db.products.find((item) => item.id === productDetailMatch[1]);
      if (!product) return send(response, 404, { message: "Product not found" });
      return send(response, 200, { ...product, description: product.description || "Professional OMOSALA PRINT product with quality production, approval workflow, and delivery support.", reviews: [{ name: "Verified buyer", rating: 5, comment: "Clean finish and fast communication." }] });
    }

    if (url.pathname === "/api/products" && request.method === "POST") {
      if (!requireAdmin(request, response)) return;
      const body = await readBody(request);
      const product = {
        id: createId("prod"),
        name: body.name || "Untitled product",
        category: body.category || "Business Printing",
        vendor: body.vendor || "OMOSALA PRINT Studio",
        price: Number(body.price || 0),
        stock: Number(body.stock || 0),
        sku: body.sku || `OMS-${Date.now()}`,
        requiresDesign: Boolean(body.requiresDesign),
        pricingUnit: body.pricingUnit || "unit",
        designPrices: body.designPrices || db.settings.designPrices || defaultDesignPrices,
        status: body.status || "Pending Approval",
        image: body.image || "",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      };
      db.products.unshift(product);
      await saveDb();
      return send(response, 201, product);
    }

    const productMatch = url.pathname.match(/^\/api\/products\/([^/]+)$/);
    if (productMatch && request.method === "PATCH") {
      if (!requireAdmin(request, response)) return;
      const body = await readBody(request);
      const index = db.products.findIndex((product) => product.id === productMatch[1]);
      if (index === -1) return send(response, 404, { message: "Product not found" });
      db.products[index] = {
        ...db.products[index],
        ...body,
        price: Number(body.price ?? db.products[index].price),
        stock: Number(body.stock ?? db.products[index].stock),
        requiresDesign: body.requiresDesign ?? db.products[index].requiresDesign,
        pricingUnit: body.pricingUnit || db.products[index].pricingUnit || "unit",
        designPrices: body.designPrices || db.products[index].designPrices || db.settings.designPrices || defaultDesignPrices,
        updatedAt: new Date().toISOString()
      };
      await saveDb();
      return send(response, 200, db.products[index]);
    }

    if (url.pathname === "/api/quotes" && request.method === "GET") return send(response, 200, quotes);

    if (url.pathname === "/api/quotes" && request.method === "POST") {
      const body = await readBody(request);
      const quote = {
        _id: createId("quote"),
        customerName: body.customerName || "",
        service: body.service || "General print request",
        quantity: body.quantity || "",
        contact: body.contact || "",
        notes: body.notes || "",
        quotedAmount: Number(body.quotedAmount || 0),
        invoiceNumber: body.invoiceNumber || "",
        status: "New",
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      };
      quotes.unshift(quote);
      await saveQuotes();
      return send(response, 201, quote);
    }

    const quoteMatch = url.pathname.match(/^\/api\/quotes\/([^/]+)$/);
    if (quoteMatch && request.method === "PATCH") {
      const body = await readBody(request);
      const index = quotes.findIndex((quote) => quote._id === quoteMatch[1] || quote.id === quoteMatch[1]);
      if (index === -1) return send(response, 404, { message: "Quote not found" });
      const quotedAmount = body.quotedAmount !== undefined ? Number(body.quotedAmount) : quotes[index].quotedAmount;
      quotes[index] = { ...quotes[index], ...body, quotedAmount, invoiceNumber: body.invoiceNumber || quotes[index].invoiceNumber || (quotedAmount ? `OMQ-INV-${Date.now()}` : ""), updatedAt: new Date().toISOString() };
      await saveQuotes();
      return send(response, 200, quotes[index]);
    }

    if (url.pathname === "/api/orders" && request.method === "GET") return send(response, 200, db.orders);

    if (url.pathname === "/api/orders" && request.method === "POST") {
      const body = await readBody(request);
      const items = Array.isArray(body.items) ? body.items : [];
      const subtotal = items.reduce((sum, item) => {
        const squareFeet = item.pricingUnit === "per_sqft" ? Math.max(1, Number(item.widthFeet || 1)) * Math.max(1, Number(item.heightFeet || 1)) : 1;
        return sum + Number(item.price || 0) * Number(item.quantity || 1) * squareFeet;
      }, 0);
      const deliveryFee = Number(body.deliveryFee || (subtotal > 250000 ? 0 : 3500));
      const designFee = Number(body.designFee || body.designFlow?.designFee || 0);
      if (body.paymentMethod === "Pay Later") {
        return send(response, 400, { message: "Pay later is coming soon." });
      }
      if (body.paymentMethod === "Pay on Delivery") {
        const eligibility = payOnDeliveryEligibility({ phone: body.phone, address: body.address, deliveryZone: body.deliveryZone });
        if (!eligibility.eligible) return send(response, 400, { message: eligibility.reason, eligibility });
      }
      const order = {
        id: createId("ord"),
        orderNumber: createOrderNumber(),
        customerName: body.customerName || "Walk-in Customer",
        phone: body.phone || "",
        address: body.address || "",
        items,
        subtotal,
        deliveryFee,
        designFee,
        deliveryZone: body.deliveryZone || "Lagos Mainland",
        bankProof: body.bankProof || "",
        bankProofFile: body.bankProofFile || "",
        designFlow: body.designFlow || {},
        riderId: body.riderId || "",
        trackingNumber: `OMD-${Date.now()}`,
        total: subtotal + deliveryFee + designFee,
        paymentMethod: body.paymentMethod || "Online Payment",
        paymentStatus: "Pending",
        status: "Pending Payment",
        deliveryStatus: "Pending Payment",
        invoiceNumber: `OMOSALA-INV-${Date.now()}`,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      };
      db.orders.unshift(order);
      addAudit(`Order created: ${order.orderNumber}`);
      const orderMessage = `Hello ${order.customerName}, your OMOSALA PRINTS order ${order.orderNumber} has been received. Tracking: ${order.trackingNumber}. Total: NGN ${order.total.toLocaleString()}.`;
      const whatsappStatus = await sendWhatsappMessage(order.phone, orderMessage);
      db.notifications.unshift({ id: createId("note"), type: "whatsapp", title: "New order received", message: orderMessage, whatsappUrl: whatsappLink(order.phone, orderMessage), whatsappStatus, createdAt: new Date().toISOString(), read: false });
      await saveDb();
      return send(response, 201, order);
    }

    const orderMatch = url.pathname.match(/^\/api\/orders\/([^/]+)$/);
    if (orderMatch && request.method === "PATCH") {
      if (!requireAdmin(request, response)) return;
      const body = await readBody(request);
      const index = db.orders.findIndex((order) => order.id === orderMatch[1] || order.orderNumber === orderMatch[1]);
      if (index === -1) return send(response, 404, { message: "Order not found" });
      db.orders[index] = { ...db.orders[index], ...body, updatedAt: new Date().toISOString() };
      if (body.riderId) db.orders[index].deliveryStatus = body.deliveryStatus || "Out for delivery";
      addAudit(`Order updated: ${db.orders[index].orderNumber}`, verifyToken(request)?.id || "admin");
      await saveDb();
      return send(response, 200, db.orders[index]);
    }

    const orderTrackMatch = url.pathname.match(/^\/api\/orders\/track\/([^/]+)$/);
    if (orderTrackMatch && request.method === "GET") {
      const order = db.orders.find((item) => item.orderNumber === orderTrackMatch[1] || item.trackingNumber === orderTrackMatch[1]);
      if (!order) return send(response, 404, { message: "Order not found" });
      const rider = db.riders.find((item) => item.id === order.riderId) || null;
      return send(response, 200, { order, rider, timeline: db.settings.orderStatuses.map((status) => ({ status, active: status === order.status || status === order.deliveryStatus })) });
    }

    if (url.pathname === "/api/print-orders" && request.method === "POST") {
      const body = await readBody(request);
      const upload = {
        id: createId("upl"),
        service: body.service || "Custom print order",
        customerName: body.customerName || "",
        contact: body.contact || "",
        files: Array.isArray(body.files) ? body.files : [],
        cloudinaryReady: Boolean(process.env.CLOUDINARY_CLOUD_NAME),
        quantity: Number(body.quantity || 0),
        material: body.material || "",
        size: body.size || "",
        finishing: body.finishing || "",
        urgency: body.urgency || "",
        notes: body.notes || "",
        estimatedTotal: Number(body.estimatedTotal || 0),
        approvalStatus: "Awaiting Design Review",
        productionStatus: "Pending",
        createdAt: new Date().toISOString()
      };
      db.uploads.unshift(upload);
      await saveDb();
      return send(response, 201, upload);
    }

    if (url.pathname === "/api/uploads" && request.method === "GET") return send(response, 200, db.uploads);

    if (url.pathname === "/api/uploads/signature" && request.method === "POST") {
      if (!integrations.cloudinary) return send(response, 200, { mode: "demo", setupRequired: true, message: "Add Cloudinary keys to enable real file storage" });
      const timestamp = Math.floor(Date.now() / 1000);
      const folder = "omosala-print-orders";
      const stringToSign = `folder=${folder}&timestamp=${timestamp}${process.env.CLOUDINARY_API_SECRET}`;
      const signature = crypto.createHash("sha1").update(stringToSign).digest("hex");
      return send(response, 200, { mode: "live", cloudName: process.env.CLOUDINARY_CLOUD_NAME, apiKey: process.env.CLOUDINARY_API_KEY, folder, timestamp, signature });
    }

    if (url.pathname === "/api/uploads/complete" && request.method === "POST") {
      const body = await readBody(request);
      const upload = { id: createId("upl"), service: body.service || "Uploaded artwork", customerName: body.customerName || "", contact: body.contact || "", files: body.files || [], approvalStatus: "Awaiting Design Review", productionStatus: "Pending", createdAt: new Date().toISOString() };
      db.uploads.unshift(upload);
      await saveDb();
      return send(response, 201, upload);
    }

    if (url.pathname === "/api/payments/initialize" && request.method === "POST") {
      const body = await readBody(request);
      if (body.provider === "Pay Later") return send(response, 400, { message: "Pay later is coming soon." });
      const payment = {
        id: createId("pay"),
        provider: body.provider || "Online Payment",
        orderId: body.orderId || "",
        amount: Number(body.amount || 0),
        currency: body.currency || "NGN",
        reference: `OMS-PAY-${Date.now()}`,
        status: "Initialized",
        authorizationUrl: body.provider === "Online Payment" ? `https://paystack.com/pay/omosala-demo-${Date.now()}` : "",
        liveReady: body.provider === "Online Payment" ? integrations.paystack || integrations.flutterwave : true,
        createdAt: new Date().toISOString()
      };
      db.payments.unshift(payment);
      await saveDb();
      return send(response, 201, payment);
    }

    const paymentVerifyMatch = url.pathname.match(/^\/api\/payments\/verify\/([^/]+)$/);
    if (paymentVerifyMatch && request.method === "POST") {
      const payment = db.payments.find((item) => item.reference === paymentVerifyMatch[1] || item.id === paymentVerifyMatch[1]);
      if (!payment) return send(response, 404, { message: "Payment not found" });
      payment.status = "Verified";
      const order = db.orders.find((item) => item.id === payment.orderId);
      if (order) {
        order.paymentStatus = "Paid";
        order.status = "Payment Confirmed";
      }
      addAudit(`Payment verified: ${payment.reference}`);
      await saveDb();
      return send(response, 200, payment);
    }

    if (url.pathname === "/api/payments/webhook/paystack" && request.method === "POST") {
      const body = await readBody(request);
      if (integrations.paystack && request.headers["x-paystack-signature"]) {
        addAudit("Paystack webhook received");
      }
      return send(response, 200, { received: true, provider: "paystack", reference: body?.data?.reference || body.reference || "" });
    }

    if (url.pathname === "/api/payments/webhook/flutterwave" && request.method === "POST") {
      const body = await readBody(request);
      if (integrations.flutterwave && request.headers["verif-hash"]) {
        addAudit("Flutterwave webhook received");
      }
      return send(response, 200, { received: true, provider: "flutterwave", reference: body?.data?.tx_ref || body.reference || "" });
    }

    if (url.pathname === "/api/refunds" && request.method === "POST") {
      if (!requireAdmin(request, response)) return;
      const body = await readBody(request);
      const refund = { id: createId("refund"), orderId: body.orderId || "", amount: Number(body.amount || 0), reason: body.reason || "", status: "Requested", createdAt: new Date().toISOString() };
      db.refunds.unshift(refund);
      await saveDb();
      return send(response, 201, refund);
    }

    if (url.pathname === "/api/payments" && request.method === "GET") return send(response, 200, db.payments);
    if (url.pathname === "/api/payments/pay-on-delivery-eligibility" && request.method === "POST") {
      const body = await readBody(request);
      return send(response, 200, payOnDeliveryEligibility(body));
    }
    const invoiceMatch = url.pathname.match(/^\/api\/orders\/([^/]+)\/invoice$/);
    if (invoiceMatch && request.method === "GET") {
      const order = db.orders.find((item) => item.id === invoiceMatch[1] || item.orderNumber === invoiceMatch[1]);
      if (!order) return send(response, 404, { message: "Order not found" });
      return send(response, 200, { invoiceNumber: order.invoiceNumber, orderNumber: order.orderNumber, customerName: order.customerName, total: order.total, paymentStatus: order.paymentStatus, qrPayload: `OMOSALA|${order.orderNumber}|${order.total}` });
    }
    if (url.pathname === "/api/notifications" && request.method === "GET") return send(response, 200, db.notifications);
    if (url.pathname === "/api/delivery/zones" && request.method === "GET") return send(response, 200, db.deliveryZones);
    if (url.pathname === "/api/delivery/riders" && request.method === "GET") return send(response, 200, db.riders);

    if (url.pathname === "/api/customer/addresses" && request.method === "GET") {
      const user = requireUser(request, response);
      if (!user) return;
      return send(response, 200, db.addresses.filter((item) => item.userId === user.id));
    }

    if (url.pathname === "/api/customer/addresses" && request.method === "POST") {
      const user = requireUser(request, response);
      if (!user) return;
      const body = await readBody(request);
      const address = { id: createId("addr"), userId: user.id, name: body.name || "Default address", phone: body.phone || user.phone || "", address: body.address || "", city: body.city || "", state: body.state || "", createdAt: new Date().toISOString() };
      db.addresses.unshift(address);
      await saveDb();
      return send(response, 201, address);
    }

    if (url.pathname === "/api/customer/wishlist" && request.method === "GET") {
      const user = requireUser(request, response);
      if (!user) return;
      return send(response, 200, db.wishlists.filter((item) => item.userId === user.id));
    }

    if (url.pathname === "/api/customer/wishlist" && request.method === "POST") {
      const user = requireUser(request, response);
      if (!user) return;
      const body = await readBody(request);
      const wish = { id: createId("wish"), userId: user.id, productId: body.productId || "", createdAt: new Date().toISOString() };
      db.wishlists.unshift(wish);
      await saveDb();
      return send(response, 201, wish);
    }

    if (url.pathname === "/api/support/tickets" && request.method === "GET") return send(response, 200, db.tickets);

    if (url.pathname === "/api/support/tickets" && request.method === "POST") {
      const body = await readBody(request);
      const ticket = { id: createId("ticket"), name: body.name || "", contact: body.contact || "", subject: body.subject || "Support request", message: body.message || "", status: "Open", createdAt: new Date().toISOString() };
      db.tickets.unshift(ticket);
      const ticketMessage = `Hello ${ticket.name}, your OMOSALA PRINTS support ticket ${ticket.id} is open.`;
      const whatsappStatus = await sendWhatsappMessage(ticket.contact, ticketMessage);
      db.notifications.unshift({ id: createId("note"), type: "whatsapp", title: "Support ticket opened", message: `Support ticket ${ticket.id}: ${ticket.subject}`, whatsappUrl: whatsappLink(ticket.contact, ticketMessage), whatsappStatus, createdAt: new Date().toISOString(), read: false });
      await saveDb();
      return send(response, 201, ticket);
    }

    if (url.pathname === "/api/whatsapp/notify" && request.method === "POST") {
      const body = await readBody(request);
      const message = body.message || "Hello from OMOSALA PRINTS.";
      const whatsappStatus = await sendWhatsappMessage(body.phone, message);
      const note = { id: createId("wa"), type: "whatsapp", phone: body.phone || "08030572418", message, whatsappUrl: whatsappLink(body.phone, message), status: whatsappStatus.status, whatsappStatus, createdAt: new Date().toISOString() };
      db.notifications.unshift(note);
      await saveDb();
      return send(response, 201, note);
    }

    if (url.pathname === "/api/admin/users" && request.method === "GET") {
      if (!requireAdmin(request, response)) return;
      return send(response, 200, db.users.map(publicUser));
    }
    if (url.pathname === "/api/admin/vendors" && request.method === "GET") return send(response, 200, db.vendors);
    if (url.pathname === "/api/admin/reports" && request.method === "GET") return send(response, 200, { summary: getSummary(), refunds: db.refunds, auditLogs: db.auditLogs.slice(0, 50) });
    if (url.pathname === "/api/accounting/summary" && request.method === "GET") return send(response, 200, { revenue: getSummary().revenue, pendingPayouts: db.vendors.length * 25000, refunds: db.refunds.reduce((sum, item) => sum + Number(item.amount || 0), 0), exportsReady: true });

    return send(response, 404, { message: "Not found" });
  } catch (error) {
    return send(response, 500, { message: error.message || "Server error" });
  }
});

server.listen(port, () => {
  console.log(`OMOSALA simple API running on http://localhost:${port}`);
  console.log(`Quotes are saved in ${quotesPath}`);
  console.log(`Marketplace data is saved in ${dbPath}`);
  console.log("Default admin: admin@omosalaprints.ng / admin123");
});
