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

import { emptyCondition } from '@composed-components/ConditionGroup/constants';
import {
  fieldItems,
  valueItems,
} from '@composed-components/ConditionGroup/mocks';
import { Button, Stack, Typography } from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';

import { useMockCount, useMockCountLoading, useMockService } from './mocks';
import { type SegmentationCriteriaValues } from './types';
import useSegmentationCriteriaDrawer from '.';

const DEFAULT_VALUES = {
  conditions: [emptyCondition],
};

const INPUT_PROPS = {
  slotProps: {
    conditionLine: {
      fieldSelectorItems: fieldItems,
      valueSelectorItems: valueItems,
    },
  },
};

const queryClient = new QueryClient({
  defaultOptions: { queries: { retry: false } },
});

const meta: Meta = {
  title: 'Composed Components/Audience/Hooks/useSegmentationCriteriaDrawer',
  tags: ['autodocs'],
  decorators: [
    Story => (
      <QueryClientProvider client={queryClient}>
        <Story />
      </QueryClientProvider>
    ),
  ],
  parameters: {
    docs: {
      description: {
        component:
          'A hook that manages a segmentation criteria drawer. ' +
          'It wraps a `FormConditionGroup` inside a `useCriteriaDrawer`, providing ' +
          'pre-configured translated title, description, and cancel confirmation text. ' +
          'Users can add, edit, and remove condition rules to define audience segmentation.',
      },
    },
  },
  argTypes: {
    disabled: {
      description: 'Disables the confirm and cancel buttons inside the drawer.',
      control: 'boolean',
      table: { defaultValue: { summary: 'false' } },
    },
    loading: {
      description:
        'Shows a loading indicator on the confirm button and disables interactions.',
      control: 'boolean',
      table: { defaultValue: { summary: 'false' } },
    },
    onConfirm: {
      description:
        'Callback fired when the user submits the form. Receives the segmentation criteria values.',
    },
    onClose: {
      description:
        'Callback fired when the drawer is closed (via overlay click, close button, or cancel confirmation).',
    },
    inputProps: {
      description:
        'Props forwarded to the underlying `ConditionGroup` component (excluding `value` and `onChange`, which are managed by the form).',
      control: 'object',
      table: {
        type: {
          summary:
            'Omit<ConditionGroupProps<FieldItemType, ValueItemType>, "value" | "onChange">',
        },
      },
    },
    collaboratorsReach: {
      description:
        'Reactive collaborators-reach configuration passed at **hook level**. ' +
        'When provided, a footer alert shows the collaborator count, a loading skeleton, ' +
        'or an empty-state message depending on form and fetch state. ' +
        'Includes `service` and `queryKey` to power the selected-collaborators drawer.',
      control: false,
      table: {
        type: { summary: 'CollaboratorsReachProps' },
      },
    },
  },
  args: {
    disabled: false,
    loading: false,
  },
};

export default meta;

type Story = StoryObj<typeof meta>;

const CollaboratorsReachStory = ({
  args,
  reachLoading = false,
}: {
  args: Record<string, any>;
  reachLoading?: boolean;
}) => {
  const { segmentationCriteriaDrawer, showSegmentationCriteriaDrawer } =
    useSegmentationCriteriaDrawer({
      defaultValues: DEFAULT_VALUES,
      collaboratorsReach: {
        useCount: reachLoading ? useMockCountLoading : useMockCount,
        useService: useMockService,
        queryKey: 'segmentation-collaborators',
        onViewCollaborators: () =>
          console.debug('[CollaboratorsReach] View collaborators'),
      },
    });

  const handleOpen = () => {
    showSegmentationCriteriaDrawer({
      ...args,
      onConfirm: (values: unknown) =>
        console.debug('[useSegmentationCriteriaDrawer] onConfirm', values),
      onClose: () => console.debug('[useSegmentationCriteriaDrawer] onClose'),
      inputProps: INPUT_PROPS,
    });
  };

  return (
    <Stack gap={2}>
      <Button
        variant="primary"
        onClick={handleOpen}
      >
        Open Drawer
      </Button>
      {segmentationCriteriaDrawer}
    </Stack>
  );
};

export const Default: Story = {
  render: args => {
    const { segmentationCriteriaDrawer, showSegmentationCriteriaDrawer } =
      useSegmentationCriteriaDrawer({ defaultValues: DEFAULT_VALUES });

    const handleOpen = () => {
      showSegmentationCriteriaDrawer({
        ...args,
        onConfirm: (values: unknown) =>
          console.debug('[useSegmentationCriteriaDrawer] onConfirm', values),
        onClose: () => console.debug('[useSegmentationCriteriaDrawer] onClose'),
        inputProps: INPUT_PROPS,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          Click the button to open the segmentation criteria drawer.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Drawer
        </Button>
        {segmentationCriteriaDrawer}
      </Stack>
    );
  },
  parameters: {
    docs: {
      description: {
        story:
          'Default usage with segmentation condition rules, confirm and cancel actions.',
      },
    },
  },
};

export const Loading: Story = {
  render: args => {
    const { segmentationCriteriaDrawer, showSegmentationCriteriaDrawer } =
      useSegmentationCriteriaDrawer({ defaultValues: DEFAULT_VALUES });

    const handleOpen = () => {
      showSegmentationCriteriaDrawer({
        ...args,
        loading: true,
        disabled: true,
        onConfirm: (values: unknown) =>
          console.debug('[useSegmentationCriteriaDrawer] onConfirm', values),
        onClose: () => console.debug('[useSegmentationCriteriaDrawer] onClose'),
        inputProps: INPUT_PROPS,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          The confirm button shows a loading indicator.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Loading Drawer
        </Button>
        {segmentationCriteriaDrawer}
      </Stack>
    );
  },
  args: { loading: true },
  parameters: {
    docs: {
      description: {
        story:
          'Drawer with loading state — the confirm button shows a spinner and interactions are disabled.',
      },
    },
  },
};

export const Disabled: Story = {
  render: args => {
    const { segmentationCriteriaDrawer, showSegmentationCriteriaDrawer } =
      useSegmentationCriteriaDrawer({ defaultValues: DEFAULT_VALUES });

    const handleOpen = () => {
      showSegmentationCriteriaDrawer({
        ...args,
        disabled: true,
        onConfirm: (values: unknown) =>
          console.debug('[useSegmentationCriteriaDrawer] onConfirm', values),
        onClose: () => console.debug('[useSegmentationCriteriaDrawer] onClose'),
        inputProps: INPUT_PROPS,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          The drawer opens with both action buttons disabled.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Disabled Drawer
        </Button>
        {segmentationCriteriaDrawer}
      </Stack>
    );
  },
  args: { disabled: true },
  parameters: {
    docs: {
      description: {
        story:
          'Drawer with disabled state — both confirm and cancel buttons are disabled.',
      },
    },
  },
};

export const WithCollaboratorsReach: Story = {
  render: args => (
    <>
      <Typography variant="globalS">
        The drawer footer shows an info alert with the collaborator count. When
        no conditions are selected, an empty-state message is shown instead.
      </Typography>
      <CollaboratorsReachStory args={args} />
    </>
  ),
  parameters: {
    docs: {
      description: {
        story:
          'Drawer with `collaboratorsReach` configured. The footer alert shows ' +
          '"no collaborators" when the form is empty, a skeleton while loading, ' +
          'or the total count with a "View collaborators" button when ready.',
      },
    },
  },
};

type FieldItem = (typeof fieldItems)[number];
type ValueItem = (typeof valueItems)[number];

const validateAtLeastOneCompleteCondition = (
  values: SegmentationCriteriaValues<FieldItem, ValueItem>,
) =>
  values.conditions.some(
    c => c.field && Array.isArray(c.value) && c.value.length > 0,
  );

export const WithValidate: Story = {
  render: args => {
    const { segmentationCriteriaDrawer, showSegmentationCriteriaDrawer } =
      useSegmentationCriteriaDrawer({
        defaultValues: DEFAULT_VALUES,
        validate: validateAtLeastOneCompleteCondition,
      });

    const handleOpen = () => {
      showSegmentationCriteriaDrawer({
        ...args,
        onConfirm: (values: unknown) =>
          console.debug('[useSegmentationCriteriaDrawer] onConfirm', values),
        onClose: () => console.debug('[useSegmentationCriteriaDrawer] onClose'),
        inputProps: INPUT_PROPS,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          The confirm button stays disabled until at least one condition has a
          selected `field` and a non-empty `value`.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Drawer
        </Button>
        {segmentationCriteriaDrawer}
      </Stack>
    );
  },
  parameters: {
    docs: {
      description: {
        story:
          'Drawer with reactive `validate`. The confirm button is disabled ' +
          'until the predicate returns `true`. Here it requires at least one ' +
          'condition with both `field` and `value` set.',
      },
    },
  },
};

export const WithCollaboratorsReachLoading: Story = {
  render: args => (
    <>
      <Typography variant="globalS">
        The drawer footer shows a loading skeleton inside the info alert.
      </Typography>
      <CollaboratorsReachStory
        args={args}
        reachLoading
      />
    </>
  ),
  parameters: {
    docs: {
      description: {
        story:
          'Drawer with `collaboratorsReach` in loading state — the footer alert displays a skeleton line.',
      },
    },
  },
};
