// Server-only monitor types (internal representation with all fields).

import type { PingHost, PingMonitorTypeData } from "$lib/types/ping.js";
import type { TcpHost, TcpMonitorTypeData } from "$lib/types/tcp.js";

export interface MonitoringResult {
  status: string;
  latency: number;
  type: string;
  error_message?: string;
  raw_status?: string;
}

export interface MonitoringResultTS {
  [timestamp: number]: MonitoringResult;
}

export interface NoneMonitorTypeData {
  overrideWithLastKnownStatus: boolean;
}
export interface ApiMonitorTypeData {
  url: string;
  body?: string;
  headers?: Array<{ key: string; value: string }>;
  method: string;
  timeout?: number;
  eval?: string;
  allowSelfSignedCert?: boolean;
  follow_redirects?: boolean;
  max_redirects?: number;
}

export interface DnsMonitorTypeData {
  nameServer: string;
  host: string;
  lookupRecord: string;
  matchType: "ALL" | "ANY";
  values: string[];
  transport?: "UDP" | "TLS";
  tlsPort?: number;
  tlsServername?: string;
  allowSelfSignedCert?: boolean;
}

export type { PingHost, PingMonitorTypeData };
export type { TcpHost, TcpMonitorTypeData };

export interface SslMonitorTypeData {
  host: string;
  port?: string;
  degradedRemainingHours: number;
  downRemainingHours: number;
}

export interface SqlMonitorTypeData {
  dbType: string;
  connectionString: string;
  query: string;
  timeout?: number;
}

export interface HeartbeatMonitorTypeData {
  downRemainingMinutes: number;
  degradedRemainingMinutes: number;
  secretString: string;
}

export interface GroupMonitorMember {
  tag: string;
  /** Weight for this monitor. All weights in a group must sum to 1. */
  weight: number;
}

export interface GroupMonitorTypeData extends Record<string, unknown> {
  monitors: GroupMonitorMember[];
  executionDelay: number;
  latencyCalculation: "AVG" | "MAX" | "MIN";
}

export interface GamedigMonitorTypeData {
  gameId: string;
  host: string;
  port: number;
  timeout?: number;
  eval?: string;
  guessPort?: boolean;
  requestRules?: boolean;
}

export interface GrpcMonitorTypeData {
  host: string;
  port: number;
  service?: string;
  tls?: boolean;
  insecure?: boolean;
  timeout?: number;
}

export type MonitorTypeData =
  | ApiMonitorTypeData
  | DnsMonitorTypeData
  | PingMonitorTypeData
  | TcpMonitorTypeData
  | SslMonitorTypeData
  | SqlMonitorTypeData
  | HeartbeatMonitorTypeData
  | GroupMonitorTypeData
  | GamedigMonitorTypeData
  | GrpcMonitorTypeData;

export interface Monitor<T = MonitorTypeData> {
  tag: string;
  type_data: T;
  cron?: string;
}

export type NoneMonitor = Monitor<NoneMonitorTypeData>;
export type ApiMonitor = Monitor<ApiMonitorTypeData>;
export type DnsMonitor = Monitor<DnsMonitorTypeData>;
export type PingMonitor = Monitor<PingMonitorTypeData>;
export type TcpMonitor = Monitor<TcpMonitorTypeData>;
export type SslMonitor = Monitor<SslMonitorTypeData>;
export type SqlMonitor = Monitor<SqlMonitorTypeData>;
export type HeartbeatMonitor = Monitor<HeartbeatMonitorTypeData>;
export type GroupMonitor = Monitor<GroupMonitorTypeData>;
export type GamedigMonitor = Monitor<GamedigMonitorTypeData>;
export type GrpcMonitor = Monitor<GrpcMonitorTypeData>;

export interface EvalResponse {
  status?: string;
  latency?: number;
  type?: string;
}
