import React from 'react'

import { Badge, Group, HoverCard, Stack, Text } from '@tidbcloud/uikit'

import type { HealthcheckCheckItem } from '../types'

// ── Display name mapping ────────────────────────────────────────────
export const CHECK_ITEM_DISPLAY_NAMES: Record<string, string> = {
  metrics_healthcheck: 'Key Metrics Check',
  disk_check: 'Disk Anomaly Check',
  config_check: 'Config Change Check',
  slow_query_hugeResourceUsage: 'Extreme Slow Query',
  tablefullscan_slow_query: 'TableFullScan Slow Query',
  slowlog_top_digest: 'Slow Log Top Digest',
  sql_tikv_high_duration: 'SQL TiKV High Duration',
  sql_tikv_high_cpu: 'SQL TiKV High CPU'
}

// ── Description mapping ─────────────────────────────────────────────
export const CHECK_ITEM_DESCRIPTIONS: Record<string, string> = {
  metrics_healthcheck:
    'Compares current metrics against 14-day baseline to detect anomalies in CPU, memory, QPS, latency, and disk usage',
  disk_check:
    'Detects disk I/O anomalies such as latency spikes and EBS throughput/IOPS limit exceeded during the inspection time range',
  config_check:
    'Checks whether any configuration changes were made during the inspection time range',
  slow_query_hugeResourceUsage:
    'Detects slow queries with high memory usage or long execution time',
  tablefullscan_slow_query:
    'Detects SQL queries with `tablefullscan` operations that scan large amounts of rows',
  slowlog_top_digest:
    'Detects top slow log digests by selected aggregate dimensions',
  sql_tikv_high_duration:
    'Detects prominent TopSQL digests during TiKV coprocessor duration anomaly windows, with slow logs as enrichment',
  sql_tikv_high_cpu:
    'Detects prominent TopSQL digests during high or outlier TiKV CPU windows, with slow logs as enrichment'
}

// ── Full param definitions per check item (key → label + default) ───
const CHECK_ITEM_PARAMS: Record<
  string,
  {
    key: string
    label: string
    defaultValue: number | boolean | string | string[]
  }[]
> = {
  slow_query_hugeResourceUsage: [
    {
      key: 'memMaxThreshold',
      label: 'Memory Threshold (bytes)',
      defaultValue: 10 * 1024 * 1024 * 1024
    },
    {
      key: 'queryTimeThreshold',
      label: 'Query Time Threshold (s)',
      defaultValue: 5
    }
  ],
  tablefullscan_slow_query: [
    {
      key: 'scan_rows_threshold',
      label: 'Scan Rows Threshold',
      defaultValue: 10000
    },
    {
      key: 'topN',
      label: 'Top N',
      defaultValue: 100
    },
    { key: 'ignore_dml', label: 'Ignore DML', defaultValue: true },
    { key: 'ignore_tiflash', label: 'Ignore TiFlash', defaultValue: true },
    { key: 'sample_top_size', label: 'Sample Top Size', defaultValue: 5 }
  ],
  slowlog_top_digest: [
    {
      key: 'topN',
      label: 'Top N',
      defaultValue: 10
    },
    {
      key: 'dimensions',
      label: 'Top Dimensions',
      defaultValue: [
        'count',
        'total_latency',
        'total_keys',
        'process_keys',
        'request_count',
        'sum_ru'
      ]
    },
    {
      key: 'ignore_dml',
      label: 'Ignore DML',
      defaultValue: false
    },
    {
      key: 'min_count',
      label: 'Min Count',
      defaultValue: 0
    },
    {
      key: 'min_total_keys',
      label: 'Min Total Keys',
      defaultValue: 0
    }
  ],
  sql_tikv_high_duration: [
    {
      key: 'window_min_duration_seconds',
      label: 'Minimum Window Duration (s)',
      defaultValue: 180
    },
    {
      key: 'topsql_cpu_percent_threshold',
      label: 'Min TopSQL Share (%)',
      defaultValue: 10
    },
    {
      key: 'critical_window_duration_seconds',
      label: 'Critical Window Duration (s)',
      defaultValue: 600
    },
    {
      key: 'topsql_dominance_ratio_threshold',
      label: 'Dominance Ratio',
      defaultValue: 2
    },
    {
      key: 'duration_threshold_ms',
      label: 'Duration Alert Threshold (ms)',
      defaultValue: 1000
    },
    {
      key: 'critical_duration_threshold_ms',
      label: 'Critical Duration Threshold (ms)',
      defaultValue: 4000
    }
  ],
  sql_tikv_high_cpu: [
    {
      key: 'window_min_duration_seconds',
      label: 'Minimum Window Duration (s)',
      defaultValue: 180
    },
    {
      key: 'topsql_cpu_percent_threshold',
      label: 'Min TopSQL Share (%)',
      defaultValue: 10
    },
    {
      key: 'critical_window_duration_seconds',
      label: 'Critical Window Duration (s)',
      defaultValue: 600
    },
    {
      key: 'topsql_dominance_ratio_threshold',
      label: 'Dominance Ratio',
      defaultValue: 2
    },
    {
      key: 'absolute_cpu_threshold_percent',
      label: 'CPU Alert Threshold (%)',
      defaultValue: 75
    },
    {
      key: 'relative_cpu_delta_threshold_percent',
      label: 'Relative CPU Delta (%)',
      defaultValue: 10
    },
    {
      key: 'critical_cpu_threshold_percent',
      label: 'Critical CPU Threshold (%)',
      defaultValue: 85
    }
  ]
}

const DIMENSION_LABELS: Record<string, string> = {
  count: 'Count',
  total_latency: 'Total Latency',
  total_keys: 'SUM Total Keys',
  process_keys: 'SUM Process Keys',
  request_count: 'SUM Request Count',
  sum_ru: 'SUM RU'
}
const HOTSPOT_ITEM_NAMES = new Set([
  'sql_tikv_high_duration',
  'sql_tikv_high_cpu'
])
const HOTSPOT_PRIMARY_PARAM_ORDER = [
  'duration_threshold_ms',
  'critical_duration_threshold_ms',
  'absolute_cpu_threshold_percent',
  'relative_cpu_delta_threshold_percent',
  'critical_cpu_threshold_percent',
  'window_min_duration_seconds',
  'critical_window_duration_seconds',
  'topsql_cpu_percent_threshold',
  'topsql_dominance_ratio_threshold'
]
const HOTSPOT_PRIMARY_PARAM_KEYS = new Set(HOTSPOT_PRIMARY_PARAM_ORDER)

function getDisplayName(name?: string) {
  return CHECK_ITEM_DISPLAY_NAMES[name ?? ''] ?? name ?? 'Unknown'
}

function parseParams(
  params?: string | Record<string, unknown>
): Record<string, unknown> {
  if (!params) return {}
  if (typeof params === 'object') return params
  try {
    return JSON.parse(params)
  } catch {
    return {}
  }
}

function getFullParams(
  itemName: string,
  actual: Record<string, unknown>
): { key: string; label: string; value: unknown }[] {
  const defs = CHECK_ITEM_PARAMS[itemName]
  if (!defs) {
    // Fallback: show whatever the API returned
    return Object.entries(actual).map(([key, value]) => ({
      key,
      label: key,
      value
    }))
  }
  const visibleDefs = HOTSPOT_ITEM_NAMES.has(itemName)
    ? defs.filter((d) => HOTSPOT_PRIMARY_PARAM_KEYS.has(d.key))
    : defs
  const orderedDefs = HOTSPOT_ITEM_NAMES.has(itemName)
    ? [...visibleDefs].sort(
        (a, b) =>
          HOTSPOT_PRIMARY_PARAM_ORDER.indexOf(a.key) -
          HOTSPOT_PRIMARY_PARAM_ORDER.indexOf(b.key)
      )
    : visibleDefs
  return orderedDefs.map((d) => ({
    key: d.key,
    label: d.label,
    value: d.key in actual ? actual[d.key] : d.defaultValue
  }))
}

function formatParamValue(value: unknown): string {
  if (typeof value === 'boolean') return value ? 'Yes' : 'No'
  if (Array.isArray(value)) {
    return value
      .map((item) => DIMENSION_LABELS[String(item)] ?? item)
      .join(', ')
  }
  return String(value)
}

interface CheckItemBadgeProps {
  item: HealthcheckCheckItem
}

export const CheckItemBadge: React.FC<CheckItemBadgeProps> = ({ item }) => {
  const actual = parseParams(item.params)
  const allParams = getFullParams(item.name, actual)

  return (
    <HoverCard width={280} shadow='md' withArrow>
      <HoverCard.Target>
        <Badge size='sm' variant='outline' style={{ cursor: 'pointer' }}>
          {getDisplayName(item.name)}
        </Badge>
      </HoverCard.Target>
      <HoverCard.Dropdown>
        <Stack gap='xs' style={{ maxHeight: 520, overflowY: 'auto' }}>
          <Text size='sm' fw={500}>
            {getDisplayName(item.name)}
          </Text>
          {(item.description || CHECK_ITEM_DESCRIPTIONS[item.name]) && (
            <Text size='xs' c='dimmed'>
              {item.description || CHECK_ITEM_DESCRIPTIONS[item.name]}
            </Text>
          )}
          {allParams.length > 0 && (
            <>
              <Text size='xs' fw={500} mt={4}>
                Parameters
              </Text>
              {allParams.map((p) => (
                <Group key={p.key} justify='space-between' gap='xs'>
                  <Text size='xs' c='dimmed'>
                    {p.label}
                  </Text>
                  <Text size='xs' fw={500}>
                    {formatParamValue(p.value)}
                  </Text>
                </Group>
              ))}
            </>
          )}
        </Stack>
      </HoverCard.Dropdown>
    </HoverCard>
  )
}
