import { getGlobalErrorHandler } from '@/lib/infrastructure/GlobalErrorHandler';
import { getGlobalApiLogger } from '@/lib/infrastructure/ApiRequestLogger';
import { ApiError } from '@/lib/api/base/ApiError';
import { Result } from '@/lib/contracts/Result';
import { DomainError, Service } from '@/lib/contracts/services/Service';
import { getWebsiteServerEnv } from '@/lib/config/env';

export interface ErrorStats {
  totalErrors: number;
  errorsByType: Record<string, number>;
  errorsByTime: Array<{ time: string; count: number }>;
  recentErrors: Array<{
    timestamp: string;
    message: string;
    type: string;
    context?: unknown;
  }>;
  apiStats: {
    totalRequests: number;
    successful: number;
    failed: number;
    averageDuration: number;
    slowestRequests: Array<{ url: string; duration: number }>;
  };
  environment: {
    mode: string;
    version?: string;
    buildTime?: string;
  };
}

export function getErrorAnalyticsStats(): ErrorStats {
  return ErrorAnalyticsService.getErrorAnalyticsStats();
}

export class ErrorAnalyticsService implements Service {
  static getErrorAnalyticsStats(): ErrorStats {
    const globalHandler = getGlobalErrorHandler();
    const apiLogger = getGlobalApiLogger();

    const errorHistory = globalHandler.getErrorHistory();
    const errorStats = globalHandler.getStats();
    const apiStats = apiLogger.getStats();

    // Group errors by time (last 10 minutes)
    const timeGroups = new Map<string, number>();
    const now = Date.now();
    const tenMinutesAgo = now - (10 * 60 * 1000);

    errorHistory.forEach(entry => {
      const entryTime = new Date(entry.timestamp).getTime();
      if (entryTime >= tenMinutesAgo) {
        const timeKey = new Date(entry.timestamp).toLocaleTimeString();
        timeGroups.set(timeKey, (timeGroups.get(timeKey) || 0) + 1);
      }
    });

    const errorsByTime = Array.from(timeGroups.entries())
      .map(([time, count]) => ({ time, count }))
      .sort((a, b) => a.time.localeCompare(b.time));

    const recentErrors = errorHistory.slice(-10).reverse().map(entry => ({
      timestamp: entry.timestamp,
      message: entry.error.message,
      type: entry.error instanceof ApiError ? entry.error.type : entry.error.name || 'Error',
      context: entry.context,
    }));

    const slowestRequests = apiLogger.getSlowestRequests(5).map(log => ({
      url: log.url,
      duration: log.response?.duration || 0,
    }));

    const env = getWebsiteServerEnv();

    return {
      totalErrors: errorStats.total,
      errorsByType: errorStats.byType,
      errorsByTime,
      recentErrors,
      apiStats: {
        totalRequests: apiStats.total,
        successful: apiStats.successful,
        failed: apiStats.failed,
        averageDuration: apiStats.averageDuration,
        slowestRequests,
      },
      environment: {
        mode: env.NODE_ENV || 'unknown',
        version: process.env.NEXT_PUBLIC_APP_VERSION,
        buildTime: process.env.NEXT_PUBLIC_BUILD_TIME,
      },
    };
  }

  async getErrorAnalyticsStats(): Promise<Result<ErrorStats, DomainError>> {
    try {
      return Result.ok(ErrorAnalyticsService.getErrorAnalyticsStats());
    } catch (error: unknown) {
      return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to get error analytics stats' });
    }
  }
}
