import React, { memo, useCallback, useMemo, useState } from 'react'

import { LazyIllustration } from '../../components/lazy-illustration/LazyIllustration'
import { illustrationNames } from '../../generated/illustrationAssets'

const debounce = <P = unknown,>(
  callback: (...args: P[]) => unknown,
  wait: number,
) => {
  let timeoutId: number
  return (...args: P[]) => {
    if (timeoutId) {
      window.clearTimeout(timeoutId)
    }
    timeoutId = window.setTimeout(() => {
      callback(...args)
    }, wait)
  }
}

const AnimationItem = memo(
  ({
    children,
    name,
    copyText,
    onClick,
  }: React.PropsWithChildren<{
    name: string
    copyText: string
    onClick: () => void
  }>) => {
    return (
      <li>
        <button
          onClick={onClick}
          className="uy:group uy:flex uy:flex-col uy:w-full uy:items-center uy:gap-125 uy:p-200 uy:transition-all uy:rounded-100 uy:bg-surface-neutral uy:hover:bg-surface-neutral-low-hover uy:shadow-raising uy:hover:shadow-floating uy:focus-visible:shadow-floating uy:focus-visible:outline-none uy:focus-visible:ring-2 uy:focus-visible:ring-ring uy:focus-visible:ring-offset-2 uy:focus-visible:ring-utility-focus-ring uy:focus-visible:border-border-form-hover uy:focus-visible:bg-surface-neutral-low-hover uy:border uy:border-solid uy:border-border-neutral"
        >
          <figure className="uy:flex uy:flex-col uy:items-center uy:w-full">
            <div
              className="uy:flex uy:justify-center uy:items-center uy:w-full uy:transition-all uy:group-hover:scale-105"
              style={{ maxWidth: '200px' }}
            >
              {children}
            </div>
            <figcaption className="uy:flex uy:flex-col uy:items-center">
              <span className="uy:typography-body-strong uy:text-content-neutral uy:cursor-pointer uy:truncate uy:w-full uy:block">
                {name}
              </span>
              <span className="uy:typography-action-small uy:bg-transparent uy:text-content-primary">
                {copyText}
              </span>
            </figcaption>
          </figure>
        </button>
      </li>
    )
  },
)

const AnimationLibrary = () => {
  const [query, setQuery] = useState<string>('')
  const [copiedAnimation, setCopiedAnimation] = useState<string | null>(null)

  // Filter only animation names (those ending with 'Animation')
  const animationList = useMemo(() => {
    return illustrationNames.filter(name => name.endsWith('Animation'))
  }, [])

  const copyToClipboard = useCallback((animationName: string) => {
    const importStatement = `import ${animationName} from '@payfit/unity-illustrations/assets/${animationName}'`

    navigator.clipboard
      .writeText(importStatement)
      .then(() => {
        setCopiedAnimation(animationName)
        setTimeout(() => {
          setCopiedAnimation(null)
        }, 5000)
      })
      .catch((error: unknown) => {
        console.error('Failed to copy: ', error)
      })
  }, [])

  const updateSearchQuery = debounce((animationName: string) => {
    setQuery(animationName)
  }, 150)

  const animationListMatchingSearch = animationList.filter(animationName =>
    animationName.toLowerCase().includes(query.toLowerCase()),
  )

  return (
    <section className="uy:flex uy:flex-col uy:gap-300 uy:max-w-[80vmax] uy:mx-auto">
      <header>
        <h3>Animation Gallery</h3>
        <p className="uy:m-0!">
          Click on any animation to copy its import path to the clipboard. All animations are displayed with a maximum width of 600px to ensure optimal viewing.
        </p>
      </header>
      <input
        type="search"
        placeholder="Search for an animation..."
        className="uy:flex uy:h-500 uy:w-full uy:text-content-form-enabled uy:rounded-100 uy:border uy:border-solid uy:border-border-form-enabled uy:bg-background uy:px-150 uy:py-100 uy:typography-body uy:placeholder:text-content-neutral-lowest uy:hover:border-border-form-hover uy:focus-visible:outline-none uy:focus-visible:ring-2 uy:focus-visible:ring-ring uy:focus-visible:ring-offset-2 uy:focus-visible:ring-utility-focus-ring"
        onChange={e => {
          updateSearchQuery(e.target.value)
        }}
      />

      {animationListMatchingSearch.length === 0 ? (
        <div className="uy:text-center uy:py-800">
          <p className="uy:typography-body uy:text-content-tertiary">
            {query ? `No animations found matching "${query}"` : 'No animations available'}
          </p>
        </div>
      ) : (
        <ul className="sb-unstyled uy:list-none uy:grid uy:grid-cols-[repeat(auto-fill,minmax(200px,_1fr))] uy:gap-200">
          {animationListMatchingSearch.map(name => {
            return (
              <AnimationItem
                name={name}
                copyText={
                  copiedAnimation === name ? 'Copied!' : 'Click to Copy'
                }
                key={name}
                onClick={() => {
                  copyToClipboard(name)
                }}
              >
                <LazyIllustration
                  variant="picture"
                  alt={`${name} animation`}
                  name={name}
                />
              </AnimationItem>
            )
          })}
        </ul>
      )}
    </section>
  )
}

export default AnimationLibrary
