import {
  DASHBOARD_SCHEMA_VERSION,
  type DashboardDocument,
  type DatasourceReference,
  type MetricValue,
  type ServiceEntry,
  type ServiceGroup,
  type Severity,
  type TelemetryCard,
} from "@dimensionlab/dashboard-model";

type NumericValueKind = "percent" | "bytes" | "temperature" | "latency" | "number";

interface MetricSeed {
  id: string;
  label: string;
  icon: string;
  kind: NumericValueKind;
  value: number;
  detail: string;
  severity: Severity;
  datasource: DatasourceReference;
  thresholds?: TelemetryCard["thresholds"];
  sparkline?: number[];
  precision?: number;
}

interface ServiceSeed {
  id: string;
  label: string;
  description: string;
  icon: string;
  datasource: DatasourceReference;
  href?: string;
  severity?: Severity;
  detail?: string;
}

const REAL_FILESYSTEM_FILTER =
  'fstype!~"tmpfs|overlay|squashfs|nsfs|tracefs|autofs|proc|sysfs|cgroup2|devtmpfs|securityfs|debugfs|pstore|bpf|configfs|selinuxfs|mqueue|hugetlbfs|fusectl|ramfs"';
const USER_MOUNT_FILTER =
  'mountpoint=~"^/home($|/)|^/srv($|/)|^/data($|/)|^/mnt($|/)|^/media($|/)",mountpoint!~"^/(boot|boot/efi|efi|var|usr|opt|run|dev|proc|sys)($|/)"';
const SYSTEM_MOUNT_FILTER =
  'mountpoint=~"^/$|^/boot($|/)|^/boot/efi$|^/var($|/)|^/usr($|/)|^/opt($|/)",mountpoint!~"^/home($|/)|^/srv($|/)|^/data($|/)|^/mnt($|/)|^/media($|/)"';

const diskUsedQuery = (mountFilter: string) => {
  const selector = `job="node",${REAL_FILESYSTEM_FILTER},${mountFilter}`;
  return `topk(1, max by (host, mountpoint) (100 * (1 - node_filesystem_avail_bytes{${selector}} / node_filesystem_size_bytes{${selector}})))`;
};
const ramQuery = (host: string) =>
  `100 * (1 - node_memory_MemAvailable_bytes{job="node",host="${host}"} / node_memory_MemTotal_bytes{job="node",host="${host}"})`;
const gpuQuery = (name: string, metric: string) =>
  `${metric}{job="node",name=~".*${name}.*"}`;
const gpuVramQuery = (name: string) =>
  `100 * nvidia_gpu_memory_used_bytes{job="node",name=~".*${name}.*"} / nvidia_gpu_memory_total_bytes{job="node",name=~".*${name}.*"}`;
const hostCpuQuery =
  'topk(1, 100 * (1 - avg by (host) (rate(node_cpu_seconds_total{job="node",mode="idle"}[5m]))))';
const topCpuQuery =
  'topk(1, 100 * rate(podman_container_cpu_seconds_total{job=~"podman-.*"}[5m]) * on(host,id) group_left(name) podman_container_info{job=~"podman-.*"})';
const topRamQuery =
  'topk(1, podman_container_mem_usage_bytes{job=~"podman-.*"} * on(host,id) group_left(name) podman_container_info{job=~"podman-.*"})';

export const dimensionLabDashboardFixture: DashboardDocument = {
  schemaVersion: DASHBOARD_SCHEMA_VERSION,
  metadata: {
    title: "System Overview",
    subtitle: "Capacity, noise & top consumers",
    description:
      "Initial Dimension Lab dashboard seed data. Runtime values are fallback values until datasource adapters are enabled.",
    timezone: "Europe/Amsterdam",
    refreshIntervalSeconds: 15,
  },
  layout: {
    density: "dense",
    telemetry: [
      "infra-ram",
      "gpu-host-ram",
      "network-ram",
      "user-disk-peak",
      "system-disk-peak",
      "peak-cpu-busy",
      "top-cpu-container",
      "top-ram-container",
      "gpu-3060-load",
      "gpu-3060-vram",
      "gpu-3060-temp",
      "gpu-3060-fan",
      "gpu-3090-load",
      "gpu-3090-vram",
      "gpu-3090-temp",
      "gpu-3090-fan",
    ],
    serviceGroups: ["essentials", "monitoring", "ai-automation", "systems", "runtime-health"],
    statusStrips: ["footer-status"],
    modules: ["weather-amsterdam", "runtime-health-summary"],
  },
  telemetry: [
    metric({
      id: "infra-ram",
      label: "Infra RAM",
      icon: "mdi:memory",
      kind: "percent",
      value: 19,
      detail: "fallback - linux-infra memory used",
      severity: "ok",
      thresholds: percentThresholds(),
      datasource: prometheus(
        ramQuery("linux-infra"),
      ),
      sparkline: [18, 18, 19, 19, 18, 19],
    }),
    metric({
      id: "gpu-host-ram",
      label: "GPU Host RAM",
      icon: "mdi:memory",
      kind: "percent",
      value: 17,
      detail: "fallback - GPU host memory used",
      severity: "ok",
      thresholds: percentThresholds(),
      datasource: prometheus(
        ramQuery("linux"),
      ),
      sparkline: [16, 16, 17, 17, 17, 17],
    }),
    metric({
      id: "network-ram",
      label: "Network RAM",
      icon: "mdi:router-network",
      kind: "percent",
      value: 5,
      detail: "fallback - network core memory used",
      severity: "ok",
      thresholds: percentThresholds(),
      datasource: prometheus(
        ramQuery("network-core"),
      ),
      sparkline: [5, 5, 5, 6, 5, 5],
    }),
    metric({
      id: "user-disk-peak",
      label: "User Disk Peak",
      icon: "mdi:harddisk",
      kind: "percent",
      value: 29,
      detail: "fallback - /home peak usage",
      severity: "ok",
      thresholds: percentThresholds(80, 92),
      datasource: prometheus(
        diskUsedQuery(USER_MOUNT_FILTER),
      ),
      sparkline: [27, 27, 28, 29, 29, 29],
    }),
    metric({
      id: "system-disk-peak",
      label: "System Disk Peak",
      icon: "mdi:harddisk",
      kind: "percent",
      value: 49,
      detail: "fallback - /boot peak usage",
      severity: "ok",
      thresholds: percentThresholds(80, 92),
      datasource: prometheus(
        diskUsedQuery(SYSTEM_MOUNT_FILTER),
      ),
      sparkline: [48, 48, 49, 49, 49, 49],
    }),
    metric({
      id: "peak-cpu-busy",
      label: "Peak CPU Busy",
      icon: "mdi:cpu-64-bit",
      kind: "percent",
      value: 3,
      detail: "fallback - linux-infra 5m CPU busy",
      severity: "ok",
      thresholds: percentThresholds(75, 90),
      datasource: prometheus(
        hostCpuQuery,
      ),
      sparkline: [2, 3, 3, 4, 3, 3],
    }),
    metric({
      id: "top-cpu-container",
      label: "Top CPU Container",
      icon: "mdi:docker",
      kind: "percent",
      value: 7.9,
      precision: 1,
      detail: "fallback - top container CPU pending label mapping",
      severity: "ok",
      thresholds: percentThresholds(70, 90),
      datasource: prometheus(topCpuQuery),
      sparkline: [6.1, 6.4, 7.0, 7.5, 7.2, 7.9],
    }),
    metric({
      id: "top-ram-container",
      label: "Top RAM Container",
      icon: "mdi:docker",
      kind: "bytes",
      value: Math.round(5.2 * 1024 ** 3),
      precision: 1,
      detail: "fallback - top container RAM pending label mapping",
      severity: "danger",
      thresholds: { warning: 3 * 1024 ** 3, danger: 5 * 1024 ** 3 },
      datasource: prometheus(topRamQuery),
      sparkline: [
        3.1 * 1024 ** 3,
        3.5 * 1024 ** 3,
        4.1 * 1024 ** 3,
        4.8 * 1024 ** 3,
        5.0 * 1024 ** 3,
        5.2 * 1024 ** 3,
      ],
    }),
    metric({
      id: "gpu-3060-load",
      label: "3060 GPU Load",
      icon: "mdi:expansion-card",
      kind: "percent",
      value: 0,
      detail: "fallback - RTX 3060 GPU utilization",
      severity: "ok",
      thresholds: percentThresholds(85, 95),
      datasource: prometheus(gpuQuery("3060", "nvidia_gpu_utilization_percent")),
      sparkline: [0, 0, 0, 0, 0, 0],
    }),
    metric({
      id: "gpu-3060-vram",
      label: "3060 VRAM",
      icon: "mdi:memory",
      kind: "percent",
      value: 0,
      detail: "fallback - RTX 3060 VRAM used",
      severity: "ok",
      thresholds: percentThresholds(80, 92),
      datasource: prometheus(
        gpuVramQuery("3060"),
      ),
      sparkline: [0, 0, 0, 0, 0, 0],
    }),
    metric({
      id: "gpu-3060-temp",
      label: "3060 Temp",
      icon: "mdi:thermometer",
      kind: "temperature",
      value: 54,
      detail: "fallback - RTX 3060 temperature",
      severity: "ok",
      thresholds: { warning: 75, danger: 85 },
      datasource: prometheus(gpuQuery("3060", "nvidia_gpu_temperature_celsius")),
      sparkline: [52, 53, 54, 54, 53, 54],
    }),
    metric({
      id: "gpu-3060-fan",
      label: "3060 Fan Spin",
      icon: "mdi:fan",
      kind: "percent",
      value: 0,
      detail: "fallback - RTX 3060 fan duty",
      severity: "ok",
      thresholds: percentThresholds(80, 95),
      datasource: prometheus(gpuQuery("3060", "nvidia_gpu_fan_speed_percent")),
      sparkline: [0, 0, 0, 0, 0, 0],
    }),
    metric({
      id: "gpu-3090-load",
      label: "3090 GPU Load",
      icon: "mdi:expansion-card",
      kind: "percent",
      value: 0,
      detail: "fallback - RTX 3090 GPU utilization",
      severity: "ok",
      thresholds: percentThresholds(85, 95),
      datasource: prometheus(gpuQuery("3090", "nvidia_gpu_utilization_percent")),
      sparkline: [0, 0, 0, 0, 0, 0],
    }),
    metric({
      id: "gpu-3090-vram",
      label: "3090 VRAM",
      icon: "mdi:memory",
      kind: "percent",
      value: 74,
      detail: "fallback - RTX 3090 VRAM used",
      severity: "warning",
      thresholds: percentThresholds(70, 90),
      datasource: prometheus(
        gpuVramQuery("3090"),
      ),
      sparkline: [68, 70, 72, 74, 73, 74],
    }),
    metric({
      id: "gpu-3090-temp",
      label: "3090 Temp",
      icon: "mdi:thermometer",
      kind: "temperature",
      value: 50,
      detail: "fallback - RTX 3090 temperature",
      severity: "ok",
      thresholds: { warning: 75, danger: 85 },
      datasource: prometheus(gpuQuery("3090", "nvidia_gpu_temperature_celsius")),
      sparkline: [49, 50, 50, 51, 50, 50],
    }),
    metric({
      id: "gpu-3090-fan",
      label: "3090 Fan Spin",
      icon: "mdi:fan",
      kind: "percent",
      value: 0,
      detail: "fallback - RTX 3090 fan duty",
      severity: "ok",
      thresholds: percentThresholds(80, 95),
      datasource: prometheus(gpuQuery("3090", "nvidia_gpu_fan_speed_percent")),
      sparkline: [0, 0, 0, 0, 0, 0],
    }),
  ],
  serviceGroups: [
    group("essentials", "Essentials", [
      service({
        id: "vaultwarden",
        label: "Vaultwarden",
        description: "Password manager",
        icon: "simple-icons:vaultwarden",
        href: "https://vault.dimensionlab.net",
        datasource: uptimeMonitor(1),
      }),
      service({
        id: "forgejo",
        label: "Forgejo",
        description: "Git repositories",
        icon: "simple-icons:forgejo",
        href: "https://git.dimensionlab.net",
        datasource: uptimeMonitor(2),
      }),
      service({
        id: "wiki",
        label: "Wiki",
        description: "Internal documentation",
        icon: "simple-icons:wikidotjs",
        href: "https://wiki.dimensionlab.net",
        datasource: uptimeMonitor(3),
      }),
      service({
        id: "aws-start",
        label: "AWS Start",
        description: "AWS access portal",
        icon: "simple-icons:amazonwebservices",
        href: "https://dimensionlab.awsapps.com/start",
        datasource: uptimeMonitor(21),
      }),
      service({
        id: "adguard-primary",
        label: "AdGuard Primary",
        description: "DNS filtering and DHCP",
        icon: "simple-icons:adguard",
        href: "https://control.dimensionlab.net",
        datasource: uptimeMonitor(14),
      }),
      service({
        id: "adguard-secondary",
        label: "AdGuard Secondary",
        description: "Fallback DNS",
        icon: "simple-icons:adguard",
        href: "https://control-secondary.dimensionlab.net",
        datasource: uptimeMonitor(18),
      }),
    ]),
    group("monitoring", "Monitoring", [
      service({
        id: "grafana",
        label: "Grafana",
        description: "Capacity and noise dashboard",
        icon: "simple-icons:grafana",
        href: "https://grafana.dimensionlab.net",
        datasource: uptimeMonitor(11),
      }),
      service({
        id: "uptime-kuma",
        label: "Uptime Kuma",
        description: "Service uptime checks",
        icon: "simple-icons:uptimekuma",
        href: "https://uptime.dimensionlab.net",
        datasource: uptimeMonitor(10),
      }),
      service({
        id: "prometheus",
        label: "Prometheus",
        description: "Metrics database",
        icon: "simple-icons:prometheus",
        href: "https://prometheus.dimensionlab.net",
        datasource: uptimeMonitor(12),
      }),
      service({
        id: "backrest",
        label: "Backrest",
        description: "Restic backup manager",
        icon: "mdi:backup-restore",
        href: "https://backups.dimensionlab.net",
        datasource: uptimeMonitor(13),
      }),
    ]),
    group("ai-automation", "AI & Automation", [
      service({
        id: "n8n",
        label: "n8n",
        description: "Workflow automation",
        icon: "simple-icons:n8n",
        href: "https://workflows.dimensionlab.net",
        datasource: uptimeMonitor(4),
      }),
      service({
        id: "open-webui",
        label: "Open WebUI",
        description: "Chat and model interface",
        icon: "mdi:web",
        href: "https://webui.dimensionlab.net",
        datasource: uptimeMonitor(5),
      }),
      service({
        id: "comfyui",
        label: "ComfyUI",
        description: "Image generation workflows",
        icon: "mdi:image-edit-outline",
        href: "https://comfy.dimensionlab.net",
        datasource: uptimeMonitor(6),
      }),
      service({
        id: "models",
        label: "Models",
        description: "Local model management",
        icon: "mdi:brain",
        href: "https://models.dimensionlab.net",
        datasource: uptimeMonitor(7),
      }),
      service({
        id: "prompt-registry",
        label: "Prompt Registry",
        description: "Shared prompts, traces, evals",
        icon: "mdi:text-box-search",
        href: "https://prompts.dimensionlab.net",
        datasource: uptimeMonitor(20),
      }),
    ]),
    group("systems", "Systems", [
      service({
        id: "adminer",
        label: "Adminer",
        description: "PostgreSQL database browser",
        icon: "simple-icons:adminer",
        href: "https://db.dimensionlab.net",
        datasource: uptimeMonitor(17),
      }),
      service({
        id: "assistant",
        label: "Assistant",
        description: "Personal AI agent gateway",
        icon: "mdi:robot-outline",
        href: "https://assistant.dimensionlab.net",
        datasource: uptimeMonitor(8),
      }),
      service({
        id: "suna",
        label: "Suna",
        description: "AI command center",
        icon: "mdi:account-hard-hat-outline",
        href: "https://suna.dimensionlab.net",
        datasource: uptimeMonitor(9),
      }),
      service({
        id: "cockpit-infra",
        label: "Cockpit Infra",
        description: "linux-infra server console",
        icon: "simple-icons:cockpit",
        href: "https://infra-cockpit.dimensionlab.net",
        datasource: uptimeMonitor(15),
      }),
      service({
        id: "cockpit-gpu",
        label: "Cockpit GPU",
        description: "Linux GPU server console",
        icon: "simple-icons:cockpit",
        href: "https://linux-cockpit.dimensionlab.net",
        datasource: uptimeMonitor(16),
      }),
      service({
        id: "cockpit-network-core",
        label: "Cockpit Network Core",
        description: "i3 NUC DNS/DHCP console",
        icon: "simple-icons:cockpit",
        href: "https://network-core.dimensionlab.net",
        datasource: uptimeMonitor(19),
      }),
    ]),
    group("runtime-health", "Runtime Health", [
      service({
        id: "forgejo-ssh-relay",
        label: "Forgejo SSH Relay",
        description: "Public Git SSH relay",
        icon: "simple-icons:forgejo",
        href: "https://uptime.dimensionlab.net/status/dimensionlab",
        datasource: uptimeMonitor(28),
        detail: "fallback - uptime monitor pending",
      }),
      service({
        id: "postgresql",
        label: "PostgreSQL",
        description: "Shared application database",
        icon: "simple-icons:postgresql",
        datasource: uptimeMonitor(22),
        detail: "fallback - postgres exporter pending",
      }),
      service({
        id: "ollama-api",
        label: "Ollama API",
        description: "Local model API",
        icon: "simple-icons:ollama",
        datasource: uptimeMonitor(23),
        detail: "fallback - internal health check pending",
      }),
      service({
        id: "node-exporter",
        label: "Node Exporter",
        description: "Host metrics exporter",
        icon: "simple-icons:prometheus",
        datasource: uptimeMonitor(24),
        detail: "fallback - exporter health from Uptime Kuma",
      }),
      service({
        id: "podman-user-exporter",
        label: "Podman User Exporter",
        description: "Rootless container metrics",
        icon: "simple-icons:prometheus",
        datasource: uptimeMonitor(25),
        detail: "fallback - exporter health from Uptime Kuma",
      }),
      service({
        id: "podman-system-exporter",
        label: "Podman System Exporter",
        description: "System container metrics",
        icon: "simple-icons:prometheus",
        datasource: uptimeMonitor(26),
        detail: "fallback - exporter health from Uptime Kuma",
      }),
      service({
        id: "network-core-node-exporter",
        label: "Network Core Node Exporter",
        description: "i3 DNS/DHCP metrics",
        icon: "simple-icons:prometheus",
        datasource: uptimeMonitor(27),
        detail: "fallback - exporter health from Prometheus",
      }),
    ], "grid"),
  ],
  statusStrips: [
    {
      id: "footer-status",
      items: [
        { id: "system-status", label: "System Status", value: "Fallback operational", severity: "ok" },
        { id: "last-sync", label: "Last Sync", value: "fallback: 2 minutes ago", severity: "stale" },
        { id: "uptime", label: "Uptime", value: "fallback: 28d 14h 32m", severity: "ok" },
        { id: "load-avg", label: "Load Avg", value: "fallback: 0.47 0.53 0.59", severity: "neutral" },
        { id: "auto-refresh", label: "Auto Refresh", value: "fallback: 15s", severity: "neutral" },
      ],
    },
  ],
  modules: [
    {
      id: "weather-amsterdam",
      kind: "weather",
      title: "Amsterdam",
      value: "28.3 C",
      detail: "fallback - weather adapter pending",
      icon: "mdi:weather-sunny",
      severity: "ok",
      datasource: {
        type: "external",
        adapter: "weather",
        reference: "open-meteo:latitude=52.3676&longitude=4.9041",
      },
    },
    {
      id: "runtime-health-summary",
      kind: "summary",
      title: "Runtime Health",
      value: "fallback",
      detail: "fallback - health adapters pending",
      icon: "mdi:pulse",
      severity: "stale",
      datasource: placeholder("summary pending live health aggregation"),
    },
  ],
};

function metric(seed: MetricSeed): TelemetryCard {
  return {
    id: seed.id,
    label: seed.label,
    icon: seed.icon,
    value: metricValue(seed.kind, seed.value, seed.precision),
    detail: seed.detail,
    severity: seed.severity,
    thresholds: seed.thresholds,
    datasource: seed.datasource,
    sparkline: seed.sparkline,
  };
}

function metricValue(
  kind: NumericValueKind,
  value: number,
  precision?: number,
): MetricValue {
  return precision === undefined ? { kind, value } : { kind, value, precision };
}

function service(seed: ServiceSeed): ServiceEntry {
  const entry: ServiceEntry = {
    id: seed.id,
    label: seed.label,
    description: seed.description,
    icon: seed.icon,
    severity: seed.severity || "ok",
    detail: seed.detail || "fallback - health check pending",
    datasource: seed.datasource,
  };

  if (!seed.href) return entry;

  return {
    ...entry,
    link: {
      href: seed.href,
      label: `Open ${seed.label}`,
      external: true,
    },
  };
}

function group(
  id: string,
  title: string,
  services: ServiceEntry[],
  layout: ServiceGroup["layout"] = "list",
): ServiceGroup {
  return {
    id,
    layout,
    services,
    title,
  };
}

function percentThresholds(warning = 80, danger = 92) {
  return { warning, danger };
}

function prometheus(reference: string): DatasourceReference {
  return {
    type: "external",
    adapter: "prometheus",
    reference,
  };
}

function httpStatus(url: string): DatasourceReference {
  return {
    type: "external",
    adapter: "http-status",
    reference: `GET ${url}`,
  };
}

function placeholder(reason: string): DatasourceReference {
  return {
    type: "placeholder",
    reason,
  };
}

function uptimeMonitor(id: number): DatasourceReference {
  return httpStatus(`https://uptime.dimensionlab.net/_homepage-badge/${id}`);
}
