/**
 * Prometheus Metrics
 *
 * Application metrics for monitoring and observability
 */

import { Registry, Counter, Histogram, Gauge } from 'prom-client';

// Create registry
export const register = new Registry();

// Default labels
register.setDefaultLabels({
  app: 'translate-api',
});

/**
 * HTTP Request Metrics
 */
export const httpRequestDuration = new Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in seconds',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.1, 0.5, 1, 2, 5, 10],
  registers: [register],
});

export const httpRequestTotal = new Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status_code'],
  registers: [register],
});

/**
 * Translation Job Metrics
 */
export const translationJobsTotal = new Counter({
  name: 'translation_jobs_total',
  help: 'Total number of translation jobs',
  labelNames: ['model', 'status', 'type'],
  registers: [register],
});

export const translationJobDuration = new Histogram({
  name: 'translation_job_duration_seconds',
  help: 'Duration of translation jobs in seconds',
  labelNames: ['model', 'type'],
  buckets: [1, 5, 10, 30, 60, 120],
  registers: [register],
});

export const tokensProcessedTotal = new Counter({
  name: 'tokens_processed_total',
  help: 'Total number of tokens processed',
  labelNames: ['model'],
  registers: [register],
});

/**
 * Webhook Delivery Metrics
 */
export const webhookDeliveriesTotal = new Counter({
  name: 'webhook_deliveries_total',
  help: 'Total number of webhook delivery attempts',
  labelNames: ['success'],
  registers: [register],
});

export const webhookDeliveryDuration = new Histogram({
  name: 'webhook_delivery_duration_seconds',
  help: 'Duration of webhook delivery attempts in seconds',
  buckets: [0.1, 0.5, 1, 2, 5],
  registers: [register],
});

/**
 * Subscription Metrics
 */
export const activeSubscriptions = new Gauge({
  name: 'active_subscriptions',
  help: 'Number of active subscriptions',
  labelNames: ['tier'],
  registers: [register],
});

export const subscriptionEventsTotal = new Counter({
  name: 'subscription_events_total',
  help: 'Total number of subscription events',
  labelNames: ['event_type'],
  registers: [register],
});

/**
 * Credit Metrics
 */
export const creditsAllocatedTotal = new Counter({
  name: 'credits_allocated_total',
  help: 'Total number of credits allocated',
  labelNames: ['tier'],
  registers: [register],
});

export const creditsDeductedTotal = new Counter({
  name: 'credits_deducted_total',
  help: 'Total number of credits deducted',
  labelNames: ['tier', 'model'],
  registers: [register],
});

/**
 * Payment Metrics
 */
export const paymentsTotal = new Counter({
  name: 'payments_total',
  help: 'Total number of payments',
  labelNames: ['status', 'type'],
  registers: [register],
});

export const revenueTotal = new Counter({
  name: 'revenue_total',
  help: 'Total revenue in USD',
  labelNames: ['tier', 'cycle'],
  registers: [register],
});

export const permanentOrphanDisputesTotal = new Counter({
  name: 'permanent_orphan_disputes_total',
  help: 'Number of payment disputes detected with no matching payment after 24h. Indicates potential missing payment webhook delivery or adversarial dispute activity.',
  labelNames: ['reason'],
  registers: [register],
});

/**
 * Error Metrics
 */
export const errorsTotal = new Counter({
  name: 'errors_total',
  help: 'Total number of errors',
  labelNames: ['type', 'code'],
  registers: [register],
});

/**
 * Database Metrics
 */
export const databaseQueryDuration = new Histogram({
  name: 'database_query_duration_seconds',
  help: 'Duration of database queries in seconds',
  labelNames: ['operation'],
  buckets: [0.01, 0.05, 0.1, 0.5, 1, 2],
  registers: [register],
});

export const databaseConnectionsActive = new Gauge({
  name: 'database_connections_active',
  help: 'Number of active database connections',
  registers: [register],
});

/**
 * Queue Metrics
 */
export const queueJobsTotal = new Counter({
  name: 'queue_jobs_total',
  help: 'Total number of queue jobs',
  labelNames: ['queue', 'status'],
  registers: [register],
});

export const queueJobDuration = new Histogram({
  name: 'queue_job_duration_seconds',
  help: 'Duration of queue jobs in seconds',
  labelNames: ['queue'],
  buckets: [1, 5, 10, 30, 60, 120],
  registers: [register],
});

export const queueLength = new Gauge({
  name: 'queue_length',
  help: 'Number of jobs in queue',
  labelNames: ['queue'],
  registers: [register],
});

/**
 * Helper function to track HTTP request
 */
export function trackHttpRequest(method: string, route: string, statusCode: number, duration: number) {
  httpRequestTotal.inc({ method, route, status_code: statusCode });
  httpRequestDuration.observe({ method, route, status_code: statusCode }, duration);
}

/**
 * Helper function to track translation job
 */
export function trackTranslationJob(model: string, status: string, type: 'sync' | 'async', duration?: number) {
  translationJobsTotal.inc({ model, status, type });
  if (duration !== undefined) {
    translationJobDuration.observe({ model, type }, duration / 1000); // Convert ms to seconds
  }
}

/**
 * Helper function to track tokens processed
 */
export function trackTokensProcessed(model: string, tokens: number) {
  tokensProcessedTotal.inc({ model }, tokens);
}

/**
 * Helper function to track webhook delivery
 */
export function trackWebhookDelivery(success: boolean, duration: number) {
  webhookDeliveriesTotal.inc({ success: success.toString() });
  webhookDeliveryDuration.observe(duration / 1000); // Convert ms to seconds
}

/**
 * Helper function to track error
 */
export function trackError(type: string, code: string) {
  errorsTotal.inc({ type, code });
}

/**
 * Collect all metrics
 */
export async function getMetrics(): Promise<string> {
  return register.metrics();
}
