'use client';

import { useMemo, useState } from 'react';
import { CheckOutlined, ClockCircleOutlined, StarFilled } from '@ant-design/icons';
import { Box, Button, Group, Stack, Text, Tooltip } from '@tidbcloud/uikit';
import { useTranslation, type TranslationKey } from '@/lib/i18n';

export type ConfirmedTimeRange = {
  start: string;
  end: string;
  timezone: string;
};

export type DiagnosisTimeCheckpoint = {
  kind: 'time';
  status: 'awaiting_user';
  source_expression: string;
  normalized_range: ConfirmedTimeRange | null;
  clarification_needed: string | null;
};

export const STANDARD_DIAGNOSIS_ROUTES = [
  'sql_plan_or_query',
  'transaction_or_lock_contention',
  'tikv_hotspot_or_coprocessor',
  'storage_or_io_bottleneck',
  'memory_or_oom_pressure',
  'gc_or_allocator_pressure',
  'resource_control_or_capacity',
  'pd_tso_or_scheduling',
  'cdc_or_replication_lag',
  'network_or_connectivity',
  'component_failure_or_bug',
] as const;

export type StandardDiagnosisRoute = typeof STANDARD_DIAGNOSIS_ROUTES[number];

export function isStandardDiagnosisRoute(value: unknown): value is StandardDiagnosisRoute {
  return typeof value === 'string'
    && (STANDARD_DIAGNOSIS_ROUTES as readonly string[]).includes(value);
}

export type DiagnosisRouteCandidate = {
  route: StandardDiagnosisRoute;
  label: string;
  routing_confidence: number;
  evidence_for: string[];
  evidence_against: string[];
};

export type DiagnosisRoutingCheckpoint = {
  kind: 'routing';
  status: 'awaiting_user';
  candidates: DiagnosisRouteCandidate[];
  recommended_route: StandardDiagnosisRoute;
};

export type DiagnosisCheckpointState = DiagnosisTimeCheckpoint | DiagnosisRoutingCheckpoint;

type Props = {
  checkpoint: DiagnosisCheckpointState;
  disabled: boolean;
  onConfirmTime: (range: ConfirmedTimeRange) => void;
  onReviseTime: () => void;
  onSelectRoutes: (routes: string[]) => void;
  onRejectRoutes: () => void;
};

const ROUTE_LABEL_KEYS: Record<string, TranslationKey> = {
  sql_plan_or_query: 'chat.copilot.route.sql',
  transaction_or_lock_contention: 'chat.copilot.route.transaction',
  tikv_hotspot_or_coprocessor: 'chat.copilot.route.tikvHotspot',
  storage_or_io_bottleneck: 'chat.copilot.route.storageIo',
  memory_or_oom_pressure: 'chat.copilot.route.memoryOom',
  gc_or_allocator_pressure: 'chat.copilot.route.gcAllocator',
  resource_control_or_capacity: 'chat.copilot.route.resourceCapacity',
  pd_tso_or_scheduling: 'chat.copilot.route.pdTso',
  cdc_or_replication_lag: 'chat.copilot.route.cdcReplication',
  network_or_connectivity: 'chat.copilot.route.network',
  component_failure_or_bug: 'chat.copilot.route.componentFailure',
};

export function DiagnosisCheckpoint({
  checkpoint,
  disabled,
  onConfirmTime,
  onReviseTime,
  onSelectRoutes,
  onRejectRoutes,
}: Props) {
  const { t } = useTranslation();
  const [selectedRoutes, setSelectedRoutes] = useState<string[]>(
    checkpoint.kind === 'routing' ? [checkpoint.recommended_route] : [],
  );

  const selectedSet = useMemo(() => new Set(selectedRoutes), [selectedRoutes]);

  if (checkpoint.kind === 'time') {
    return (
      <Box
        px="md"
        py="sm"
        style={{
          border: '1px solid #bfdbfe',
          borderRadius: 6,
          backgroundColor: '#eff6ff',
          alignSelf: 'flex-start',
          maxWidth: '100%',
        }}
      >
        <Group justify="space-between" align="center" wrap="wrap" gap="sm">
          <Group gap="sm" align="center">
            <ClockCircleOutlined style={{ color: '#2563eb' }} />
            <Stack gap={2}>
              <Text size="sm" fw={600} c="blue.9">{t('chat.copilot.confirmTimeTitle')}</Text>
              {checkpoint.normalized_range ? (
                <Text size="xs" c="carbon.7" style={{ fontFamily: 'monospace' }}>
                  {checkpoint.normalized_range.start} - {checkpoint.normalized_range.end} ({checkpoint.normalized_range.timezone})
                </Text>
              ) : (
                <Text size="xs" c="red.7">{checkpoint.clarification_needed || t('chat.copilot.timeClarification')}</Text>
              )}
            </Stack>
          </Group>
          <Group gap="xs">
            <Button
              size="compact-sm"
              variant="outline"
              color="gray"
              disabled={disabled}
              onClick={onReviseTime}
            >
              {t('chat.copilot.modifyTime')}
            </Button>
            {checkpoint.normalized_range && (
              <Button
                size="compact-sm"
                leftSection={<CheckOutlined />}
                disabled={disabled}
                onClick={() => onConfirmTime(checkpoint.normalized_range!)}
              >
                {t('chat.copilot.confirmTime')}
              </Button>
            )}
          </Group>
        </Group>
      </Box>
    );
  }

  const toggleRoute = (route: string) => {
    setSelectedRoutes(current => {
      if (current.includes(route)) return current.filter(item => item !== route);
      if (current.length >= 3) return current;
      return [...current, route];
    });
  };

  return (
    <Box
      px="md"
      py="sm"
      style={{
        border: '1px solid #d1d5db',
        borderRadius: 6,
        backgroundColor: '#f9fafb',
        alignSelf: 'flex-start',
        maxWidth: '100%',
      }}
    >
      <Stack gap="xs">
        <Group justify="space-between" align="center">
          <Text size="sm" fw={600}>{t('chat.copilot.routesTitle')}</Text>
          <Text size="xs" c="carbon.6">{t('chat.copilot.promptHint')}</Text>
        </Group>
        <Group gap="xs" wrap="wrap">
          {checkpoint.candidates.map(candidate => {
            const selected = selectedSet.has(candidate.route);
            const recommended = candidate.route === checkpoint.recommended_route;
            const routeLabelKey = ROUTE_LABEL_KEYS[candidate.route];
            const routeLabel = routeLabelKey ? t(routeLabelKey) : candidate.label;
            return (
              <Tooltip
                key={candidate.route}
                label={candidate.label}
                multiline
                w={360}
                position="top"
                withArrow
              >
                <Button
                  size="compact-sm"
                  variant={selected ? 'filled' : 'outline'}
                  color={selected ? 'blue' : 'gray'}
                  leftSection={selected ? <CheckOutlined /> : undefined}
                  rightSection={recommended ? <StarFilled aria-label={t('chat.copilot.recommended')} /> : undefined}
                  disabled={disabled}
                  onClick={() => toggleRoute(candidate.route)}
                >
                  <span
                    style={{
                      display: 'block',
                      maxWidth: 180,
                      overflow: 'hidden',
                      textOverflow: 'ellipsis',
                      whiteSpace: 'nowrap',
                    }}
                  >
                    {routeLabel}
                  </span>
                </Button>
              </Tooltip>
            );
          })}
        </Group>
        <Group gap="xs" justify="space-between" wrap="wrap">
          <Button
            size="compact-sm"
            variant="subtle"
            color="gray"
            disabled={disabled}
            onClick={() => {
              setSelectedRoutes([]);
              onRejectRoutes();
            }}
          >
            {t('chat.copilot.noneOfRoutes')}
          </Button>
          <Button
            size="compact-sm"
            disabled={disabled || selectedRoutes.length === 0}
            onClick={() => onSelectRoutes(selectedRoutes)}
          >
            {t('chat.copilot.diagnoseSelected', { count: selectedRoutes.length })}
          </Button>
        </Group>
      </Stack>
    </Box>
  );
}
