import { useState } from 'react';

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

import { DialogLayerProvider, useDialogLayer } from '../Dialogs';

import {
  Drawer,
  DrawerLayerProvider,
  useDrawerLayer,
  useDrawerLayerItem,
} from '.';

const meta: Meta = {
  title: 'Layers/Drawers',
  decorators: [
    Story => (
      <DialogLayerProvider>
        <DrawerLayerProvider>
          <Story />
        </DrawerLayerProvider>
      </DialogLayerProvider>
    ),
  ],
  tags: ['autodocs'],
};

export default meta;

type Story = StoryObj;

/**
 * The simplest way to use the Drawer layer.
 * Uses `useDrawerLayer` hook with the Simple API (props-based).
 */
export const Simple: Story = {
  render: () => {
    function Component() {
      const { openDrawer, closeDrawer } = useDrawerLayer();

      const handleOpen = () => {
        openDrawer({
          title: 'Simple Drawer',
          children: (
            <Stack sx={{ gap: 2 }}>
              <Typography>
                This is the simplest implementation of a drawer.
              </Typography>
              <Typography
                variant="body2"
                color="text.secondary"
              >
                Use this pattern for simple, one-off drawers that don't need
                reactive state updates.
              </Typography>
            </Stack>
          ),
          primaryButtonProps: {
            children: 'Confirm',
            onClick: () => {
              console.log('Confirmed!');
              closeDrawer();
            },
          },
          secondaryButtonProps: {
            children: 'Cancel',
            onClick: () => closeDrawer(),
          },
          wrapperProps: {
            PaperProps: {
              sx: {
                '*': {
                  backgroundColor: 'red',
                },
              },
            },
          },
        });
      };

      return (
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open Simple Drawer
        </Button>
      );
    }

    return <Component />;
  },
};

/**
 * Drawer with reactive state using `useDrawerLayerItem`.
 * The drawer configuration automatically stays in sync with component state.
 */
export const ReactiveState: Story = {
  render: () => {
    function Component() {
      const [isLoading, setIsLoading] = useState(false);
      const [counter, setCounter] = useState(0);

      const handleSubmit = async () => {
        setIsLoading(true);
        await new Promise(resolve => setTimeout(resolve, 1500));
        setCounter(prev => prev + 1);
        setIsLoading(false);
        closeDrawer();
      };

      const { openDrawer, closeDrawer } = useDrawerLayerItem('reactive-demo', {
        title: 'Reactive Drawer',
        children: (
          <Stack sx={{ gap: 2 }}>
            <Typography>
              This drawer uses <code>useDrawerLayerItem</code> for reactive
              state.
            </Typography>

            <Stack
              sx={{
                p: 2,
                bgcolor: 'info.light',
                borderRadius: 1,
              }}
            >
              <Typography variant="body2">
                <strong>Counter value:</strong> {counter}
              </Typography>
              <Typography variant="body2">
                <strong>Loading state:</strong> {isLoading ? 'Yes' : 'No'}
              </Typography>
            </Stack>

            <Typography
              variant="body2"
              color="text.secondary"
            >
              Notice how the button loading state updates automatically when you
              click "Save". The drawer config stays in sync with component
              state.
            </Typography>

            <Button
              variant="secondary"
              onClick={() => setCounter(prev => prev + 1)}
            >
              Increment Counter (currently: {counter})
            </Button>
          </Stack>
        ),
        primaryButtonProps: {
          children: 'Save',
          loading: isLoading,
          onClick: handleSubmit,
        },
        secondaryButtonProps: {
          children: 'Cancel',
          onClick: () => {
            closeDrawer();
          },
        },
        footer: (
          <Typography variant="caption">Submissions: {counter}</Typography>
        ),
      });

      return (
        <Stack sx={{ gap: 2 }}>
          <Typography
            variant="body2"
            color="text.secondary"
          >
            Total submissions: {counter}
          </Typography>
          <Button
            variant="primary"
            onClick={() => openDrawer()}
          >
            Open Reactive Drawer
          </Button>
        </Stack>
      );
    }

    return <Component />;
  },
};

/**
 * Demonstrates the Task Focus toggle in a drawer opened via the Drawer Layer.
 * Pass `enableTaskFocus: true` to show the maximize/restore button in the header;
 * clicking it toggles fullscreen (task focus) mode.
 */
export const TaskFocusEnabled: Story = {
  render: () => {
    function Component() {
      const { openDrawer, closeDrawer } = useDrawerLayer();

      const handleOpen = () => {
        openDrawer({
          title: 'Drawer with Task Focus',
          enableTaskFocus: true,
          anchor: 'bottom',
          extraHeaderActions: (
            <ButtonGroup
              labels={['List', 'Grid', 'Map']}
              defaultValue={0}
              onChange={value => console.log('Selected index:', value)}
            />
          ),
          children: (
            <Stack sx={{ gap: 2 }}>
              <Typography>
                Use the maximize icon in the header to toggle task focus
                (fullscreen) mode. The drawer will expand to fullscreen with no
                rounded corners.
              </Typography>
            </Stack>
          ),
          primaryButtonProps: {
            children: 'Confirm',
            onClick: () => closeDrawer(),
          },
          secondaryButtonProps: {
            children: 'Cancel',
            onClick: () => closeDrawer(),
          },
        });
      };

      return (
        <Button
          variant="primary"
          onClick={handleOpen}
        >
          Open drawer (Task Focus toggle)
        </Button>
      );
    }

    return <Component />;
  },
};

/**
 * Demonstrates nested drawers combining all patterns:
 * - First drawer: Simple API with `useDrawerLayer`
 * - Second drawer: Reactive state with `useDrawerLayerItem`
 * - Third drawer: Composition API with custom layout
 * - Dialog confirmation on close
 */
export const NestedMixed: Story = {
  render: () => {
    function Component() {
      const { openDrawer: openSimpleDrawer, closeDrawer } = useDrawerLayer();

      const handleOpenFirst = () => {
        openSimpleDrawer({
          title: 'First Drawer (Simple API)',
          children: (
            <Stack sx={{ gap: 2 }}>
              <Stack sx={{ p: 2, bgcolor: 'info.light', borderRadius: 1 }}>
                <Typography variant="body2">
                  <strong>Pattern:</strong> useDrawerLayer + Simple API
                </Typography>
              </Stack>
              <Typography>
                This is the first drawer using the simplest pattern.
              </Typography>
              <SecondDrawerButton />
            </Stack>
          ),
          primaryButtonProps: {
            children: 'Close',
            onClick: () => closeDrawer(),
          },
        });
      };

      return (
        <Stack sx={{ gap: 2 }}>
          <Typography
            variant="body2"
            color="text.secondary"
          >
            Opens a stack of 3 drawers, each using a different pattern, plus a
            Dialog confirmation.
          </Typography>
          <Button
            variant="primary"
            onClick={handleOpenFirst}
          >
            Open Nested Drawers Demo
          </Button>
        </Stack>
      );

      function SecondDrawerButton() {
        const [saveCount, setSaveCount] = useState(0);
        const [isSaving, setIsSaving] = useState(false);

        const handleSave = async () => {
          setIsSaving(true);
          await new Promise(resolve => setTimeout(resolve, 1000));
          setSaveCount(prev => prev + 1);
          setIsSaving(false);
        };

        const { openDrawer: openReactiveDrawer, closeDrawer: closeReactive } =
          useDrawerLayerItem('second-reactive', {
            title: 'Second Drawer (Reactive)',
            children: (
              <Stack sx={{ gap: 2 }}>
                <Stack sx={{ p: 2, bgcolor: 'success.light', borderRadius: 1 }}>
                  <Typography variant="body2">
                    <strong>Pattern:</strong> useDrawerLayerItem (reactive
                    state)
                  </Typography>
                </Stack>
                <Typography>
                  This drawer has reactive state. The save button shows loading
                  state.
                </Typography>
                <Typography variant="body2">
                  Times saved: <strong>{saveCount}</strong>
                </Typography>
                <ThirdDrawerButton />
              </Stack>
            ),
            primaryButtonProps: {
              children: isSaving ? 'Saving...' : 'Save',
              loading: isSaving,
              onClick: handleSave,
            },
            secondaryButtonProps: {
              children: 'Cancel',
              onClick: () => closeReactive(),
            },
          });

        return (
          <Button
            variant="secondary"
            onClick={() => openReactiveDrawer()}
          >
            Open Second Drawer (Reactive)
          </Button>
        );
      }

      function ThirdDrawerButton() {
        const {
          openDrawer: openCompositionDrawer,
          closeDrawer: closeComposition,
        } = useDrawerLayer();
        const {
          openDialog: openConfirmDialog,
          closeDialog: closeConfirmDialog,
        } = useDialogLayer();

        const handleCloseWithConfirmation = () => {
          openConfirmDialog({
            title: 'Close drawer?',
            textBody:
              'This demonstrates how Dialog integrates with Drawer. Both use the same layer pattern.',
            primaryButtonProps: {
              children: 'Yes, close',
              onClick: () => {
                closeConfirmDialog();
                closeComposition();
              },
            },
            secondaryButtonProps: {
              children: 'Cancel',
              onClick: () => closeConfirmDialog(),
            },
          });
        };

        const handleOpen = () => {
          openCompositionDrawer({
            content: (
              <>
                <Drawer.Header
                  title="Third Drawer (Composition)"
                  onClose={handleCloseWithConfirmation}
                  hasBackButton
                  onBack={closeComposition}
                />
                <Drawer.Body>
                  <Stack sx={{ gap: 2 }}>
                    <Stack
                      sx={{ p: 2, bgcolor: 'warning.light', borderRadius: 1 }}
                    >
                      <Typography variant="body2">
                        <strong>Pattern:</strong> Composition API (custom
                        layout)
                      </Typography>
                    </Stack>
                    <Typography>
                      This drawer uses the Composition API for full control over
                      the layout.
                    </Typography>
                    <Typography
                      variant="body2"
                      color="text.secondary"
                    >
                      Click the X button to see the Dialog confirmation.
                    </Typography>
                  </Stack>
                </Drawer.Body>
                <Drawer.Footer>
                  <Stack sx={{ p: 1, bgcolor: 'grey.100', borderRadius: 1 }}>
                    <Typography variant="caption">
                      Custom footer using Drawer.Footer
                    </Typography>
                  </Stack>
                </Drawer.Footer>
                <Drawer.Actions>
                  <Button
                    variant="tertiary"
                    onClick={handleCloseWithConfirmation}
                  >
                    Cancel
                  </Button>
                  <Button
                    variant="primary"
                    onClick={() => closeComposition()}
                  >
                    Done
                  </Button>
                </Drawer.Actions>
              </>
            ),
          });
        };

        return (
          <Button
            variant="secondary"
            onClick={handleOpen}
          >
            Open Third Drawer (Composition)
          </Button>
        );
      }
    }

    return <Component />;
  },
};
