import type { Meta, StoryObj } from "@storybook/react";
import { useEffect } from "react";
import { Button } from "../Button";
import { Flex } from "../Flex";
import { Stack } from "../Stack";
import { Text } from "../Text";
import { toast } from "./Toast";
import { Toaster } from "./Toaster";
import type { ToasterProps } from "./Toaster";
import { excludeControls } from "../../utils";

type StoryType = StoryObj<typeof Toaster>;

const meta: Meta<typeof Toaster> = {
  title: "Components/Toast",
  component: Toaster,
  argTypes: {
    position: {
      control: { type: "select" },
      options: [
        "top-left",
        "top-center",
        "top-right",
        "bottom-left",
        "bottom-center",
        "bottom-right",
      ],
    },
    ...excludeControls("toastOptions", "theme", "icons", "dir", "hotkey"),
  },
  parameters: {
    docs: {
      description: {
        component:
          "Toast notifications for displaying brief, non-blocking messages. Built on Sonner.",
      },
    },
  },
};

export default meta;

export const Default: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button onClick={() => toast.info("This is an info toast")}>
        Show Toast
      </Button>
    </>
  ),
  args: {
    position: "top-right",
    closeButton: true,
    expand: false,
    duration: 4000,
    visibleToasts: 3,
  },
  play: () => {
    toast.info("This is an info toast");
  },
};

export const Info: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button
        onClick={() => toast.info("Your session will expire in 5 minutes")}
      >
        Show Info Toast
      </Button>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.info("Your session will expire in 5 minutes");
  },
};

export const Success: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button onClick={() => toast.success("Your changes have been saved")}>
        Show Success Toast
      </Button>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.success("Your changes have been saved");
  },
};

export const Warning: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button
        onClick={() =>
          toast.warning("Please review your input before continuing")
        }
      >
        Show Warning Toast
      </Button>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.warning("Please review your input before continuing");
  },
};

export const ErrorVariant: StoryType = {
  name: "Error",
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button
        onClick={() => toast.error("Something went wrong. Please try again.")}
      >
        Show Error Toast
      </Button>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.error("Something went wrong. Please try again.");
  },
};

export const WithTitle: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button
        onClick={() =>
          toast.success("Your quote has been saved and sent to your email.", {
            title: "Quote saved",
          })
        }
      >
        Show Toast with Title
      </Button>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.success("Your quote has been saved and sent to your email.", {
      title: "Quote saved",
    });
  },
};

export const WithActions: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Button
        onClick={() =>
          toast.info("Would you like to save your progress?", {
            title: "Save progress",
            action: {
              label: "Save",
              onClick: () => console.log("Saved!"),
            },
            cancel: {
              label: "Discard",
              onClick: () => console.log("Discarded!"),
            },
          })
        }
      >
        Show Toast with Actions
      </Button>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.info("Would you like to save your progress?", {
      title: "Save progress",
      action: {
        label: "Save",
        onClick: () => console.log("Saved!"),
      },
      cancel: {
        label: "Discard",
        onClick: () => console.log("Discarded!"),
      },
    });
  },
};

export const AllVariants: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <Stack gap="sm">
        <Button onClick={() => toast.info("This is an info message")}>
          Info
        </Button>
        <Button onClick={() => toast.success("This is a success message")}>
          Success
        </Button>
        <Button onClick={() => toast.warning("This is a warning message")}>
          Warning
        </Button>
        <Button onClick={() => toast.error("This is an error message")}>
          Error
        </Button>
      </Stack>
    </>
  ),
  args: {
    position: "top-right",
  },
  play: () => {
    toast.info("This is an info message");
    toast.success("This is a success message");
    toast.warning("This is a warning message");
    toast.error("This is an error message");
  },
};

const InteractiveDemoComponent = () => {
  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.key === "r" || e.key === "R") {
        const random = Math.floor(Math.random() * 4);
        switch (random) {
          case 0:
            toast.info("This is an info toast");
            break;
          case 1:
            toast.success("Operation completed successfully");
            break;
          case 2:
            toast.warning("Please check your input");
            break;
          default:
            toast.error("Something went wrong");
        }
      }
    };
    window.addEventListener("keydown", handler);
    return () => window.removeEventListener("keydown", handler);
  }, []);

  return (
    <Stack gap="md">
      <Text>Press &apos;R&apos; to show a random toast</Text>
      <Flex gap="sm">
        <Button onClick={() => toast.info("Info toast")}>Info</Button>
        <Button onClick={() => toast.success("Success toast")}>Success</Button>
        <Button onClick={() => toast.warning("Warning toast")}>Warning</Button>
        <Button onClick={() => toast.error("Error toast")}>Error</Button>
      </Flex>
    </Stack>
  );
};

export const InteractiveDemo: StoryType = {
  render: (args: ToasterProps) => (
    <>
      <Toaster {...args} />
      <InteractiveDemoComponent />
    </>
  ),
  args: {
    position: "top-right",
  },
};
