import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
import {
  AdminMonitoringCategory,
  AdminMonitoringEvent,
  AdminMonitoringEventFilters,
  AdminMonitoringLevel,
  AdminQueue,
  AdminWebhookDelivery,
} from '../models/admin-monitoring.model';
import { AdminMonitoringGateway } from './admin-monitoring-gateway.interface';

const CATEGORIES: AdminMonitoringCategory[] = ['audit', 'security', 'login', 'failed_login', 'api', 'error', 'warning'];
const ACTORS = ['karen@dexar.market', 'anna@dexar.market', 'system', 'unknown'];
const EVENT_COUNT = 40;

@Injectable({ providedIn: 'root' })
export class AdminMonitoringLocalGateway implements AdminMonitoringGateway {
  private events: AdminMonitoringEvent[] | null = null;

  loadEvents(filters: AdminMonitoringEventFilters): Observable<AdminMonitoringEvent[]> {
    const all = this.ensureEvents();
    const filtered = all
      .filter(event => filters.category === 'all' || event.category === filters.category)
      .filter(event => !filters.search || `${event.message} ${event.actor}`.toLowerCase().includes(filters.search.toLowerCase()))
      .sort((left, right) => right.timestamp.localeCompare(left.timestamp));
    return of(filtered).pipe(delay(50));
  }

  loadQueues(): Observable<AdminQueue[]> {
    const queues: AdminQueue[] = [
      { name: 'order-notifications', depth: 3, status: 'healthy' },
      { name: 'media-processing', depth: 0, status: 'healthy' },
      { name: 'webhook-delivery', depth: 12, status: 'degraded' },
    ];
    return of(queues).pipe(delay(50));
  }

  loadWebhooks(): Observable<AdminWebhookDelivery[]> {
    return of(Array.from({ length: 8 }, (_, index) => ({
      id: `webhook-${index + 1}`,
      endpoint: index % 2 === 0 ? 'https://partner.example.com/orders' : 'https://partner.example.com/inventory',
      event: index % 2 === 0 ? 'order.created' : 'inventory.updated',
      status: index % 5 === 0 ? 'failed' : index % 4 === 0 ? 'pending' : 'delivered',
      timestamp: new Date(Date.now() - index * 3 * 60 * 60 * 1000).toISOString(),
    } as AdminWebhookDelivery))).pipe(delay(50));
  }

  private ensureEvents(): AdminMonitoringEvent[] {
    if (!this.events) {
      this.events = Array.from({ length: EVENT_COUNT }, (_, index) => this.seedEvent(index));
    }
    return this.events;
  }

  private seedEvent(index: number): AdminMonitoringEvent {
    const category = CATEGORIES[index % CATEGORIES.length];
    const level: AdminMonitoringLevel = category === 'error' || category === 'failed_login' ? 'error' : category === 'warning' ? 'warning' : 'info';
    return {
      id: `event-${index + 1}`,
      category,
      level,
      message: this.messageFor(category, index),
      technicalDetail: this.technicalDetailFor(category, index),
      actor: ACTORS[index % ACTORS.length],
      timestamp: new Date(Date.now() - index * 45 * 60 * 1000).toISOString(),
    };
  }

  private messageFor(category: AdminMonitoringCategory, index: number): string {
    switch (category) {
      case 'audit': return `Admin action recorded (#${index})`;
      case 'security': return `Security policy check passed (#${index})`;
      case 'login': return `Successful admin login (#${index})`;
      case 'failed_login': return `Failed login attempt (#${index})`;
      case 'api': return `Product data refreshed successfully`;
      case 'error': return `A background task failed unexpectedly`;
      case 'warning': return `A data lookup took longer than usual`;
      default: return `Event #${index}`;
    }
  }

  private technicalDetailFor(category: AdminMonitoringCategory, index: number): string | undefined {
    switch (category) {
      case 'api': return `GET /api/products responded 200 in ${80 + index}ms`;
      case 'error': return `Unhandled exception in checkout flow (#${index})`;
      case 'warning': return `Slow query detected (#${index})`;
      default: return undefined;
    }
  }
}
