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

import FormInputClassic from '@design-system/Inputs/Classic/form';
import { Button, Stack, Typography } from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';

import {
  isFormEmpty,
  useMockCount,
  useMockCountLoading,
  useMockCountReady,
  useMockService,
} from './mocks';
import useCriteriaDrawer from '.';

type FormValues = {
  name: string;
  description: string;
};

const DEFAULT_VALUES: FormValues = {
  name: '',
  description: '',
};

const DRAWER_TITLE = 'Criteria Configuration';
const DRAWER_DESCRIPTION =
  'Set the criteria values for the segmentation group.';

const FormFields = () => (
  <Stack gap={2}>
    <FormInputClassic
      name="name"
      inputProps={{
        label: 'Name',
        placeholder: 'Enter criteria name',
        fullWidth: true,
      }}
    />
    <FormInputClassic
      name="description"
      inputProps={{
        label: 'Description',
        placeholder: 'Enter criteria description',
        fullWidth: true,
        multiline: true,
      }}
    />
  </Stack>
);

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

const meta: Meta = {
  title: 'Composed Components/Audience/Hooks/useCriteriaDrawer',
  tags: ['autodocs'],
  decorators: [
    Story => (
      <QueryClientProvider client={queryClient}>
        <Story />
      </QueryClientProvider>
    ),
  ],
  parameters: {
    docs: {
      description: {
        component:
          'A hook that manages a drawer for configuring segmentation criteria. ' +
          'It wraps content in a form with react-hook-form, provides confirm/cancel actions, ' +
          'and shows a confirmation modal when the user tries to close with unsaved changes. ' +
          'Optionally renders a collaborators-reach info alert in the drawer footer.',
      },
    },
  },
  argTypes: {
    title: {
      description: 'Title displayed in the drawer header.',
      control: 'text',
      table: { defaultValue: { summary: 'undefined' } },
    },
    description: {
      description:
        'Description text rendered at the top of the drawer content.',
      control: 'text',
      table: { defaultValue: { summary: 'undefined' } },
    },
    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 form values as argument.',
    },
    onClose: {
      description:
        'Callback fired when the drawer is closed (via overlay click or close button).',
    },
    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: 'CriteriaCollaboratorsReachConfig<TValues>' },
      },
    },
  },
  args: {
    title: DRAWER_TITLE,
    description: DRAWER_DESCRIPTION,
    disabled: false,
    loading: false,
    onConfirm: () => alert('[UseCriteriaDrawer] onConfirm'),
    onClose: () => alert('[UseCriteriaDrawer] onClose'),
  },
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
  render: args => {
    const { criteriaDrawer, showCriteriaDrawer } =
      useCriteriaDrawer<FormValues>({ defaultValues: DEFAULT_VALUES });

    const handleOpen = () => {
      showCriteriaDrawer({
        ...args,
        children: <FormFields />,
      });
    };

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

export const Disabled: Story = {
  render: args => {
    const { criteriaDrawer, showCriteriaDrawer } =
      useCriteriaDrawer<FormValues>({ defaultValues: DEFAULT_VALUES });

    const handleOpen = () => {
      showCriteriaDrawer({
        ...args,
        disabled: true,
        children: <FormFields />,
      });
    };

    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>
        {criteriaDrawer}
      </Stack>
    );
  },
  args: { disabled: true },
  parameters: {
    docs: {
      description: {
        story:
          'Drawer with disabled state — both confirm and cancel buttons are disabled.',
      },
    },
  },
};

export const Loading: Story = {
  render: args => {
    const { criteriaDrawer, showCriteriaDrawer } =
      useCriteriaDrawer<FormValues>({ defaultValues: DEFAULT_VALUES });

    const handleOpen = () => {
      showCriteriaDrawer({
        ...args,
        loading: true,
        disabled: true,
        children: <FormFields />,
      });
    };

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

export const CollaboratorsReachEmpty: Story = {
  render: args => {
    const { criteriaDrawer, showCriteriaDrawer } =
      useCriteriaDrawer<FormValues>({
        defaultValues: DEFAULT_VALUES,
        collaboratorsReach: {
          useCount: useMockCount,
          useService: useMockService,
          queryKey: 'criteria-collaborators',
          onViewCollaborators: () =>
            console.debug('[CollaboratorsReach] View collaborators'),
          isFormEmpty,
        },
      });

    const handleOpen = () => {
      showCriteriaDrawer({
        ...args,
        children: <FormFields />,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          The drawer footer shows the empty-state collaborators alert. Fill a
          field to see the count.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Drawer
        </Button>
        {criteriaDrawer}
      </Stack>
    );
  },
  parameters: {
    docs: {
      description: {
        story:
          'Footer with empty state — shows a "no collaborators selected" info alert when the form is empty.',
      },
    },
  },
};

export const CollaboratorsReachLoading: Story = {
  render: args => {
    const { criteriaDrawer, showCriteriaDrawer } =
      useCriteriaDrawer<FormValues>({
        defaultValues: { name: 'Filled', description: '' },
        collaboratorsReach: {
          useCount: useMockCountLoading,
          useService: useMockService,
          queryKey: 'criteria-collaborators',
          onViewCollaborators: () =>
            console.debug('[CollaboratorsReach] View collaborators'),
          isFormEmpty,
        },
      });

    const handleOpen = () => {
      showCriteriaDrawer({
        ...args,
        children: <FormFields />,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          The drawer footer shows a loading skeleton inside the info alert.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Drawer
        </Button>
        {criteriaDrawer}
      </Stack>
    );
  },
  parameters: {
    docs: {
      description: {
        story:
          'Footer with loading state — shows a skeleton line inside the info alert.',
      },
    },
  },
};

export const CollaboratorsReachReady: Story = {
  render: args => {
    const { criteriaDrawer, showCriteriaDrawer } =
      useCriteriaDrawer<FormValues>({
        defaultValues: { name: 'Filled', description: '' },
        collaboratorsReach: {
          useCount: useMockCountReady,
          useService: useMockService,
          queryKey: 'criteria-collaborators',
          onViewCollaborators: () =>
            console.debug('[CollaboratorsReach] View collaborators'),
          isFormEmpty,
        },
      });

    const handleOpen = () => {
      showCriteriaDrawer({
        ...args,
        children: <FormFields />,
      });
    };

    return (
      <Stack gap={2}>
        <Typography variant="globalS">
          The drawer footer shows the collaborator count with a &quot;View
          collaborators&quot; action button. Clicking it opens the
          selected-collaborators drawer.
        </Typography>
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Drawer
        </Button>
        {criteriaDrawer}
      </Stack>
    );
  },
  parameters: {
    docs: {
      description: {
        story:
          'Footer with ready state — shows the total collaborator count and a "View collaborators" button that opens the selected-collaborators drawer.',
      },
    },
  },
};
