import { faker } from "@faker-js/faker"
import { wait } from "@opensea/testing-utils/wait"
import {
  Card,
  FlexColumn,
  Grid,
  GridProps,
  Skeleton,
  SkeletonBlock,
  Text,
} from "@opensea/ui-kit"
import { useItemsWithSkeletons } from "@opensea/ui-kit/hooks"
import { Meta, StoryObj } from "@storybook/react"
import React, { memo, useState } from "react"
import { Image } from "./Image"
import { IMAGE_URLS_AND_HASHES } from "./mock"

type Story = StoryObj<typeof Image>

const meta: Meta<typeof Image> = {
  title: "Design System/Image",
  component: Image,
  args: {
    alt: "Nice image",
  },
}

export default meta

export const Original: Story = {
  args: {
    original: true,
    src: "https://i2.seadn.io/ethereum/0xbd3531da5cf5857e7cfaa92426877b022e612cf8/28788fc3bd769b396cd74a6c53e68ae9.png",
    className: "flex",
  },
}

export const VideoFrame: Story = {
  args: {
    frameTime: 1,
    src: "https://i2.dev.seadn.io/earth.mp4",
    width: 1000,
  },
}

export const Blurhash: Story = {
  args: {
    blurhash: "LtJvsaoMPqbHXRW=aMn$pIn%aJW;",
    src: "https://i2.dev.seadn.io/ethereum/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/627815701c4280ddb3f5971616a20d5a.png",
    width: 1000,
  },
}

export const Fill: Story = {
  render: function Render() {
    const images = [
      "https://i2.seadn.io/ethereum/59c0d41c675e4f7baf2abc70866dc0f1/26e3de0f309089cbb1e5ab969fc0bc/8a26e3de0f309089cbb1e5ab969fc0bc.png",
      "https://i2.seadn.io/ethereum/535fc68f536649a39f45b926db2cf4dd/12374123ac5e8571b01d03874e8a76/ff12374123ac5e8571b01d03874e8a76.png",
      "https://i2.seadn.io/ethereum/dff7c9f1e5e64b2fbf4ca977d4867236/b000858106506fccba695f90c3a7fc/2fb000858106506fccba695f90c3a7fc.jpeg",
      "https://i2.seadn.io/ethereum/2f3fe96db3764959af78f4f783dbe1b5/655fc54f4f95819d23d65dbb346edb/99655fc54f4f95819d23d65dbb346edb.jpeg",
      "https://i2.seadn.io/ethereum/17a01d0611784673b805d3edcddd8595/448fe425d5e5e2bd44ded754865f37/62448fe425d5e5e2bd44ded754865f37.png",
    ]
    return (
      <FlexColumn className="gap-4">
        {images.map(image => (
          <div className="relative h-[500px] w-full" key={image}>
            <Image className="object-cover" layout="fill" src={image} />
          </div>
        ))}
      </FlexColumn>
    )
  },
}

export const Boost: Story = {
  args: {
    src: "https://i2.dev.seadn.io/ethereum/0x5af0d9827e0c53e4799bb226655a1de152a425a5/28bac4238ec3d45941c3e029abe8a124.png",
    width: 24,
    height: 24,
    boost: 2,
  },
}

const PAGE_SIZE = 50

const generateItem = (rowIndex: number) => ({
  imageUrl:
    IMAGE_URLS_AND_HASHES[rowIndex % IMAGE_URLS_AND_HASHES.length].imageUrl,
  imageBlurhash:
    IMAGE_URLS_AND_HASHES[rowIndex % IMAGE_URLS_AND_HASHES.length]
      .imageBlurhash,
  name: faker.person.firstName(),
  tokenId: faker.string.numeric(4),
  price: faker.number.float({ min: 0, max: 10, fractionDigits: 2 }),
  id: faker.string.uuid(),
})

const RenderItem = memo(function RenderItem({
  item,
}: {
  item: ReturnType<typeof generateItem> | undefined
}) {
  if (!item) {
    return (
      <Card>
        <Card.Content>
          <SkeletonBlock className="aspect-square" />
        </Card.Content>
        <Card.Footer>
          <Skeleton.Line className="mb-0.5" />
          <Skeleton.Line />
        </Card.Footer>
      </Card>
    )
  }

  return (
    <Card>
      <Card.Content className="aspect-square w-full">
        <Image
          blurhash={item.imageBlurhash}
          className="object-cover"
          src={item.imageUrl}
          width={350}
        />
      </Card.Content>
      <Card.Footer>
        <Text className="mb-0.5" weight="semibold">
          {item.name}
        </Text>
        <Text>Price: {item.price} ETH</Text>
      </Card.Footer>
    </Card>
  )
})

const BlurhashGridTemplate = ({
  size,
}: Pick<GridProps<ReturnType<typeof generateItem>>, "size">) => {
  const [items, setItems] = useState(
    Array.from({ length: PAGE_SIZE - 1 }, (_, i) => generateItem(i)),
  )
  const [isLoadingNext, setIsLoadingNext] = useState(false)

  const loadNext = async () => {
    setIsLoadingNext(true)
    await wait(1500)
    setItems([
      ...items,
      ...Array.from({ length: PAGE_SIZE - 1 }, (_, i) => generateItem(i)),
    ])
    setIsLoadingNext(false)
  }

  const pagination = {
    hasNext: true,
    isLoadingNext,
    loadNext,
  }

  const itemsWithSkeletons = useItemsWithSkeletons({
    items,
    pageSize: PAGE_SIZE,
    isLoading: false,
    isLoadingNext,
  })

  return (
    <Grid
      itemKey={item => item?.id}
      items={itemsWithSkeletons}
      renderItem={RenderItem}
      size={size}
      {...pagination}
    />
  )
}

export const BlurhashGrid = {
  render: BlurhashGridTemplate,
}
