import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { GrafanaQueryService } from './grafana-query.service';
import { ZabbixHostService } from './zabbix-host.service';
import { ZabbixMetricsService } from './zabbix-metrics.service';
import { ZabbixStatusService } from './zabbix-status.service';

type GrafanaQueryPayload = Record<string, unknown>;

@Injectable()
export class GrafanaProxyService {
  constructor(
    private readonly zabbixHostService: ZabbixHostService,
    private readonly zabbixStatusService: ZabbixStatusService,
    private readonly zabbixMetricsService: ZabbixMetricsService,
    private readonly grafanaQueryService: GrafanaQueryService
  ) {}

  private requireApiKey(apiKey?: string) {
    const expectedApiKey = process.env.GRAFANA_PROXY_API_KEY;
    if (!expectedApiKey) {
      throw new HttpException('GRAFANA_PROXY_API_KEY not configured', HttpStatus.SERVICE_UNAVAILABLE);
    }
    if (apiKey !== expectedApiKey) {
      throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
    }
  }

  async listZabbixHosts(
    apiKey?: string,
    orgIdHeader?: string
  ): Promise<{ hosts: string[]; rows: Array<{ text: string; value: string }> }> {
    this.requireApiKey(apiKey);
    return this.zabbixHostService.listHosts(orgIdHeader);
  }

  async getZabbixSummary(
    apiKey?: string,
    orgIdHeader?: string
  ): Promise<{ rows: Array<Record<string, string | number | null>> }> {
    this.requireApiKey(apiKey);
    return this.zabbixStatusService.getSummary(orgIdHeader);
  }

  async getZabbixHostDetail(
    apiKey?: string,
    orgIdHeader?: string,
    hostName?: string,
    view?: string,
    contains?: string
  ): Promise<{ host: string; rows: Array<Record<string, string | number | null>> }> {
    this.requireApiKey(apiKey);
    return this.zabbixHostService.getHostDetail(orgIdHeader, hostName, view, contains);
  }

  async getZabbixHostMetrics(
    apiKey?: string,
    orgIdHeader?: string,
    hostName?: string,
    metric?: string,
    from?: string,
    to?: string
  ): Promise<{ host: string; rows: Array<Record<string, string | number>> }> {
    this.requireApiKey(apiKey);
    return this.zabbixMetricsService.getHostMetrics(orgIdHeader, hostName, metric, from, to);
  }

  async getZabbixHostStatus(
    apiKey?: string,
    orgIdHeader?: string,
    hostName?: string
  ): Promise<{
    host: string;
    status_summary: string | null;
    uptime_human: string | null;
    rows: Array<{ label: string; value: string | null }>;
  }> {
    this.requireApiKey(apiKey);
    return this.zabbixStatusService.getHostStatus(orgIdHeader, hostName);
  }

  async query(
    body: GrafanaQueryPayload,
    apiKey?: string,
    orgIdHeader?: string
  ): Promise<unknown> {
    this.requireApiKey(apiKey);
    return this.grafanaQueryService.query(body, orgIdHeader);
  }
}
