import { useState } from 'react';

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

import {
  Dialog,
  DialogLayerProvider,
  useDialogLayer,
  useDialogLayerItem,
} from '.';

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

export default meta;

type Story = StoryObj;

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

      return (
        <Stack spacing={2}>
          <Button
            variant="primary"
            onClick={() => {
              openDialog({
                title: 'Confirm action',
                textBody:
                  'If you leave now, your changes will be lost. Are you sure you want to continue?',
                primaryButtonProps: {
                  children: 'Continue',
                  onClick: () => {
                    console.log('Confirmed');
                    closeDialog();
                  },
                },
                secondaryButtonProps: {
                  children: 'Cancel',
                  onClick: () => closeDialog(),
                },
              });
            }}
          >
            Open Simple Dialog
          </Button>
        </Stack>
      );
    }

    return <Component />;
  },
};

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

      const { openDialog, closeDialog } = useDialogLayerItem(
        'reactive-dialog',
        {
          title: 'Confirm action',
          textBody:
            'This dialog uses useDialogLayerItem. When you click Continue, the button shows a loading state for a few seconds, then the dialog closes.',
          primaryButtonProps: {
            children: isLoading ? 'Loading...' : 'Continue',
            loading: isLoading,
            onClick: async () => {
              setIsLoading(true);
              await new Promise(resolve => setTimeout(resolve, 2500));
              closeDialog();
              setIsLoading(false);
            },
          },
          secondaryButtonProps: {
            children: 'Cancel',
            onClick: () => closeDialog(),
          },
        },
      );

      return (
        <Stack spacing={2}>
          <Button
            variant="primary"
            onClick={() => openDialog()}
          >
            Open Reactive Dialog
          </Button>
        </Stack>
      );
    }

    return <Component />;
  },
};

/**
 * Demonstrates nested dialogs combining all patterns:
 * - First dialog: Simple API with `useDialogLayer`
 * - Second dialog: Reactive state with `useDialogLayerItem`
 * - Third dialog: Composition API with custom layout
 */
export const NestedMixed: Story = {
  render: () => {
    function Component() {
      const { openDialog: openSimpleDialog, closeDialog } = useDialogLayer();

      const handleOpenFirst = () => {
        openSimpleDialog({
          title: 'First Dialog (Simple API)',
          textBody:
            'This is the first dialog using the simplest pattern. Click the button below to open the second dialog.',
          body: <SecondDialogButton />,
          primaryButtonProps: {
            children: 'Close',
            onClick: () => closeDialog(),
          },
          secondaryButtonProps: {
            children: 'Cancel',
            onClick: () => closeDialog(),
          },
        });
      };

      return (
        <Stack spacing={2}>
          <Button
            variant="primary"
            onClick={handleOpenFirst}
          >
            Open Nested Dialogs Demo
          </Button>
        </Stack>
      );

      function SecondDialogButton() {
        const [saveCount, setSaveCount] = useState(0);
        const [isSaving, setIsSaving] = useState(false);
        const {
          openDialog: openCompositionDialog,
          closeDialog: closeDialogLayer,
        } = useDialogLayer();

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

        const openThirdDialog = () => {
          openCompositionDialog({
            content: (
              <>
                <Dialog.Header
                  title="Third Dialog (Composition)"
                  onClose={closeDialogLayer}
                />
                <Dialog.Body>
                  <Stack spacing={2}>
                    <Stack
                      sx={{
                        p: 2,
                        bgcolor: 'warning.light',
                        borderRadius: 1,
                      }}
                    >
                      <strong>Pattern:</strong> Composition API (custom layout)
                    </Stack>
                    <p>
                      This dialog uses the Composition API for full control over
                      the layout.
                    </p>
                  </Stack>
                </Dialog.Body>
                <Dialog.Footer>
                  <Button
                    variant="tertiary"
                    onClick={() => closeDialogLayer()}
                  >
                    Cancel
                  </Button>
                  <Button
                    variant="primary"
                    onClick={() => closeDialogLayer()}
                  >
                    Done
                  </Button>
                </Dialog.Footer>
              </>
            ),
          });
        };

        const { openDialog: openReactiveDialog, closeDialog: closeReactive } =
          useDialogLayerItem('second-reactive', {
            title: 'Second Dialog (Reactive)',
            textBody: `This dialog has reactive state. Times saved: ${saveCount}. The Save button shows loading.`,
            body: (
              <Stack spacing={2}>
                <Button
                  variant="secondary"
                  onClick={openThirdDialog}
                >
                  Open Third Dialog (Composition)
                </Button>
              </Stack>
            ),
            primaryButtonProps: {
              children: isSaving ? 'Saving...' : 'Save',
              loading: isSaving,
              onClick: handleSave,
            },
            secondaryButtonProps: {
              children: 'Close',
              onClick: () => closeReactive(),
            },
          });

        return (
          <Button
            variant="primary"
            onClick={() => openReactiveDialog()}
          >
            Open Second Dialog (Reactive)
          </Button>
        );
      }
    }

    return <Component />;
  },
};
