import { useState } from 'react';
import { QueryClient, QueryClientProvider, useQuery } from 'react-query';

import { segmentations } from '@src/mock/data/segmentations';
import segmentationsService from '@src/mock/services/segmentations';
import { type Meta, type StoryObj } from '@storybook/react-vite';

import SegmentationGroupItemsSelection, {
  type SegmentationGroupItemsSelectionProps,
} from './index';

type StoryComponentArgs = {
  selectedSegmentationIds: Record<number, Set<number>>;
  setSelectedSegmentationIds: (data: {
    selectedSegmentationIds: Record<number, Set<number>>;
  }) => void;
  allowSelectAll?: boolean;
  excludedGroupsIds?: Set<number>;
  error?: { message: string };
  empty?: boolean;
};

const useMockSegmentationsQuery = (empty: boolean = false) => {
  return useQuery({
    queryKey: ['segmentations'],
    queryFn: () => segmentationsService.getSegmentations(),
    enabled: !empty,
    staleTime: Infinity,
    cacheTime: Infinity,
  });
};

const sampleSlotProps: SegmentationGroupItemsSelectionProps['slotProps'] = {
  title: {
    title: 'Selección por Segmentación',
    description: 'Selecciona segmentaciones específicas para tu audiencia',
  },
  search: {
    placeholder: 'Buscar por nombre de segmentación...',
  },
  stateCard: {
    title: 'No se encontraron segmentaciones',
    description: 'No hay segmentaciones que coincidan con tu búsqueda',
  },
  collapsibleSelectionList: {
    virtualized: true,
    allowSelectAll: false,
    listHeight: 250,
    rowHeight: 48,
    overscanCount: 5,
    slotProps: {
      accordion: {
        getDescription: (selected, total) =>
          selected.size > 0
            ? `${selected.size} de ${total} segmentaciones seleccionadas`
            : '',
      },
      stateCard: {
        title: 'No se encontraron segmentaciones',
        description: 'No hay segmentaciones que coincidan con tu búsqueda',
      },
    },
  },
};

const SegmentationGroupSelectionWithMockQuery = ({
  empty,
  ...props
}: StoryComponentArgs) => {
  const [selectedSegmentationIds, setSelectedSegmentationIds] = useState<
    Record<number, Set<number>>
  >(props?.selectedSegmentationIds || {});
  const segmentationsQuery = useMockSegmentationsQuery(empty);

  return (
    <SegmentationGroupItemsSelection
      {...props}
      segmentationsQuery={segmentationsQuery}
      segmentationsQueryDataParser={(data: any) => data?.data || []}
      value={selectedSegmentationIds}
      onChange={({ selectedSegmentationIds: _selectedSegmentationIds }) =>
        setSelectedSegmentationIds(_selectedSegmentationIds)
      }
      error={{ message: 'Error al obtener las segmentaciones' }}
      slotProps={sampleSlotProps}
    />
  );
};

const defaultArgs: StoryComponentArgs = {
  selectedSegmentationIds: {
    [segmentations[0].id]: new Set([1, 3, 5]),
  },
  setSelectedSegmentationIds: () => {},
  allowSelectAll: false,
  excludedGroupsIds: new Set(),
};

const meta: Meta<typeof SegmentationGroupSelectionWithMockQuery> = {
  component: SegmentationGroupSelectionWithMockQuery,
  title: 'Composed Components/Audience/SegmentationGroupItemsSelection',
  tags: ['autodocs'],
  decorators: [
    Story => {
      const queryClient = new QueryClient({
        defaultOptions: {
          queries: {
            retry: false,
          },
        },
      });

      return (
        <QueryClientProvider client={queryClient}>
          <Story />
        </QueryClientProvider>
      );
    },
  ],
  args: defaultArgs,
};

export default meta;

type Story = StoryObj<typeof SegmentationGroupSelectionWithMockQuery>;

export const Default: Story = {};

const SegmentationGroupSelectionWithCustomItemSx = ({
  empty,
  ...props
}: StoryComponentArgs) => {
  const [selectedSegmentationIds, setSelectedSegmentationIds] = useState<
    Record<number, Set<number>>
  >(props?.selectedSegmentationIds || {});
  const segmentationsQuery = useMockSegmentationsQuery(empty);

  return (
    <SegmentationGroupItemsSelection
      {...props}
      segmentationsQuery={segmentationsQuery}
      segmentationsQueryDataParser={(data: any) => data?.data || []}
      value={selectedSegmentationIds}
      onChange={({ selectedSegmentationIds: _selectedSegmentationIds }) =>
        setSelectedSegmentationIds(_selectedSegmentationIds)
      }
      slotProps={{
        ...sampleSlotProps,
        collapsibleSelectionList: {
          ...sampleSlotProps.collapsibleSelectionList,
          sx: {
            backgroundColor: ({ palette }) =>
              palette.new.background.elements.grey,
            borderRadius: 2,
            border: '1px solid',
            borderColor: 'divider',
            p: 1,
          },
        },
      }}
    />
  );
};

export const CustomItemStyles: StoryObj<
  typeof SegmentationGroupSelectionWithCustomItemSx
> = {
  render: args => <SegmentationGroupSelectionWithCustomItemSx {...args} />,
};
