import Card from '@/components/Card';
import {
  Dashboard,
  DashboardOverviewCharts,
  DashboardComparisonCharts,
  DashboardChartsSeries,
  DashboardChartsDataset,
} from '@/types/api/dashboard/dashboard';
import { Icon } from '@iconify/react';
import { forwardRef, useImperativeHandle, useRef } from 'react';
import {
  CartesianGrid,
  Line,
  LineChart,
  ResponsiveContainer,
  XAxis,
  YAxis,
} from 'recharts';

type DashboardExportChartsProps = {
  data: Dashboard;
  analysisMode: string;
};

export type DashboardExportChartsRef = {
  getChartRefs: () => {
    key: string;
    ref: HTMLDivElement | null;
    label: string;
  }[];
};

// Type guard to check if charts is DashboardOverviewCharts
function isOverviewCharts(
  charts: DashboardOverviewCharts | DashboardComparisonCharts | undefined
): charts is DashboardOverviewCharts {
  if (!charts) return false;
  return (
    'deplesi' in charts ||
    'body_weight' in charts ||
    'fcr' in charts ||
    'performance' in charts ||
    'quality_control' in charts
  );
}

// Type guard to check if charts is DashboardComparisonCharts
function isComparisonCharts(
  charts: DashboardOverviewCharts | DashboardComparisonCharts | undefined
): charts is DashboardComparisonCharts {
  if (!charts) return false;
  return 'farm' in charts || 'flock' in charts || 'kandang' in charts;
}

const lineColors: Record<string, string> = {
  body_weight: '#10B981',
  std_body_weight: '#10B981',
  act_laying: '#1062B9',
  std_laying: '#1062B9',
  act_egg_weight: '#10B981',
  std_egg_weight: '#10B981',
  act_feed_intake: '#F52419',
  std_feed_intake: '#F52419',
  act_uniformity: '#F59E0B',
  std_uniformity: '#F59E0B',
  act_fcr: '#10B981',
  std_fcr: '#10B981',
  act_fcr_cum: '#F52419',
  std_fcr_cum: '#F52419',
  normal: '#10B981',
  abnormal: '#F52419',
  act_deplesi: '#10B981',
  std_deplesi: '#10B981',
};

const defaultLineColors: string[] = [
  '#10B981',
  '#1062B9',
  '#F52419',
  '#F59E0B',
  '#7F56D9',
];

// Helper function to get line color
const getLineColor = (seriesId: string | number, index: number): string => {
  const predefinedColor = lineColors[seriesId];
  if (predefinedColor) {
    return predefinedColor;
  }
  return defaultLineColors[index % defaultLineColors.length];
};

// Mapping for chart type labels
const chartTypeLabels: Record<keyof DashboardOverviewCharts, string> = {
  body_weight: 'Body Weight',
  performance: 'Performance',
  fcr: 'FCR',
  quality_control: 'Quality Control',
  deplesi: 'Deplesi',
};

const DashboardExportCharts = forwardRef<
  DashboardExportChartsRef,
  DashboardExportChartsProps
>(({ data, analysisMode }, ref) => {
  // Create refs for charts - use string keys for flexibility
  const chartRefs = useRef<{
    [key: string]: HTMLDivElement | null;
  }>({});

  // Determine chart keys and labels based on analysis mode
  const getChartConfig = () => {
    if (analysisMode === 'OVERVIEW' && isOverviewCharts(data.charts)) {
      const overviewKeys: (keyof DashboardOverviewCharts)[] = [
        'body_weight',
        'performance',
        'fcr',
        'quality_control',
        'deplesi',
      ];
      return overviewKeys.map((key) => ({
        key,
        label: chartTypeLabels[key],
        chartData: (data.charts as DashboardOverviewCharts)[key],
      }));
    } else if (
      analysisMode === 'COMPARISON' &&
      isComparisonCharts(data.charts)
    ) {
      // For comparison mode, find which comparison type has data
      const comparisonKey = data.charts.farm
        ? 'farm'
        : data.charts.flock
          ? 'flock'
          : 'kandang';

      const comparisonLabels: Record<string, string> = {
        farm: 'Farm Comparison',
        flock: 'Flock Comparison',
        kandang: 'Kandang Comparison',
      };

      return [
        {
          key: comparisonKey,
          label: comparisonLabels[comparisonKey],
          chartData: data.charts[comparisonKey],
        },
      ];
    }
    return [];
  };

  const chartConfig = getChartConfig();

  // Expose method to get all chart refs
  useImperativeHandle(ref, () => ({
    getChartRefs: () => {
      return chartConfig
        .map(({ key, label }) => ({
          key,
          ref: chartRefs.current[key] || null,
          label,
        }))
        .filter((item) => item.ref !== null);
    },
  }));

  return (
    <div className='space-y-6'>
      {chartConfig.map(({ key, label, chartData }) => {
        if (
          !chartData ||
          !chartData.dataset ||
          chartData.dataset.length === 0
        ) {
          return null;
        }

        const seriesData: DashboardChartsSeries[] = chartData.series || [];
        const dataset: DashboardChartsDataset[] = chartData.dataset || [];

        return (
          <div
            key={key}
            ref={(el: HTMLDivElement | null) => {
              chartRefs.current[key] = el;
            }}
          >
            <Card
              className={{
                wrapper: 'w-full rounded-lg p-0',
                body: 'p-4',
              }}
              variant='bordered'
            >
              <div className='flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4 mb-6'>
                <div className='text-lg font-semibold'>
                  {label}{' '}
                  <Icon
                    icon='heroicons:information-circle'
                    width={20}
                    height={20}
                    className='inline text-neutral-500'
                  />
                </div>
              </div>

              {/* Legend */}
              <div className='flex flex-wrap gap-3 mb-6'>
                {seriesData.map((series, index) => {
                  const isStandard = series.id
                    .toString()
                    .toLowerCase()
                    .includes('std');

                  return (
                    <div
                      key={series.id}
                      className='flex items-center gap-2 px-3 py-2 rounded-lg border border-neutral-400 bg-neutral-50'
                    >
                      <div
                        className={`w-6 h-0.5 ${
                          isStandard ? 'border-t-2 border-dashed' : ''
                        }`}
                        style={{
                          backgroundColor: isStandard
                            ? 'transparent'
                            : getLineColor(series.id, index),
                          borderColor: isStandard
                            ? getLineColor(series.id, index)
                            : 'transparent',
                        }}
                      ></div>
                      <span className='text-sm text-neutral-900 font-medium'>
                        {series.label}
                      </span>
                      <Icon
                        icon='heroicons:information-circle'
                        width={16}
                        height={16}
                        className='text-neutral-400'
                      />
                    </div>
                  );
                })}
              </div>

              {/* Chart */}
              <ResponsiveContainer width='100%' height={350}>
                <LineChart
                  data={dataset}
                  margin={{
                    top: 5,
                    right: 10,
                    left: 0,
                    bottom: 5,
                  }}
                >
                  <CartesianGrid strokeDasharray='3 3' stroke='#e5e7eb' />
                  <XAxis
                    dataKey='week'
                    tick={{ fontSize: 11, fill: '#9ca3af' }}
                    tickLine={false}
                    axisLine={{ stroke: '#e5e7eb' }}
                    label={{
                      value: 'Weeks',
                      position: 'insideBottom',
                      offset: -5,
                      style: { fontSize: 12, fill: '#9ca3af' },
                    }}
                  />
                  <YAxis
                    tick={{ fontSize: 11, fill: '#9ca3af' }}
                    tickLine={false}
                    axisLine={{ stroke: '#e5e7eb' }}
                    domain={(() => {
                      const allValues: number[] = [];
                      dataset.forEach((item: DashboardChartsDataset) => {
                        seriesData.forEach((series) => {
                          const value = item[series.id];
                          if (typeof value === 'number') {
                            allValues.push(value);
                          }
                        });
                      });

                      if (allValues.length === 0) return [0, 100];

                      const minValue = Math.min(...allValues);
                      const maxValue = Math.max(...allValues);
                      const padding = (maxValue - minValue) * 0.1;
                      const domainMin = Math.floor(
                        Math.max(0, minValue - padding)
                      );
                      const domainMax = Math.ceil(maxValue + padding);

                      return [domainMin, domainMax];
                    })()}
                  />
                  {seriesData.map((series, index) => {
                    const isStandard = series.id
                      .toString()
                      .toLowerCase()
                      .includes('std');
                    const dataKey = series.id.toString();

                    return (
                      <Line
                        key={series.id}
                        type='monotone'
                        dataKey={dataKey}
                        name={series.label}
                        stroke={getLineColor(series.id, index)}
                        opacity={isStandard ? 0.5 : 1}
                        strokeWidth={2}
                        strokeDasharray={isStandard ? '5 5' : undefined}
                        dot={
                          isStandard
                            ? false
                            : {
                                r: 3,
                                fill: '#fff',
                                stroke: getLineColor(series.id, index),
                                strokeWidth: 2,
                              }
                        }
                        activeDot={isStandard ? undefined : { r: 5 }}
                      />
                    );
                  })}
                </LineChart>
              </ResponsiveContainer>
            </Card>
          </div>
        );
      })}
    </div>
  );
});

DashboardExportCharts.displayName = 'DashboardExportCharts';

export default DashboardExportCharts;
