import { Meta, StoryObj } from '@storybook/react-vite'

import { ChartTooltip, ChartTooltipContent } from './base'
import { LineChart } from './line'

const meta = {
  title: 'LineChart',
  component: LineChart,
  tags: ['autodocs'],
  argTypes: {
    type: {
      control: 'select',
      options: ['natural', 'linear', 'step'],
      description: 'The type of line interpolation',
    },
    dots: {
      control: 'boolean',
      description:
        'Enabling this option will show small visual indicators for each datapoint in the chart. When disabled the chart will plot a single line.',
    },
  },
} satisfies Meta<any>

export default meta

const randomDatapoint = () => Math.max(3, Math.min(17, ~~(Math.random() * 20)))

const singlePlot = [
  { label: 'Sep 2022', value: randomDatapoint() },
  { label: 'Oct 2022', value: randomDatapoint() },
  { label: 'Nov 2022', value: randomDatapoint() },
  { label: 'Dec 2022', value: randomDatapoint() },
  { label: 'Jan 2023', value: randomDatapoint() },
  { label: 'Feb 2023', value: randomDatapoint() },
  { label: 'Mar 2023', value: randomDatapoint() },
  { label: 'Apr 2023', value: randomDatapoint() },
  { label: 'May 2023', value: randomDatapoint() },
  { label: 'Jun 2023', value: randomDatapoint() },
  { label: 'Jul 2023', value: randomDatapoint() },
  { label: 'Aug 2023', value: randomDatapoint() },
  { label: 'Sep 2023', value: randomDatapoint() },
]

const multiplePlots = [
  { label: 'Sep 2022', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Oct 2022', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Nov 2022', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Dec 2022', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Jan 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Feb 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Mar 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Apr 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'May 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Jun 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Jul 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Aug 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
  { label: 'Sep 2023', a: randomDatapoint(), b: randomDatapoint(), c: randomDatapoint() },
]

export const Default: StoryObj<any> = {
  name: 'Simple plot',
  render: () => (
    <div className="flex items-center justify-center border rounded p-4">
      <LineChart
        className="h-[400px]"
        data={singlePlot}
        plots={['value']}
        config={{
          value: {
            type: 'natural',
            label: 'Value',
            // 'hsl(var(--chart-1))' would use a theme CSS variable, but Storybook doesn't provide that variable by default.
            // Define the variable in Storybook's global styles (e.g. preview.css) or use a concrete color here for the story.
            color: '#2563eb',
            dot: true,
          },
        }}
        onDatapointClick={(data) => console.log(JSON.stringify(data))}
      >
        <ChartTooltip content={<ChartTooltipContent hideLabel />} />
      </LineChart>
    </div>
  ),
}

export const MultiplePlots: StoryObj<any> = {
  name: 'Multiple plots',
  render: () => (
    <div className="flex items-center justify-center border rounded p-4">
      <LineChart
        className="h-[400px] max-w-full"
        data={multiplePlots}
        plots={['a', 'b', 'c']}
        config={{
          a: {
            type: 'natural',
            label: 'a',
            // 'hsl(var(--chart-1))' would use a theme CSS variable, but Storybook doesn't provide that variable by default.
            // Define the variable in Storybook's global styles (e.g. preview.css) or use a concrete color here for the story.
            color: '#2563eb',
            dot: true,
          },
          b: {
            type: 'natural',
            label: 'b',
            color: '#dc2626',
            dot: true,
          },
          c: {
            type: 'natural',
            label: 'c',
            color: '#16a34a',
            dot: true,
          },
        }}
        onDatapointClick={(data) => console.log(JSON.stringify(data))}
      >
        <ChartTooltip content={<ChartTooltipContent hideLabel />} />
      </LineChart>
    </div>
  ),
}

export const WithAxes: StoryObj<any> = {
  name: 'With axes',
  parameters: {
    docs: {
      description: {
        story: `By default rendering the <LineChart /> component will give you the basic plot but nothing else. To render axes you can supply the 'x' or 'y' prop. This can either be a string key of your data, or an object with additional configuration.`,
      },
    },
  },
  render: () => (
    <div className="flex items-center justify-center border rounded p-4">
      <LineChart
        className="h-[400px]"
        data={singlePlot}
        plots={['value']}
        config={{
          value: {
            type: 'natural',
            label: 'Value',
            // 'hsl(var(--chart-1))' would use a theme CSS variable, but Storybook doesn't provide that variable by default.
            // Define the variable in Storybook's global styles (e.g. preview.css) or use a concrete color here for the story.
            color: '#2563eb',
            dot: true,
          },
        }}
        x="label"
        y="value"
      >
        <ChartTooltip content={<ChartTooltipContent hideLabel />} />
      </LineChart>
    </div>
  ),
}

export const WithFormattedAxes: StoryObj<any> = {
  name: 'With formatted axes',
  parameters: {
    docs: {
      description: {
        story: `An axis label can be customised by passing in a formatter function. In this example we show the month name for each tick but for January we show the year instead.`,
      },
    },
  },
  render: () => (
    <div className="flex items-center justify-center border rounded p-4">
      <LineChart
        className="h-[400px]"
        data={singlePlot}
        plots={['value']}
        config={{
          value: {
            type: 'natural',
            label: 'Value',
            // 'hsl(var(--chart-1))' would use a theme CSS variable, but Storybook doesn't provide that variable by default.
            // Define the variable in Storybook's global styles (e.g. preview.css) or use a concrete color here for the story.
            color: '#2563eb',
            dot: true,
          },
        }}
        x={{ key: 'label', formatter: (value) => (value.startsWith('Jan') ? value.slice(4) : value.slice(0, 3)) }}
        y="value"
      >
        <ChartTooltip content={<ChartTooltipContent hideLabel />} />
      </LineChart>
    </div>
  ),
}

export const Interactive: StoryObj<any> = {
  name: 'Interactive Controls',
  args: {
    type: 'natural',
    dots: true,
  },
  parameters: {
    docs: {
      description: {
        story:
          'Use the controls below to interact with the chart and see how different settings affect the visualization.',
      },
    },
  },
  render: (args: any) => (
    <div className="flex items-center justify-center border rounded p-4">
      <LineChart
        className="h-[400px]"
        data={singlePlot}
        plots={['value']}
        config={{
          value: {
            type: args.type as 'natural' | 'linear' | 'step',
            label: 'Value',
            // 'hsl(var(--chart-1))' would use a theme CSS variable, but Storybook doesn't provide that variable by default.
            // Define the variable in Storybook's global styles (e.g. preview.css) or use a concrete color here for the story.
            color: '#2563eb',
            dot: args.dots,
          },
        }}
        onDatapointClick={(data) => console.log(JSON.stringify(data))}
        x="label"
        y="value"
      >
        <ChartTooltip content={<ChartTooltipContent hideLabel />} />
      </LineChart>
    </div>
  ),
}
