import { useState } from 'react';
import { useDropzone } from 'react-dropzone';

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

import { useModal } from '../../../hooks/useModal';
import { getColorPaletteMapping } from '../../../utils/colors';
import CroppingModal from '../CroppingModal';

import ConfettiBackground from '.';

const colors = getColorPaletteMapping();

const colorLabels = Object.entries(colors).reduce(
  (acc, [key, value]) => {
    acc[value] = key;
    return acc;
  },
  {} as Record<string, string>,
);

const meta: Meta<typeof ConfettiBackground> = {
  component: ConfettiBackground,
  title: 'Composed Components/ConfettiBackground',
  tags: ['autodocs'],
  argTypes: {
    bgColor: {
      description: 'The background color of the confetti background',
      control: {
        type: 'select',
        labels: colorLabels,
      },
      options: Object.values(colors),
    },
    showConfetti: {
      description: 'If cover picture is provided, confetti will be hidden.',
      if: {
        arg: 'coverPicture',
        exists: false,
      },
    },
    showPoints: {
      description: 'Boolean to show or hide the points pill',
    },
    coverPicture: {
      description: 'It can be a File, a string (url) or null',
      table: {
        type: {
          summary: 'File | string | null',
        },
        defaultValue: {
          summary: 'null',
        },
      },
    },
    points: {
      control: 'number',
      description: 'If points is 0, the pill will be hidden',
      if: {
        arg: 'showPoints',
        eq: true,
      },
    },
  },
  parameters: {
    componentSubtitle: 'Used in acknowledgements module',
  },
};

export default meta;

type Story = StoryObj<typeof ConfettiBackground>;

export const Default: Story = {
  args: {
    bgColor: colors.DARK_GREEN,
    showConfetti: true,
    showPoints: true,
    points: '10',
  },
};

export const WithCroppedCustomImage: Story = {
  args: {
    bgColor: colors.DARK_GREEN,
    showPoints: true,
    points: '10',
  },

  render: args => {
    const expectedImageHeight = 236;
    const expectedImageWidth = 550;
    const [file, setFile] = useState<File | undefined>(undefined);

    const { getRootProps, open } = useDropzone({
      onDrop: files => {
        setFile(files[0]);
        showCroppingModal();
      },
      accept: {
        'image/png': [],
        'image/jpg': [],
      },
    });

    const { modal: croppingModal, showModal: showCroppingModal } = useModal(
      CroppingModal,
      { fullWidth: true, maxWidth: 'md' },
      {
        file,
        recommendedHeight: expectedImageHeight,
        recommendedWidth: expectedImageWidth,
        title: 'Crop Image',
        saveLabel: 'Save',
        cancelLabel: 'Cancel',
        onSave: croppedFile => {
          setFile(croppedFile);
        },
      },
    );

    return (
      <>
        {croppingModal}
        <ConfettiBackground
          {...args}
          showConfetti={!file}
          coverPicture={file}
          cropHeight={expectedImageHeight}
          cropWidth={expectedImageWidth}
        />
        <Stack sx={{ marginTop: 2, gap: 1 }}>
          <Stack sx={{ flexDirection: 'row', gap: 1 }}>
            <Button
              variant="contained"
              onClick={open}
              {...getRootProps()}
            >
              Upload Custom Image
            </Button>
            <Button
              variant="secondary"
              onClick={() => setFile(undefined)}
            >
              Remove Image
            </Button>
          </Stack>
          <Typography>Image height: {expectedImageHeight}px</Typography>
          <Typography>Image width: {expectedImageWidth}px</Typography>
        </Stack>
      </>
    );
  },
};

export const WithNoBorderRadius: Story = {
  args: {
    bgColor: colors.DARK_GREEN,
    showConfetti: true,
    showPoints: true,
    points: '10',
    stylesOptions: {
      borderRadius: 0,
    },
  },
};
