import { useCallback, useState } from "react";

import { Box } from "../box";
import { Text } from "../text";
import { Button } from "../button";
import { commonProps } from "../../utils/storybook";
import { Accordion } from "./";

import type { Meta, StoryObj } from "@storybook/react";
import type { AccordionItemsProps } from ".";

const mockAccordionItem: AccordionItemsProps = [
  {
    value: "1",
    header: <Text variant="h4">Header 1</Text>,
    body: (
      <Text variant="body2">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
        labore et dolore magna aliqua. Ut enim ad minim veniam
      </Text>
    ),
  },
  {
    value: "2",
    header: <Text variant="h4">Header 2</Text>,
    body: (
      <Text variant="body2">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
        labore et dolore magna aliqua. Ut enim ad minim veniam
      </Text>
    ),
  },
  {
    value: "3",
    header: <Text variant="h4">Header 3</Text>,
    body: (
      <Text variant="body2">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
        labore et dolore magna aliqua. Ut enim ad minim veniam
      </Text>
    ),
  },
];

const meta: Meta<typeof Accordion> = {
  title: "Accordion",
  component: Accordion,
  tags: ["autodocs"],
  argTypes: {
    type: {
      options: ["single", "multiple"],
      control: { type: "select" },
      table: {
        defaultValue: {
          summary: "single",
        },
      },
      description: "Determines whether one or multiple items can be opened at the same time.",
    },
    items: {
      control: false,
      table: {
        type: {
          summary: `Array<React.ComponentProps<typeof AccordionPrimitive.Item> & {
            header: React.ReactElement;
            body: React.ReactElement;
          }>`,
        },
      },
    },
    asChild: {
      description:
        "Change the default rendered element for the one passed as a child, merging their props and behavior.",
      control: false,
      table: {
        defaultValue: {
          summary: "false",
        },
      },
    },
    headerProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixAccordion.Header>",
        },
      },
    },
    triggerProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixAccordion.Trigger>",
        },
      },
    },
    contentProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixAccordion.Content>",
        },
      },
    },
    ...commonProps,
  },
  args: { type: "single", items: mockAccordionItem },
};

export default meta;

type Story = StoryObj<typeof Accordion>;

export const Uncontrolled: Story = {
  render: (args) => (
    <Box css={{ backgroundColor: "#fff", p: "$4" }}>
      <Accordion {...args} />
    </Box>
  ),
};

export const Controlled: Story = {
  render: (args) => {
    const [current, setCurrent] = useState<string | string[]>(args.type === "single" ? "" : []);

    const onClick = useCallback(() => {
      setCurrent((prev) => {
        const parsedPrev = Number(prev);
        const nextValue = isNaN(parsedPrev) ? 1 : parsedPrev < 3 ? parsedPrev + 1 : 0;
        return nextValue ? nextValue.toString() : "";
      });
    }, []);

    const toggleValue = (value: string) => {
      setCurrent((prev) => {
        const index = prev.indexOf(value);

        if (index === -1) {
          return [...prev, value];
        }

        const copy = [...prev];
        copy.splice(index, 1);
        return copy;
      });
    };
    return (
      <Box css={{ backgroundColor: "#fff", p: "$4" }}>
        {/* @ts-expect-error value props will match `type` */}
        <Accordion {...args} value={current} onValueChange={setCurrent} />

        <Box>
          {args.type === "single" ? (
            <Button onClick={onClick}>Cycle</Button>
          ) : (
            <>
              <Button onClick={() => toggleValue("1")}>Toggle Header 1</Button>
              <Button onClick={() => toggleValue("2")}>Toggle Header 2</Button>
              <Button onClick={() => toggleValue("3")}>Toggle Header 3</Button>
            </>
          )}
        </Box>
      </Box>
    );
  },
};
