#!/usr/bin/env node

import { execSync } from "node:child_process";
import { env } from "node:process";

const requiredVariables = [
  { key: "DATABASE_URL", requiredInProduction: true },
  { key: "AUTH_SECRET", requiredInProduction: true },
  { key: "CAMPAIGN_RETRY_JOB_TOKEN", requiredInProduction: true },
  { key: "WHATSAPP_WEBHOOK_VERIFY_TOKEN", requiredInProduction: false },
  { key: "WHATSAPP_WEBHOOK_SECRET", requiredInProduction: false },
  { key: "NEXT_PUBLIC_APP_URL", requiredInProduction: false },
  { key: "APP_URL", requiredInProduction: false },
  { key: "OPS_BASE_URL", requiredInProduction: false }
];

const placeholderPatterns = [
  "change-me",
  "changeme",
  "your-",
  "example",
  "todo",
  "placeholder"
];

const isProductionLike = env.NODE_ENV === "production";
let hasFailure = false;

function isPresent(value) {
  return typeof value === "string" && value.trim().length > 0;
}

function isPlaceholderValue(value) {
  const lowered = value.toLowerCase();
  return placeholderPatterns.some((pattern) => lowered.includes(pattern));
}

function validateSecretValue(key, value, expected) {
  if (!isPresent(value)) {
    if (expected) {
      reportIssue("error", `${key} is missing`);
    }
    return;
  }

  if (expected && value === expected) {
    reportIssue("error", `${key} is using production default placeholder`);
  }

  if (isPlaceholderValue(value)) {
    reportIssue("warn", `${key} looks like placeholder value`);
  }
}

function reportIssue(level, message) {
  if (level === "error") {
    console.error(`[ERROR] ${message}`);
    hasFailure = true;
    return;
  }

  if (level === "warn") {
    console.warn(`[WARN] ${message}`);
    return;
  }

  console.log(`[OK] ${message}`);
}

function checkEnv() {
  console.log("Checking environment variables...");
  for (const item of requiredVariables) {
    const value = env[item.key];
    const isRequired = item.requiredInProduction && isProductionLike;
    if (!isPresent(value)) {
      if (isRequired) {
        reportIssue("error", `${item.key} is missing`);
      } else {
        reportIssue("warn", `${item.key} is missing (optional)`);
      }
      continue;
    }

    if (item.key === "AUTH_SECRET") {
      validateSecretValue(item.key, value, "whatsapp-inbox-dev-secret");
      continue;
    }

    if (isPlaceholderValue(value)) {
      reportIssue("warn", `${item.key} has placeholder-like value`);
    }

    const display = value.replace(/./g, "*").slice(0, 4);
    reportIssue("ok", `${item.key} set (${display}...)`);
  }
}

function checkPrismaMigrationStatus() {
  console.log("Checking Prisma migration status...");
  try {
    const output = execSync("npx prisma migrate status --schema prisma/schema.prisma", {
      encoding: "utf8",
      stdio: ["pipe", "pipe", "pipe"]
    });
    if (/database is up to date/i.test(output)) {
      reportIssue("ok", "Database schema is up to date");
      return;
    }

    if (/No migration found/i.test(output)) {
      reportIssue("warn", "No migration found for current database");
      return;
    }

    reportIssue("warn", `Prisma migrate status output: ${output.trim()}`);
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    reportIssue("error", `Prisma migration check failed: ${message}`);
  }
}

async function runHealthCheck() {
  const baseUrl = (env.OPS_BASE_URL || env.APP_URL || env.NEXT_PUBLIC_APP_URL || "http://localhost:3000").replace(/\/+$/, "");
  const healthToken = env.HEALTHCHECK_TOKEN?.trim();

  const url = `${baseUrl}/api/health`;
  const headers = healthToken ? { Authorization: `Bearer ${healthToken}` } : {};

  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 12_000);

  try {
    const response = await fetch(url, { headers, signal: controller.signal });
    clearTimeout(timeout);
    if (!response.ok) {
      reportIssue("error", `Health endpoint returned ${response.status}`);
      return;
    }

    const payload = await response.json();
    if (!payload?.ok) {
      reportIssue("warn", `Health endpoint warning: ${JSON.stringify(payload)}`);
    } else {
      reportIssue("ok", `Health endpoint OK: ${payload.status}`);
    }
  } catch (error) {
    clearTimeout(timeout);
    reportIssue("error", `Health endpoint unreachable: ${error instanceof Error ? error.message : String(error)}`);
  }
}

async function runRetryEndpointCheck() {
  const baseUrl = (env.OPS_BASE_URL || env.APP_URL || env.NEXT_PUBLIC_APP_URL || "http://localhost:3000").replace(/\/+$/, "");
  const token = env.CAMPAIGN_RETRY_JOB_TOKEN?.trim();
  if (!token) {
    reportIssue("warn", "CAMPAIGN_RETRY_JOB_TOKEN missing; campaign job endpoint health check skipped");
    return;
  }

  const url = `${baseUrl}/api/jobs/campaign-retry?token=${encodeURIComponent(token)}`;
  const headers = { Authorization: `Bearer ${token}` };
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), 12_000);

  try {
    const response = await fetch(url, { headers, signal: controller.signal });
    clearTimeout(timeout);
    if (!response.ok) {
      reportIssue("warn", `Campaign retry endpoint returned ${response.status}`);
      return;
    }
    const payload = await response.json();
    reportIssue("ok", `Campaign retry endpoint reachable: ${payload.ok ? "ok" : "down"}`);
  } catch (error) {
    clearTimeout(timeout);
    reportIssue("warn", `Campaign retry endpoint error: ${error instanceof Error ? error.message : String(error)}`);
  }
}

async function main() {
  checkEnv();
  checkPrismaMigrationStatus();
  await runHealthCheck();
  await runRetryEndpointCheck();

  if (hasFailure) {
    reportIssue("error", "Readiness check failed.");
    process.exit(1);
  }

  reportIssue("ok", "Readiness check completed.");
}

await main();
