import type { Meta, StoryObj } from '@storybook/react';
import Drawer, { useDrawer } from '../index.js';
import { DrawerProps } from '../types.js';
import { withDrawerStyles, buttonStyle } from './DrawerDecorator.js';
import { SBContainer } from '@sb-utils/SBContainer.js';
import type { CSSVariables } from '../../utils/types.js';

const meta: Meta<DrawerProps> = {
  title: 'Component Library/Drawer',
  component: Drawer,
  parameters: {
    layout: 'fullscreen',
    docs: {
      description: {
        component: `The Drawer component provides a slide-out panel that overlays content from the side, top, or bottom of the viewport. It supports customizable directions, sizes, overlay control, and full-screen mode. Use the \`useDrawer\` hook for state management.`,
      },
      story: {
        inline: false,
        iframeHeight: 500,
      },
    },
  },
  decorators: [withDrawerStyles],
};

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
  render: () => {
    const { isOpen, open, close } = useDrawer();

    return (
      <SBContainer flex direction="column" gap="medium">
        <button type="button" style={buttonStyle} onClick={open}>
          Open Drawer
        </button>
        <Drawer
          open={isOpen}
          direction="right"
          onOverlayClick={close}
          aria-label="Default drawer"
        >
          <SBContainer padding="large">
            <h2>Drawer Content</h2>
            <p>This is the default drawer sliding in from the right.</p>
            <button type="button" style={buttonStyle} onClick={close}>
              Close
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};

export const Directions: Story = {
  name: 'Direction Options',
  render: () => {
    const rightDrawer = useDrawer();
    const leftDrawer = useDrawer();
    const topDrawer = useDrawer();
    const bottomDrawer = useDrawer();

    return (
      <SBContainer flex direction="column" gap="large">
        <SBContainer addBackground flex direction="row" gap="medium">
          <button type="button" style={buttonStyle} onClick={rightDrawer.open}>
            Right Drawer
          </button>
          <button type="button" style={buttonStyle} onClick={leftDrawer.open}>
            Left Drawer
          </button>
          <button type="button" style={buttonStyle} onClick={topDrawer.open}>
            Top Drawer
          </button>
          <button type="button" style={buttonStyle} onClick={bottomDrawer.open}>
            Bottom Drawer
          </button>
        </SBContainer>

        <Drawer
          open={rightDrawer.isOpen}
          direction="right"
          onOverlayClick={rightDrawer.close}
          aria-label="Right drawer"
        >
          <SBContainer padding="large">
            <h2>Right Drawer</h2>
            <p>Slides in from the right side of the screen.</p>
            <button
              type="button"
              style={buttonStyle}
              onClick={rightDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={leftDrawer.isOpen}
          direction="left"
          onOverlayClick={leftDrawer.close}
          aria-label="Left drawer"
        >
          <SBContainer padding="large">
            <h2>Left Drawer</h2>
            <p>Slides in from the left side of the screen.</p>
            <button
              type="button"
              style={buttonStyle}
              onClick={leftDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={topDrawer.isOpen}
          direction="top"
          onOverlayClick={topDrawer.close}
          aria-label="Top drawer"
        >
          <SBContainer padding="large">
            <h2>Top Drawer</h2>
            <p>Slides in from the top of the screen.</p>
            <button type="button" style={buttonStyle} onClick={topDrawer.close}>
              Close
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={bottomDrawer.isOpen}
          direction="bottom"
          onOverlayClick={bottomDrawer.close}
          aria-label="Bottom drawer"
        >
          <SBContainer padding="large">
            <h2>Bottom Drawer</h2>
            <p>Slides in from the bottom of the screen.</p>
            <button
              type="button"
              style={buttonStyle}
              onClick={bottomDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};

export const Sizes: Story = {
  name: 'Size Variations',
  render: () => {
    const smallDrawer = useDrawer();
    const mediumDrawer = useDrawer();
    const largeDrawer = useDrawer();
    const fullScreenDrawer = useDrawer();

    return (
      <SBContainer flex direction="column" gap="large">
        <SBContainer addBackground flex direction="row" gap="medium">
          <button type="button" style={buttonStyle} onClick={smallDrawer.open}>
            Small (250px)
          </button>
          <button type="button" style={buttonStyle} onClick={mediumDrawer.open}>
            Medium (400px)
          </button>
          <button type="button" style={buttonStyle} onClick={largeDrawer.open}>
            Large (600px)
          </button>
          <button
            type="button"
            style={buttonStyle}
            onClick={fullScreenDrawer.open}
          >
            Full Screen
          </button>
        </SBContainer>

        <Drawer
          open={smallDrawer.isOpen}
          direction="right"
          size="250px"
          onOverlayClick={smallDrawer.close}
          aria-label="Small drawer"
        >
          <SBContainer padding="large">
            <h3>Small Drawer</h3>
            <p>Width: 250px</p>
            <button
              type="button"
              style={buttonStyle}
              onClick={smallDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={mediumDrawer.isOpen}
          direction="right"
          size="400px"
          onOverlayClick={mediumDrawer.close}
          aria-label="Medium drawer"
        >
          <SBContainer padding="large">
            <h3>Medium Drawer</h3>
            <p>Width: 400px</p>
            <button
              type="button"
              style={buttonStyle}
              onClick={mediumDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={largeDrawer.isOpen}
          direction="right"
          size="600px"
          onOverlayClick={largeDrawer.close}
          aria-label="Large drawer"
        >
          <SBContainer padding="large">
            <h3>Large Drawer</h3>
            <p>Width: 600px</p>
            <button
              type="button"
              style={buttonStyle}
              onClick={largeDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={fullScreenDrawer.isOpen}
          direction="right"
          fullScreen
          onOverlayClick={fullScreenDrawer.close}
          aria-label="Full screen drawer"
        >
          <SBContainer padding="extralarge" flex direction="column" gap="large">
            <h1>Full Screen Drawer</h1>
            <p>
              This drawer takes up the entire screen, useful for forms, detailed
              content, or focused tasks.
            </p>
            <p>
              The fullScreen prop overrides the size prop and makes the drawer
              fill the viewport.
            </p>
            <button
              type="button"
              style={buttonStyle}
              onClick={fullScreenDrawer.close}
            >
              Close
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};

export const WithoutOverlay: Story = {
  name: 'Without Overlay',
  render: () => {
    const { isOpen, close, toggle } = useDrawer();

    return (
      <SBContainer flex direction="column" gap="medium">
        <SBContainer addBackground>
          <h4>Drawer Without Overlay</h4>
          <p>
            Set showOverlay to false to remove the dark backdrop. The drawer
            will not close when clicking outside.
          </p>
          <button type="button" style={buttonStyle} onClick={toggle}>
            {isOpen ? 'Close' : 'Open'} Drawer
          </button>
        </SBContainer>

        <Drawer
          open={isOpen}
          direction="right"
          showOverlay={false}
          aria-label="Drawer without overlay"
        >
          <SBContainer padding="large">
            <h3>No Overlay</h3>
            <p>Background content remains visible and interactive.</p>
            <button type="button" style={buttonStyle} onClick={close}>
              Close
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};

export const KeyboardInteraction: Story = {
  name: 'Keyboard Interaction',
  render: () => {
    const { isOpen, open, close } = useDrawer();

    return (
      <SBContainer flex direction="column" gap="medium">
        <SBContainer addBackground>
          <h4>Keyboard Support</h4>
          <p>Press ESC to close the drawer when it is open</p>
          <button type="button" style={buttonStyle} onClick={open}>
            Open Drawer
          </button>
        </SBContainer>

        <Drawer
          open={isOpen}
          direction="right"
          onOverlayClick={close}
          aria-label="Keyboard interactive drawer"
        >
          <SBContainer padding="large">
            <h3>Keyboard Accessible</h3>
            <p>
              This drawer can be closed by pressing the <strong>ESC</strong> key
              or clicking the overlay.
            </p>
            <p style={{ marginTop: '16px' }}>
              Try pressing ESC on your keyboard to close this drawer.
            </p>
            <button type="button" style={buttonStyle} onClick={close}>
              Or Click to Close
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};

export const BodyScrollLock: Story = {
  name: 'Body Scroll Lock',
  render: () => {
    const { isOpen, open, close } = useDrawer();

    return (
      <SBContainer padding="large" style={{ minHeight: '200vh' }}>
        <SBContainer addBackground>
          <h4>Background Scroll Prevention</h4>
          <p>
            When the drawer is open, the background page scroll is locked to
            prevent scrolling behind the overlay.
          </p>
          <p style={{ marginTop: '16px' }}>
            This page has a long scrollable body. Scroll down and open the
            drawer from any section - the background scroll will be locked.
          </p>
        </SBContainer>

        {Array.from({ length: 20 }, (_, i) => (
          <SBContainer
            key={i}
            padding="large"
            addBackground
            style={{
              margin: '16px 0',
            }}
          >
            <h3>Background Content Section {i + 1}</h3>
            <p>
              This is scrollable content on the main page. When the drawer is
              open, you should not be able to scroll this content.
            </p>
            <button
              type="button"
              style={{ ...buttonStyle, marginTop: '12px' }}
              onClick={open}
            >
              Open Drawer
            </button>
          </SBContainer>
        ))}

        <Drawer
          open={isOpen}
          direction="right"
          onOverlayClick={close}
          aria-label="Drawer with scroll lock"
        >
          <SBContainer padding="large">
            <h3>Drawer Content</h3>
            <p>The background scroll is now locked.</p>
            <p style={{ marginTop: '16px' }}>
              Try scrolling the page - it should be prevented. The body element
              has <code>overflow: hidden</code> applied when the drawer is open.
            </p>
            <button type="button" style={buttonStyle} onClick={close}>
              Close Drawer
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};

export const NestedDrawers: Story = {
  name: 'Nested Drawers',
  render: () => {
    const parentDrawer = useDrawer();
    const childDrawer = useDrawer();

    const childDrawerStyle: CSSVariables = {
      '--hscl-drawer-zIndex': '1001',
      '--hscl-drawer-overlay-zIndex': '1000',
    };

    return (
      <SBContainer flex direction="column" gap="medium">
        <SBContainer addBackground>
          <h4>Nested Drawer Example</h4>
          <p>
            This example demonstrates opening a second drawer from within the
            first drawer. Use this pattern carefully - only when necessary for
            complex workflows.
          </p>
          <button
            type="button"
            style={{ ...buttonStyle, marginTop: '16px' }}
            onClick={parentDrawer.open}
          >
            Open Parent Drawer
          </button>
        </SBContainer>

        <Drawer
          open={parentDrawer.isOpen}
          direction="right"
          size="400px"
          onOverlayClick={parentDrawer.close}
          aria-label="Parent drawer"
        >
          <SBContainer padding="large">
            <h2>Parent Drawer</h2>
            <p>This is the first level drawer.</p>
            <p style={{ marginTop: '16px' }}>
              Click the button below to open a second drawer on top of this one:
            </p>
            <button
              type="button"
              style={{ ...buttonStyle, marginTop: '16px' }}
              onClick={childDrawer.open}
            >
              Open Child Drawer
            </button>
            <button
              type="button"
              style={{
                ...buttonStyle,
                marginTop: '16px',
                marginLeft: '12px',
                backgroundColor: '#666',
              }}
              onClick={parentDrawer.close}
            >
              Close Parent
            </button>
          </SBContainer>
        </Drawer>

        <Drawer
          open={childDrawer.isOpen}
          direction="bottom"
          fullScreen
          onOverlayClick={childDrawer.close}
          aria-label="Child drawer"
          style={childDrawerStyle}
        >
          <SBContainer padding="large">
            <h2>Child Drawer</h2>
            <p>This drawer opened from within the parent drawer.</p>
            <p style={{ marginTop: '16px' }}>
              Notice how it appears on top with a higher z-index. Close this
              drawer to return to the parent.
            </p>
            <button
              type="button"
              style={{ ...buttonStyle, marginTop: '16px' }}
              onClick={childDrawer.close}
            >
              Close Child
            </button>
          </SBContainer>
        </Drawer>
      </SBContainer>
    );
  },
};
