/**
 * Startup Health Check
 *
 * This module runs critical health checks when the application starts.
 * It prevents the app from starting if critical issues are detected.
 *
 * Migrated from Supabase to Convex (serverless datastore).
 */

import { convexQuery, isConvexConfigured } from './convex-client';

interface HealthCheckResult {
  passed: boolean;
  name: string;
  error?: string;
  warning?: string;
}

/**
 * Check Convex connectivity
 * Convex is serverless, so "health" means "can we reach the deployment"
 */
async function checkConvexConnection(): Promise<HealthCheckResult> {
  try {
    if (!isConvexConfigured()) {
      return {
        passed: false,
        name: 'Convex Connection',
        error: 'NEXT_PUBLIC_CONVEX_URL not configured',
      };
    }

    // Try a lightweight query to verify connectivity
    await convexQuery("auth/queries:getUserByEmail", { email: '__health_check__@mawidi.com' });

    return {
      passed: true,
      name: 'Convex Connection',
    };
  } catch (error: unknown) {
    const message = error instanceof Error ? error.message : 'Unknown error';
    return {
      passed: false,
      name: 'Convex Connection',
      error: `Convex connectivity check failed: ${message}`,
    };
  }
}

/**
 * Check required environment variables for the Convex + Clerk stack
 */
function checkEnvironmentVariables(): HealthCheckResult {
  const requiredVars = [
    'NEXT_PUBLIC_CONVEX_URL',
    'NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY',
  ];

  const missing = requiredVars.filter(varName => !process.env[varName]);

  if (missing.length > 0) {
    return {
      passed: false,
      name: 'Environment Variables',
      error: `Missing required variables: ${missing.join(', ')}`,
    };
  }

  return {
    passed: true,
    name: 'Environment Variables',
  };
}

/**
 * Run all health checks
 */
export async function runStartupHealthChecks(): Promise<{
  allPassed: boolean;
  results: HealthCheckResult[];
  criticalFailures: string[];
}> {
  const results: HealthCheckResult[] = [];
  const criticalFailures: string[] = [];

  // Check 1: Environment variables
  const envCheck = checkEnvironmentVariables();
  results.push(envCheck);
  if (!envCheck.passed) {
    criticalFailures.push(envCheck.error || 'Environment variables check failed');
  }

  // Check 2: Convex connectivity
  const connectionCheck = await checkConvexConnection();
  results.push(connectionCheck);
  if (!connectionCheck.passed) {
    criticalFailures.push(connectionCheck.error || 'Convex connection failed');
  }

  return {
    allPassed: criticalFailures.length === 0,
    results,
    criticalFailures,
  };
}

/**
 * Print health check results
 */
export function printHealthCheckResults(healthCheck: Awaited<ReturnType<typeof runStartupHealthChecks>>): void {
  console.log('\n--- Startup Health Check ---\n');

  for (const result of healthCheck.results) {
    if (result.passed) {
      console.log(`[PASS] ${result.name}`);
      if (result.warning) {
        console.log(`   Warning: ${result.warning}`);
      }
    } else {
      console.log(`[FAIL] ${result.name}`);
      if (result.error) {
        console.log(`   Error: ${result.error}`);
      }
    }
  }

  console.log();

  if (!healthCheck.allPassed) {
    console.error('CRITICAL HEALTH CHECK FAILURES:\n');
    healthCheck.criticalFailures.forEach((failure, idx) => {
      console.error(`${idx + 1}. ${failure}\n`);
    });
    console.error('Fix these issues before the application can start properly.\n');
  } else {
    console.log('All health checks passed - application ready\n');
  }
}

/**
 * Run health checks and log results.
 * Does not exit the process -- Convex is serverless and may be temporarily unreachable
 * during cold starts without indicating a true failure.
 */
export async function runHealthChecksOrExit(): Promise<void> {
  const healthCheck = await runStartupHealthChecks();
  printHealthCheckResults(healthCheck);

  if (!healthCheck.allPassed) {
    console.error('Application starting with health check failures.');
    console.error('Some features may not work correctly.\n');
  }
}

/**
 * Lightweight health check for API endpoints
 * Returns status for /api/health endpoint
 */
export async function getHealthStatus(): Promise<{
  status: 'healthy' | 'degraded' | 'unhealthy';
  checks: HealthCheckResult[];
  timestamp: string;
}> {
  const healthCheck = await runStartupHealthChecks();

  const status = healthCheck.allPassed
    ? 'healthy'
    : healthCheck.criticalFailures.length > 1
    ? 'unhealthy'
    : 'degraded';

  return {
    status,
    checks: healthCheck.results,
    timestamp: new Date().toISOString(),
  };
}
