import { useCallback, useState } from "react";

import { pxToRem } from "../../utils";
import { commonProps } from "../../utils/storybook";
import { Box } from "../box";
import { Button } from "../button";
import { Flex } from "../flex";
import { Link } from "../link";
import { Icons } from "../icons";
import { Input } from "../input";
import { Text } from "../text";
import { Breadcrumbs } from "./";

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

function generateRandomString(): string {
  const minLength = 5;
  const maxLength = 10;
  const length = Math.floor(Math.random() * (maxLength - minLength + 1)) + minLength;

  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";

  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * characters.length);
    result += characters.charAt(randomIndex);
  }

  return result;
}

const meta: Meta<typeof Breadcrumbs> = {
  title: "Breadcrumbs",
  component: Breadcrumbs,
  tags: ["autodocs"],
  argTypes: {
    crumbs: {
      table: {
        type: {
          detail: `
{linkElement: React.ReactElement<{href: string | UrlObject; children: string;}>; icon?: React.ReactElement;}[] |
{label: string; href: string; linkProps: LinkProps; icon?: React.ReactElement;}[]
          `,
        },
      },
    },
    iconPosition: {
      defaultValue: { summary: "start" },
      control: {
        type: "select",
        options: ["start", "end"],
      },
    },
    divider: {
      control: {
        type: "disable",
      },
    },
    crumbsListProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixNavigationMenu.List>",
        },
      },
    },
    subCrumbListContainerProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixNavigationMenu.Content>",
        },
      },
    },
    crumbItemProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixNavigationMenu.Item>",
        },
      },
    },
    subCrumbTriggerProps: {
      table: {
        category: "Anatomy Props",
        type: {
          summary: "React.ComponentProps<typeof RadixNavigationMenu.Trigger>",
        },
      },
    },
    ...commonProps,
  },
  args: {
    crumbs: [
      { label: "Crumb 1", href: "#1" },
      { label: "Crumb 2", href: "#2" },
      { label: "Crumb 3", href: "#3" },
    ],
  },
};

export default meta;

type Story = StoryObj<typeof Breadcrumbs>;

/**
 * Pass `crumbs` as `{label: string, href:string}[]` and each crumb will be wrapped with a [Link Component](/docs/link--docs). Each crumb can also optionally define some `LinkProps`
 */
export const Default: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};

/**
 * Pass `crumbs` as array of anchor tags if custom link implementation is needed.
 */
export const WithLinkElements: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};
WithLinkElements.args = {
  crumbs: [
    { linkElement: <Link href="#1">Crumb 1</Link> },
    { linkElement: <Link href="#2">Crumb 2</Link> },
    { linkElement: <Link href="#3">Crumb 3</Link> },
  ],
};
WithLinkElements.argTypes = { crumbs: { control: false } };

/**
 * Pass `crumbs` as array of buttons.
 */
export const WithButtonElements: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};
WithButtonElements.args = {
  crumbs: [
    {
      label: "Crumb 1",
      onClick: () => alert("crumb 1 clicked"),
    },
    {
      label: "Crumb 2",
      onClick: () => alert("crumb 2 clicked"),
    },
    {
      label: "Crumb 3",
      onClick: () => alert("crumb 3 clicked"),
    },
  ],
};

/**
 * The divider can be customised. Here it is passed as a `<Text>` component with a `/` as child.
 */
export const WithCustomDivider: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};

WithCustomDivider.args = {
  divider: (
    <Text variant="body4" css={{ color: "$off-white-72", userSelect: "none" }}>
      /
    </Text>
  ),
};

/**
 * Pass `Icon` to equip each crumb with an icon. If no color is specified the breadcrumbs will color the icon.
 */
export const WithUncontrolledIcons: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};

WithUncontrolledIcons.args = {
  crumbs: [
    { linkElement: <Link href="#1">Crumb 1</Link>, Icon: <Icons.InfoCircle /> },
    { linkElement: <Link href="#2">Crumb 2</Link>, Icon: <Icons.InfoCircle /> },
    { linkElement: <Link href="#3">Crumb 3</Link>, Icon: <Icons.InfoCircle /> },
  ],
};
WithUncontrolledIcons.argTypes = { crumbs: { control: false } };
/**
 * Pass `Icon` with an icon color specified to bypass breadcrumbs color handling.
 */
export const WithControlledIcons: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};

WithControlledIcons.args = {
  crumbs: [
    { linkElement: <Link href="#1">Crumb 1</Link>, Icon: <Icons.InfoCircle color="$dark-green" /> },
    { linkElement: <Link href="#2">Crumb 2</Link>, Icon: <Icons.InfoCircle color="$dark-green" /> },
    { linkElement: <Link href="#3">Crumb 3</Link>, Icon: <Icons.InfoCircle color="$dark-green" /> },
  ],
};
WithControlledIcons.argTypes = { crumbs: { control: false } };

/**
 * Resize the screen to trigger overflow.
 */
export const WithOverflow: Story = {
  render: (args) => (
    <Box css={{ width: "100%", border: "1px solid white" }}>
      <Breadcrumbs {...args} />
    </Box>
  ),
};

WithOverflow.args = {
  crumbs: [
    {
      label: `${generateRandomString()} 1`,
      href: "#1",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 2`,
      href: "#2",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 3`,
      href: "#3",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 4`,
      href: "#4",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 5`,
      href: "#5",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 6`,
      href: "#6",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 7`,
      href: "#7",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 8`,
      href: "#8",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 9`,
      href: "#9",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      label: `${generateRandomString()} 10`,
      href: "#10",
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
  ],
};
WithOverflow.argTypes = { crumbs: { control: false } };

/**
 * Add and subtract crumbs
 */
export const WithDynamicCrumbs: Story = {
  render: (args) => {
    const [crumbs, setCrumbs] = useState<typeof args.crumbs>([
      { label: `${generateRandomString()} 1`, href: `#1` },
    ]);
    const [px, setPx] = useState(0);

    const onAdd = useCallback(() => {
      setCrumbs((prev) => {
        return [
          ...prev,
          { label: `${generateRandomString()} ${prev.length + 1}`, href: `#${prev.length + 1}` },
        ];
      });
    }, []);

    const onRemove = useCallback(() => {
      setCrumbs((prev) => prev.slice(0, -1));
    }, []);

    const onPaddingChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
      setPx(parseInt(e.target.value));
    }, []);

    return (
      <Flex
        css={{
          width: "500px",
          flexDirection: "column",
          gap: "$2",
          p: "$2",
          border: "1px solid white",
        }}
      >
        <Breadcrumbs {...args} crumbs={crumbs} css={{ px: pxToRem(px), zIndex: 1 }} />
        <Flex gap="2">
          <Button onClick={onAdd}>Add Crumb</Button>
          <Button onClick={onRemove}>Remove Crumb</Button>
        </Flex>

        <Input type="number" label="Set x padding" onChange={onPaddingChange} />
      </Flex>
    );
  },
};
WithDynamicCrumbs.argTypes = {
  crumbs: {
    control: false,
  },
};

/**
 * Resize the screen to trigger overflow.
 */
export const WithOverflowAndCustomLinks: Story = {
  render: (args) => (
    <Box css={{ width: "100%", border: "1px solid white" }}>
      <Breadcrumbs {...args} />
    </Box>
  ),
};

WithOverflowAndCustomLinks.args = {
  crumbs: [
    {
      linkElement: <Link href="#1">{generateRandomString()} 1</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#2">{generateRandomString()} 2</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#3">{generateRandomString()} 3</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#4">{generateRandomString()} 4</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#5">{generateRandomString()} 5</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#6">{generateRandomString()} 6</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#7">{generateRandomString()} 7</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#8">{generateRandomString()} 8</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#9">{generateRandomString()} 9</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
    {
      linkElement: <Link href="#10">{generateRandomString()} 10</Link>,
      Icon: <Icons.InfoCircle color="$dark-green" />,
    },
  ],
};
WithOverflowAndCustomLinks.argTypes = { crumbs: { control: false } };

/**
 * A crumb can be Icon only.
 */
export const IconOnly: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};

IconOnly.args = {
  crumbs: [
    {
      label: "",
      Icon: <Icons.Placeholder />,
      href: "#1",
    },
    { label: "Crumb 2", href: "#2" },
    { label: "Very longggggggggggggggggggggggggg Crumb 3", href: "#3" },
  ],
};
IconOnly.argTypes = { crumbs: { control: false } };

/**
 * Assign only the label prop if you want convey to the user that the crumb is non-interactive.
 */
export const LabelOnlyCrumb: Story = {
  render: (args) => <Breadcrumbs {...args} />,
};

LabelOnlyCrumb.args = {
  crumbs: [
    { label: "Text Only Crumb 1" },
    { label: "Text Only Crumb 2" },
    { label: "Text Only Crumb 3" },
  ],
};
