import { Fragment, useEffect, useRef, useState } from 'react';

import {
  Box,
  Stack,
  ToggleButton,
  ToggleButtonGroup,
  Typography,
} from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';

import { type AIButtonVariant } from '../../shared/types';

import { type AIButtonProps } from './types';
import { AIButton } from '.';

const VARIANTS = ['primary', 'secondary', 'tertiary'] as const;

const STATES: { label: string; props: Partial<AIButtonProps> }[] = [
  { label: 'Enabled', props: {} },
  { label: 'Loading', props: { loading: true } },
  { label: 'Disabled', props: { disabled: true } },
];

const meta: Meta<typeof AIButton> = {
  title: 'Design System/AI/Buttons/AIButton',
  component: AIButton,
  tags: ['autodocs'],
  args: {
    children: 'Button',
    size: 'large',
    icon: 'sparkles',
    variant: 'primary',
  },
  argTypes: {
    variant: {
      control: 'radio',
      options: VARIANTS,
      table: { defaultValue: { summary: 'primary' } },
    },
    size: {
      control: 'radio',
      options: ['small', 'large'],
      table: { defaultValue: { summary: 'large' } },
    },
    icon: {
      control: 'radio',
      options: ['sparkles', 'ai-pencil', 'ai-photo'],
      table: { defaultValue: { summary: 'sparkles' } },
    },
    loading: {
      control: 'boolean',
      description: 'Shows the progress/stop state',
    },
    onStop: { table: { disable: true } },
  },
};

export default meta;

type Story = StoryObj<typeof meta>;

const ColumnHeader = ({ label }: { label: string }) => (
  <Typography
    variant="caption"
    sx={{ fontWeight: 700, textAlign: 'center', color: 'text.secondary' }}
  >
    {label}
  </Typography>
);

const RowHeader = ({ label }: { label: string }) => (
  <Typography
    variant="subtitle2"
    sx={{ textTransform: 'capitalize' }}
  >
    {label}
  </Typography>
);

/** Type rows × state columns. Hover a button to see the gradient/sparkle animation. */
const StateMatrix = (args: AIButtonProps) => (
  <Box
    sx={{
      display: 'inline-grid',
      gridTemplateColumns: `auto repeat(${STATES.length}, 1fr)`,
      gap: 3,
      alignItems: 'center',
    }}
  >
    <span />
    {STATES.map(({ label }) => (
      <ColumnHeader
        key={label}
        label={label}
      />
    ))}

    {VARIANTS.map(variant => (
      <Fragment key={variant}>
        <RowHeader label={variant} />
        {STATES.map(({ label, props }) => (
          <Box
            key={label}
            sx={{ display: 'flex', justifyContent: 'center' }}
          >
            <AIButton
              {...args}
              variant={variant}
              {...props}
            />
          </Box>
        ))}
      </Fragment>
    ))}
  </Box>
);

export const Playground: Story = {
  args: {},
};

export const Overview: Story = {
  parameters: { controls: { disable: true } },
  render: StateMatrix,
};

export const Sizes: Story = {
  parameters: { controls: { disable: true } },
  render: (args: AIButtonProps) => (
    <Stack spacing={3}>
      {(['large', 'small'] as const).map(size => (
        <Stack
          key={size}
          spacing={1}
        >
          <RowHeader label={size} />
          <Stack
            direction="row"
            spacing={2}
            alignItems="center"
            flexWrap="wrap"
          >
            {VARIANTS.map(variant => (
              <AIButton
                key={variant}
                {...args}
                variant={variant}
                size={size}
              />
            ))}
          </Stack>
        </Stack>
      ))}
    </Stack>
  ),
};

export const Dark: Story = {
  parameters: { controls: { disable: true } },
  render: StateMatrix,
  globals: { themeMode: 'dark' },
};

const SAMPLE_TEXT =
  'La inteligencia artificial está cambiando la forma en que trabajamos. ' +
  'Automatiza tareas repetitivas, genera contenido en segundos y nos deja ' +
  'tiempo para enfocarnos en lo que de verdad importa: pensar, crear y decidir.';

const STREAM_INTERVAL_MS = 90;

const TextGenerationDemo = (args: AIButtonProps) => {
  const [text, setText] = useState('');
  const [loading, setLoading] = useState(false);
  const [variant, setVariant] = useState<AIButtonVariant>(
    args.variant ?? 'primary',
  );
  const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const stopStreaming = () => {
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }
    setLoading(false);
  };

  const generate = () => {
    const words = SAMPLE_TEXT.split(' ');
    let index = 0;

    setText('');
    setLoading(true);

    intervalRef.current = setInterval(() => {
      index += 1;
      setText(words.slice(0, index).join(' '));
      if (index >= words.length) stopStreaming();
    }, STREAM_INTERVAL_MS);
  };

  useEffect(
    () => () => {
      if (intervalRef.current) clearInterval(intervalRef.current);
    },
    [],
  );

  return (
    <Stack
      spacing={2}
      sx={{ width: 440 }}
    >
      <ToggleButtonGroup
        exclusive
        size="small"
        color="primary"
        value={variant}
        onChange={(_, next: AIButtonVariant | null) => next && setVariant(next)}
      >
        {VARIANTS.map(option => (
          <ToggleButton
            key={option}
            value={option}
            sx={{ textTransform: 'capitalize' }}
          >
            {option}
          </ToggleButton>
        ))}
      </ToggleButtonGroup>

      <AIButton
        {...args}
        variant={variant}
        loading={loading}
        onClick={generate}
        onStop={stopStreaming}
      >
        Generar texto
      </AIButton>

      <Box
        sx={{
          minHeight: 132,
          p: 2,
          borderRadius: 2,
          border: '1px solid',
          borderColor: 'divider',
          bgcolor: 'background.paper',
        }}
      >
        <Typography
          variant="body2"
          sx={{ color: text ? 'text.primary' : 'text.secondary' }}
        >
          {text || 'El texto generado aparecerá acá…'}
          {loading && (
            <Box
              component="span"
              sx={{
                display: 'inline-block',
                width: '2px',
                height: '1em',
                ml: '2px',
                bgcolor: 'currentColor',
                verticalAlign: 'text-bottom',
                animation: 'iaCaretBlink 1s steps(2, start) infinite',
                '@keyframes iaCaretBlink': { '50%': { opacity: 0 } },
              }}
            />
          )}
        </Typography>
      </Box>
    </Stack>
  );
};

export const TextGeneration: Story = {
  parameters: {
    controls: {
      exclude: ['variant', 'loading', 'onStop', 'onClick', 'children'],
    },
  },
  render: TextGenerationDemo,
};
