'use client';

import { ChartDataPoint } from '@/lib/types';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import { useEffect, useState } from 'react';
import { Text, Box } from '@tidbcloud/uikit';
import { TransformNullValue } from 'metrics-chart';
import ChartCard from '@/components/ChartCard';
import { MetricInfo, PrometheusMatrixResponse } from '@/components/ChartCard/helpers';
import { SettingsProps } from '@elastic/charts';
import { useTranslation } from '@/lib/i18n';

dayjs.extend(utc);

interface MetricChartProps {
  data: Record<string, ChartDataPoint[]>;
  metricName: string;
  title?: string;
  timeRange: [number, number];
  nullValue?: TransformNullValue;
  chartType?: 'line' | 'bar_stacked';
  chartSetting?: SettingsProps;
}

function shortenSeriesLabel(label: string): string {
  if (label.length <= 28) return label;
  return `${label.slice(0, 12)}...${label.slice(-12)}`;
}
export default function MetricChart({
  data,
  metricName,
  title,
  timeRange,
  nullValue = TransformNullValue.AS_ZERO,
  chartType = 'line',
  chartSetting,
}: MetricChartProps) {
  const { t } = useTranslation();
  const [mounted, setMounted] = useState(false);
  const [chartData, setChartData] = useState<PrometheusMatrixResponse | null>(null);
  
  useEffect(() => {
    setMounted(true);
  }, []);

  // Pre-convert data to Prometheus format
  useEffect(() => {
    const instances = Object.keys(data);
    if (instances.length === 0) {
      setChartData(null);
      return;
    }

    const result = instances.map(instance => ({
      metric: {
        __name__: metricName,
        instance: instance
      },
      values: data[instance]
        .sort((a, b) => a.timestamp - b.timestamp)
        .map(point => [point.timestamp, point.value.toString()]) as [number, string][]
    }));

    setChartData({
      status: 'success',
      data: {
        resultType: 'matrix',
        result
      }
    });
  }, [data, metricName]);
  
  if (!mounted) {
    return (
      <Box style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
        <Text c="carbon.6" size="sm">{t('insight.metric.loading')}</Text>
      </Box>
    );
  }

  const instances = Object.keys(data);
  const queryKeyByInstance = instances.reduce<Record<string, string>>((acc, instance) => {
    acc[instance] = `${metricName}::${instance}`;
    return acc;
  }, {});
  
  if (instances.length === 0 || !chartData) {
    return (
      <Box style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
        <Text c="carbon.6" size="sm">{t('insight.metric.noData')}</Text>
      </Box>
    );
  }

  const metricInfo: MetricInfo = {
    title: title || metricName,
    label: '',
    queries: instances.map(instance => ({
      promql: queryKeyByInstance[instance],
      name: shortenSeriesLabel(instance),
      type: chartType,
    })),
    nullValue,
    unit: 'short'
  };

  // fetchPromeData handler that responds to query parameter
  const handleFetchPromeData = (params: {
    startTimeSec: number;
    endTimeSec: number;
    stepSec: number;
    query: string;
  }) => {
    // Return the pre-converted data
    const instance = Object.entries(queryKeyByInstance).find(([, queryKey]) => queryKey === params.query)?.[0];
    if (chartData && instance) {
      const matched = chartData.data.result.find(series => series.metric?.instance === instance);
      return Promise.resolve({
        status: 'success' as const,
        data: {
          resultType: 'matrix' as const,
          result: matched ? [matched] : [],
        }
      });
    }
    
    // Return empty response for unmatched queries
    return Promise.resolve({
      status: 'success' as const,
      data: {
        resultType: 'matrix' as const,
        result: []
      }
    });
  };

  return (
    <ChartCard
      title={title || metricName}
      timeRange={timeRange}
      metric={metricInfo}
      height={240}
      fetchPromeData={handleFetchPromeData}
      cardProps={{ shadow: 'xs', withBorder: true }}
      chartSetting={chartSetting}
    />
  );
}
