import produce from 'immer';

import { FieldConfigSource } from '@grafana/data';
import { GraphDrawStyle, GraphFieldConfig, StackingMode } from '@grafana/schema';

import { ExploreGraphStyle } from '../../types';

export type FieldConfig = FieldConfigSource<GraphFieldConfig>;

export function applyGraphStyle(config: FieldConfig, style: ExploreGraphStyle): FieldConfig {
  return produce(config, (draft) => {
    if (draft.defaults.custom === undefined) {
      draft.defaults.custom = {};
    }

    const { custom } = draft.defaults;

    if (custom.stacking === undefined) {
      custom.stacking = { group: 'A' };
    }

    switch (style) {
      case 'lines':
        custom.drawStyle = GraphDrawStyle.Line;
        custom.stacking.mode = StackingMode.None;
        custom.fillOpacity = 0;
        break;
      case 'bars':
        custom.drawStyle = GraphDrawStyle.Bars;
        custom.stacking.mode = StackingMode.None;
        custom.fillOpacity = 100;
        break;
      case 'points':
        custom.drawStyle = GraphDrawStyle.Points;
        custom.stacking.mode = StackingMode.None;
        custom.fillOpacity = 0;
        break;
      case 'stacked_lines':
        custom.drawStyle = GraphDrawStyle.Line;
        custom.stacking.mode = StackingMode.Normal;
        custom.fillOpacity = 100;
        break;
      case 'stacked_bars':
        custom.drawStyle = GraphDrawStyle.Bars;
        custom.stacking.mode = StackingMode.Normal;
        custom.fillOpacity = 100;
        break;
      default: {
        // should never happen
        // NOTE: casting to `never` will cause typescript
        // to verify that the switch statement checks every possible
        // enum-value
        const invalidValue: never = style;
        throw new Error(`Invalid graph-style: ${invalidValue}`);
      }
    }
  });
}
