'use client';

import {
  Stack, Text, Title, Badge, Group, Card, Box, Tabs,
  ActionIcon, Tooltip, Divider, ScrollArea,
} from '@tidbcloud/uikit';
import { LinkOutlined } from '@ant-design/icons';
import { useTranslation, type TranslationKey } from '@/lib/i18n';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface EvidenceMetric {
  name: string;
  instance?: string;
  value?: string;
  peak?: number;
  mean?: number;
  quota?: number;
  utilization?: string;
  unit?: string;
  severity?: string;
  link?: string;
}

interface EvidenceQuery {
  source?: string;
  digest?: string;
  sql_preview?: string;
  cpu_pct?: number;
  exec_count?: number | string;
  avg_time?: string;
  max_time?: string;
  max_mem?: number | string;
  link?: string;
}

interface EvidenceLog {
  level?: string;
  component?: string;
  instance?: string;
  message?: string;
  count?: number;
  link?: string;
  timestamp?: string | number;
}

interface Recommendation {
  priority?: number;
  action?: string;
  reason?: string;
}

interface AuthoredEvidenceItem {
  type: 'metric' | 'query' | 'topsql' | 'slow_query' | 'log' | 'event' | 'trace' | 'profile' | 'config' | 'file';
  source?: string;
  name?: string;
  digest?: string;
  instance?: string;
  metric_ref?: {
    metric_group_id?: string;
    instances?: string[];
  };
  reason?: string;
  link?: string;
}

interface DiagnosisData {
  type: string;
  metadata?: {
    cluster_id?: string;
    time_range?: { start: string; end: string };
    created_at?: string;
  };
  evidence?: {
    metrics?: EvidenceMetric[];
    queries?: EvidenceQuery[];
    logs?: EvidenceLog[];
    events?: unknown[];
  };
  gate_checks?: {
    infra?: string;
    hotspot?: string;
  };
  analysis?: {
    root_cause?: string;
    evidence_chain?: string[];
    causality?: string;
    severity?: string;
    key_evidence?: AuthoredEvidenceItem[];
    supporting_evidence?: AuthoredEvidenceItem[];
    recommendations?: Recommendation[];
  };
  links?: {
    clinic_overview?: string;
    slow_queries?: string;
    logs?: string;
    topsql?: string;
  };
}

interface DiagnosisReportProps {
  data: DiagnosisData;
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

const SEVERITY_COLOR: Record<string, string> = {
  critical: 'red',
  high: 'orange',
  medium: 'yellow',
  low: 'green',
};

const SEVERITY_BG: Record<string, string> = {
  critical: '#fef2f2',
  high: '#fff7ed',
  medium: '#fefce8',
  low: '#f0fdf4',
};

function severityBadge(severity?: string) {
  if (!severity) return null;
  const color = SEVERITY_COLOR[severity.toLowerCase()] || 'gray';
  return <Badge color={color} size="lg" variant="filled" c="white">{severity.toUpperCase()}</Badge>;
}

function LinkIcon({ url, label }: { url?: string; label: string }) {
  if (!url) return null;
  return (
    <Tooltip label={label}>
      <ActionIcon
        component="a"
        href={url}
        target="_blank"
        rel="noopener noreferrer"
        variant="subtle"
        size="sm"
        style={{ marginLeft: 4 }}
      >
        <LinkOutlined />
      </ActionIcon>
    </Tooltip>
  );
}

function truncate(s: string | undefined, max: number) {
  if (!s) return '';
  return s.length > max ? s.slice(0, max) + '...' : s;
}

// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------

function RootCauseSection({ analysis }: { analysis: DiagnosisData['analysis'] }) {
  const { t } = useTranslation();
  if (!analysis) return null;
  const sev = analysis.severity?.toLowerCase() || 'medium';
  const bg = SEVERITY_BG[sev] || '#f9fafb';

  return (
    <Card withBorder shadow="xs" p="md" style={{ backgroundColor: bg }}>
      <Stack gap="sm">
        <Group justify="space-between">
          <Text fw={600} size="sm">{t('diagnosis.rootCause')}</Text>
          {severityBadge(analysis.severity)}
        </Group>
        <Text size="sm" c="carbon.9">{analysis.root_cause}</Text>

        {analysis.causality && (
          <Box mt="xs">
            <Text size="xs" c="carbon.6" fw={500}>{t('diagnosis.causalityChain')}</Text>
            <Text size="sm" c="carbon.8" style={{ fontFamily: 'monospace', lineHeight: 1.8 }}>
              {analysis.causality}
            </Text>
          </Box>
        )}

        {analysis.evidence_chain && analysis.evidence_chain.length > 0 && (
          <Box mt="xs">
            <Text size="xs" c="carbon.6" fw={500}>{t('diagnosis.evidenceChain')}</Text>
            {analysis.evidence_chain.map((step, i) => (
              <Text key={i} size="xs" c="carbon.7" ml="xs" style={{ lineHeight: 1.6 }}>
                {i + 1}. {step}
              </Text>
            ))}
          </Box>
        )}
      </Stack>
    </Card>
  );
}

function MetricsSection({ metrics }: { metrics?: EvidenceMetric[] }) {
  const { t } = useTranslation();
  if (!metrics || metrics.length === 0) return <Text size="sm" c="carbon.6">{t('diagnosis.noMetrics')}</Text>;

  return (
    <Stack gap="xs">
      {metrics.map((m, i) => {
        const sev = m.severity?.toLowerCase();
        const bg = sev === 'critical' ? '#fef2f2' : sev === 'warning' ? '#fff7ed' : '#fff';
        return (
          <Card key={i} withBorder p="xs" style={{ backgroundColor: bg }}>
            <Group justify="space-between" wrap="nowrap">
              <Box style={{ flex: 1, minWidth: 0 }}>
                <Group gap="xs" wrap="nowrap">
                  <Text size="xs" fw={600} c="carbon.8">{m.name}</Text>
                  {m.instance && <Text size="xs" c="carbon.6">[{truncate(m.instance, 30)}]</Text>}
                </Group>
                <Text size="xs" c="carbon.7" style={{ fontFamily: 'monospace' }}>
                  {m.value || `${m.peak ?? ''}${m.unit ? ` ${m.unit}` : ''}${m.utilization ? ` (${m.utilization})` : ''}`}
                  {m.quota ? ` / ${m.quota} cores` : ''}
                </Text>
              </Box>
            </Group>
          </Card>
        );
      })}
    </Stack>
  );
}

function QueriesSection({ queries }: { queries?: EvidenceQuery[] }) {
  const { t } = useTranslation();
  if (!queries || queries.length === 0) return <Text size="sm" c="carbon.6">{t('diagnosis.noQueries')}</Text>;

  const openLabel = t('diagnosis.openInClinic');
  return (
    <Stack gap="xs">
      {queries.map((q, i) => (
        <Card key={i} withBorder p="xs">
          <Group justify="space-between" wrap="nowrap">
            <Box style={{ flex: 1, minWidth: 0 }}>
              {q.cpu_pct != null && (
                <Badge size="sm" color={q.cpu_pct > 20 ? 'red' : q.cpu_pct > 5 ? 'orange' : 'gray'} variant="light">
                  CPU {q.cpu_pct}%
                </Badge>
              )}
              <Text size="xs" c="carbon.7" mt={4} style={{ fontFamily: 'monospace', wordBreak: 'break-all' }}>
                {truncate(q.sql_preview, 150)}
              </Text>
              <Group gap="md" mt={4}>
                {q.exec_count != null && <Text size="xs" c="carbon.6">exec: {q.exec_count}</Text>}
                {q.avg_time && <Text size="xs" c="carbon.6">avg: {q.avg_time}</Text>}
                {q.max_time && <Text size="xs" c="carbon.6">max: {q.max_time}</Text>}
              </Group>
            </Box>
            <LinkIcon url={q.link} label={openLabel} />
          </Group>
        </Card>
      ))}
    </Stack>
  );
}

function LogsSection({ logs }: { logs?: EvidenceLog[] }) {
  const { t } = useTranslation();
  if (!logs || logs.length === 0) return <Text size="sm" c="carbon.6">{t('diagnosis.noLogs')}</Text>;

  const openLabel = t('diagnosis.openInClinic');
  return (
    <Stack gap="xs">
      {logs.map((log, i) => {
        const levelColor = log.level === 'ERROR' || log.level === 'FATAL' ? 'red' : 'orange';
        return (
          <Card key={i} withBorder p="xs" style={{ backgroundColor: levelColor === 'red' ? '#fef2f2' : '#fff7ed' }}>
            <Group justify="space-between" wrap="nowrap">
              <Box style={{ flex: 1, minWidth: 0 }}>
                <Group gap="xs" wrap="nowrap">
                  <Badge size="sm" color={levelColor} variant="filled" c="white">{log.level}</Badge>
                  {log.component && <Text size="xs" fw={500}>{log.component}</Text>}
                  {log.instance && <Text size="xs" c="carbon.6">[{truncate(log.instance, 25)}]</Text>}
                  {log.count != null && log.count > 1 && <Text size="xs" c="carbon.5">x{log.count}</Text>}
                </Group>
                <Text size="xs" c="carbon.7" mt={4} style={{ fontFamily: 'monospace', wordBreak: 'break-all' }}>
                  {truncate(log.message, 200)}
                </Text>
              </Box>
              <LinkIcon url={log.link} label={openLabel} />
            </Group>
          </Card>
        );
      })}
    </Stack>
  );
}

function evidenceTitle(item: AuthoredEvidenceItem) {
  return item.name || item.digest || item.type;
}

type EvidenceLabelKind = 'topsql' | 'slow_query' | 'query';

function evidenceTypeLabel(item: AuthoredEvidenceItem, t: (key: TranslationKey) => string): string {
  const kind = evidenceTypeKind(item);
  if (kind === 'topsql') return t('diagnosis.typeTopSql');
  if (kind === 'slow_query') return t('diagnosis.typeSlowQuery');
  if (kind === 'query') return t('diagnosis.typeQuery');
  return item.type;
}

function evidenceTypeKind(item: AuthoredEvidenceItem): EvidenceLabelKind | null {
  const rawType = String(item.type || '').toLowerCase();
  if (rawType === 'topsql') return 'topsql';
  if (rawType === 'slow_query' || rawType === 'slow-query') return 'slow_query';
  if (rawType !== 'query') return null;

  const rawSource = String(item.source || '').toLowerCase();
  if (rawSource === 'topsql') return 'topsql';
  if (rawSource === 'slow_query' || rawSource === 'slow-query') return 'slow_query';

  const hint = [item.link, item.name, item.reason].filter(Boolean).join(' ').toLowerCase();
  if (hint.includes('topsql') || hint.includes('top sql')) return 'topsql';
  if (hint.includes('slow_query') || hint.includes('slow query') || hint.includes('slow-query')) return 'slow_query';
  return 'query';
}

function evidenceTypeColor(kind: EvidenceLabelKind | null): string {
  if (kind === 'topsql') return 'grape';
  if (kind === 'slow_query') return 'violet';
  return 'blue';
}

function AuthoredEvidenceCard({ item }: { item: AuthoredEvidenceItem }) {
  const { t } = useTranslation();
  const kind = evidenceTypeKind(item);
  const typeLabel = evidenceTypeLabel(item, t);
  const showLink = item.type !== 'metric';
  return (
    <Card withBorder p="xs">
      <Group justify="space-between" wrap="nowrap" align="flex-start">
        <Box style={{ flex: 1, minWidth: 0 }}>
          <Group gap="xs" wrap="nowrap">
            <Badge size="sm" variant="light" color={evidenceTypeColor(kind) as any}>{typeLabel}</Badge>
            <Text size="xs" fw={600} c="carbon.8" style={{ wordBreak: 'break-word' }}>
              {evidenceTitle(item)}
            </Text>
            {item.instance && <Text size="xs" c="carbon.6">[{truncate(item.instance, 30)}]</Text>}
          </Group>
          {item.reason && (
            <Text size="xs" c="carbon.7" mt={4} style={{ lineHeight: 1.5 }}>
              {item.reason}
            </Text>
          )}
        </Box>
        {showLink && <LinkIcon url={item.link} label={t('diagnosis.openInClinic')} />}
      </Group>
    </Card>
  );
}

function AuthoredEvidenceGroup({ title, items }: { title: string; items?: AuthoredEvidenceItem[] }) {
  const { t } = useTranslation();
  return (
    <Box>
      <Group gap="xs" mb="xs">
        <Text fw={600} size="sm">{title}</Text>
        <Badge size="sm" variant="light">{items?.length || 0}</Badge>
      </Group>
      {items && items.length > 0 ? (
        <Stack gap="xs">
          {items.map((item, i) => (
            <AuthoredEvidenceCard key={`${item.type}-${item.name || item.digest || i}-${i}`} item={item} />
          ))}
        </Stack>
      ) : (
        <Text size="sm" c="carbon.6">{t('diagnosis.noEvidence')}</Text>
      )}
    </Box>
  );
}

function AuthoredEvidenceSection({ analysis }: { analysis?: DiagnosisData['analysis'] }) {
  const { t } = useTranslation();
  const hasAuthoredGroups = Array.isArray(analysis?.key_evidence)
    || Array.isArray(analysis?.supporting_evidence);
  if (!hasAuthoredGroups) return null;

  return (
    <Card withBorder shadow="xs" p="md">
      <Stack gap="md">
        <AuthoredEvidenceGroup title={t('diagnosis.keyEvidence')} items={analysis?.key_evidence} />
        <Divider />
        <AuthoredEvidenceGroup title={t('diagnosis.supportingEvidence')} items={analysis?.supporting_evidence} />
      </Stack>
    </Card>
  );
}

function RecommendationsSection({ recommendations }: { recommendations?: Recommendation[] }) {
  const { t } = useTranslation();
  if (!recommendations || recommendations.length === 0) return null;

  return (
    <Card withBorder shadow="xs" p="md">
      <Text fw={600} size="sm" mb="xs">{t('diagnosis.recommendations')}</Text>
      <Stack gap="xs">
        {recommendations.map((rec, i) => (
          <Box key={i} ml="xs">
            <Group gap="xs" wrap="nowrap">
              <Badge size="sm" variant="outline" color="blue">{rec.priority || i + 1}</Badge>
              <Text size="sm" fw={500} c="carbon.8" style={{ fontFamily: 'monospace' }}>
                {rec.action}
              </Text>
            </Group>
            {rec.reason && <Text size="xs" c="carbon.6" ml="lg">{rec.reason}</Text>}
          </Box>
        ))}
      </Stack>
    </Card>
  );
}

function QuickLinksSection({ links }: { links?: DiagnosisData['links'] }) {
  const { t } = useTranslation();
  if (!links) return null;
  const items = [
    { label: t('diagnosis.linkClinicOverview'), url: links.clinic_overview },
    { label: t('diagnosis.linkSlowQueries'), url: links.slow_queries },
    { label: t('diagnosis.linkLogsLoki'), url: links.logs },
    { label: t('diagnosis.linkTopSql'), url: links.topsql },
  ].filter(item => item.url);

  if (items.length === 0) return null;

  return (
    <Card withBorder shadow="xs" p="md">
      <Text fw={600} size="sm" mb="xs">{t('diagnosis.quickLinks')}</Text>
      <Stack gap="xs">
        {items.map(item => (
          <Group key={item.label} gap="xs" wrap="nowrap">
            <Text size="sm" c="blue.7" component="a" href={item.url} target="_blank" rel="noopener noreferrer"
              style={{ textDecoration: 'underline' }}>
              {item.label}
            </Text>
            <LinkOutlined style={{ fontSize: 12, color: '#228be6' }} />
          </Group>
        ))}
      </Stack>
    </Card>
  );
}

function GateCheckSection({ gateChecks }: { gateChecks?: DiagnosisData['gate_checks'] }) {
  const { t } = useTranslation();
  if (!gateChecks) return null;
  return (
    <Card withBorder shadow="xs" p="md">
      <Text fw={600} size="sm" mb="xs">{t('diagnosis.gateChecks')}</Text>
      <Stack gap="xs">
        {gateChecks.infra && (
          <Box>
            <Text size="xs" fw={500} c="carbon.6">{t('diagnosis.infrastructure')}</Text>
            <Text size="xs" c={gateChecks.infra.includes('ABNORMAL') ? 'red.7' : 'green.7'} style={{ fontFamily: 'monospace' }}>
              {truncate(gateChecks.infra, 200)}
            </Text>
          </Box>
        )}
        {gateChecks.hotspot && (
          <Box>
            <Text size="xs" fw={500} c="carbon.6">{t('diagnosis.hotspotDetection')}</Text>
            <Text size="xs" c={gateChecks.hotspot.includes('DETECTED') ? 'red.7' : 'green.7'} style={{ fontFamily: 'monospace' }}>
              {truncate(gateChecks.hotspot, 200)}
            </Text>
          </Box>
        )}
      </Stack>
    </Card>
  );
}

// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------

export default function DiagnosisReport({ data }: DiagnosisReportProps) {
  const { t } = useTranslation();
  const { metadata, evidence, analysis, gate_checks } = data;

  if (!data) {
    return (
      <Stack p="md">
        <Text c="red">{t('diagnosis.noData')}</Text>
      </Stack>
    );
  }

  const clusterLabel = metadata?.cluster_id || 'cluster';
  const timeStart = metadata?.time_range?.start;
  const timeEnd = metadata?.time_range?.end;
  const hasAuthoredEvidenceGroups = Array.isArray(analysis?.key_evidence)
    || Array.isArray(analysis?.supporting_evidence);
  // The workspace evidence report panel shows evidence only; the conclusion
  // (root cause, evidence chain, recommendations) lives in the chat answer.
  const evidenceOnly = data.type === 'workspace_evidence_report';

  return (
    <ScrollArea style={{ height: '100%' }}>
      <Stack gap="md" p="md" style={{ minHeight: '100%' }}>
        {/* Header */}
        <Card withBorder shadow="xs" p="md">
          <Stack gap="xs">
            <Group justify="space-between">
              <Title order={4}>{t('diagnosis.title')}</Title>
              {severityBadge(analysis?.severity)}
            </Group>
            <Group gap="md">
              <Text size="xs" c="carbon.6">{t('diagnosis.cluster')}: <Text component="span" fw={500} c="carbon.9" style={{ fontFamily: 'monospace' }}>{clusterLabel}</Text></Text>
              {timeStart && timeEnd && (
                <Text size="xs" c="carbon.6">{t('diagnosis.time')}: {timeStart} → {timeEnd}</Text>
              )}
            </Group>
          </Stack>
        </Card>

        {/* Root cause narrative — hidden for evidence-only workspace reports */}
        {!evidenceOnly && <RootCauseSection analysis={analysis} />}

        {hasAuthoredEvidenceGroups ? (
          <AuthoredEvidenceSection analysis={analysis} />
        ) : (
          /* Legacy evidence tabs */
          <Card withBorder shadow="xs" p="md">
            <Tabs defaultValue="metrics">
              <Tabs.List>
                <Tabs.Tab value="metrics">
                  {t('diagnosis.tabMetrics')} {(evidence?.metrics?.length || 0) > 0 && <Badge size="sm" variant="light" ml={4}>{evidence!.metrics!.length}</Badge>}
                </Tabs.Tab>
                <Tabs.Tab value="queries">
                  {t('diagnosis.tabQueries')} {(evidence?.queries?.length || 0) > 0 && <Badge size="sm" variant="light" ml={4}>{evidence!.queries!.length}</Badge>}
                </Tabs.Tab>
                <Tabs.Tab value="logs">
                  {t('diagnosis.tabLogs')} {(evidence?.logs?.length || 0) > 0 && <Badge size="sm" variant="light" ml={4}>{evidence!.logs!.length}</Badge>}
                </Tabs.Tab>
              </Tabs.List>

              <Tabs.Panel value="metrics" pt="md">
                <MetricsSection metrics={evidence?.metrics} />
              </Tabs.Panel>

              <Tabs.Panel value="queries" pt="md">
                <QueriesSection queries={evidence?.queries} />
              </Tabs.Panel>

              <Tabs.Panel value="logs" pt="md">
                <LogsSection logs={evidence?.logs} />
              </Tabs.Panel>
            </Tabs>
          </Card>
        )}

        {/* Gate checks */}
        <GateCheckSection gateChecks={gate_checks} />

        {/* Recommendations */}
        {!evidenceOnly && <RecommendationsSection recommendations={analysis?.recommendations} />}
      </Stack>
    </ScrollArea>
  );
}
