import { memo } from 'react';

import { ErrorBoundary } from 'components/ErrorBoundary';
import { Tile } from './Tile';
import { ChartTile } from './ChartTile';
import { AnalyticsTable } from './AnalyticsTable';
import { Tabs } from './Tabs';

import { CONFIG } from './config';

import { AnalyticsGroupFragment } from 'types/graphql';

function getComponentByType(type: string) {
  const config = CONFIG[type];
  switch (type) {
    case 'AreaChart':
    case 'BarChart':
    case 'CalendarChart':
    case 'Choropleth':
    case 'GroupChart':
    case 'LineChart':
    case 'ParetoChart':
    case 'PieChart':
    case 'RadarChart':
    case 'ScatterChart':
    case 'StackChart':
    case 'TreeMap':
      return {
        style: config.style,
        factory: ({ __typename, options, ...props }: any) => {
          let parsedOptions;
          if (typeof options === 'string') {
            try {
              parsedOptions = JSON.parse(options);
            } catch (error) {
              console.error(error);
            }
          }
          return <ChartTile {...props} options={parsedOptions} />;
        },
      };
    case 'InfoTabs':
      return {
        style: config.style,
        factory: ({ data }: any) => {
          return <Tabs data={data} />;
        },
      };
    case 'Table':
      return {
        style: config.style,
        factory: (content: any) => {
          return (
            <Tile name={content.label}>
              <AnalyticsTable
                data={content.dataJSON}
                options={content.optionsJSON}
              />
            </Tile>
          );
        },
      };
    default:
      return null;
  }
}

export const ContentGroup = memo(function ContentGroup({
  data,
}: {
  data: AnalyticsGroupFragment['charts'];
}) {
  if (Array.isArray(data) && data.length) {
    return (
      <div className="flex flexWrap padding2">
        {data.map((content) => {
          const component = getComponentByType(content.type);

          if (component) {
            const { factory, style } = component;
            return (
              <div className="flexGrow padding2" style={style} key={content.id}>
                <ErrorBoundary>{factory(content)}</ErrorBoundary>
              </div>
            );
          } else {
            console.error(`Unknown content type: ${content.type}`);
            return null;
          }
        })}
      </div>
    );
  } else {
    return null;
  }
});
