import * as React from "react"
import clsx from "clsx"

import type { SearchParams } from "../types/SearchParams"

import BulletIcon from "../icons/Bullet"
import EnglishIcon from "../icons/English"
import SortIcon from "../icons/Sort"
import KnightIcon from "../icons/Knight"
import LightningIcon from "../icons/Lightning"
import PawnIcon from "../icons/Pawn"
import RabbitIcon from "../icons/Rabbit"
import RightArrowIcon from "../icons/RightArrow"
import RisingGraphIcon from "../icons/RisingGraph"
import TrophyIcon from "../icons/Trophy"
import { Button } from "./Button"
import { Mode } from "../types/Mode"
import { Site } from "../types/Site"
import { Title } from "../types/Title"

interface SortOption {
  title: string
  Icon: ({ ...props }: { [x: string]: any }) => React.JSX.Element
  enable: (p: SearchParams) => SearchParams
  isEnabled: (p: SearchParams) => boolean
}

const filters: SortOption[] = [
  {
    title: "On Lichess",
    Icon: KnightIcon,
    enable: (p) => {
      p.sites.push(Site.LICHESS)
      return p
    },
    isEnabled: (p) => p.sites.includes(Site.LICHESS),
  },
  {
    title: "On Chess.com",
    Icon: PawnIcon,
    enable: (p) => {
      p.sites.push(Site.CHESSCOM)
      return p
    },
    isEnabled: (p) => p.sites.includes(Site.CHESSCOM),
  },
  {
    title: "English Speaking",
    Icon: EnglishIcon,
    enable: (p) => {
      for (const lang of ["en-US", "en-GB"]) {
        if (!p.languages.includes(lang)) {
          p.languages.push(lang)
        }
      }
      return p
    },
    // Using `||` doesn't match how `enable` works but this is probably closer
    // to how people would expect the filter to operate.
    isEnabled: (p) =>
      p.languages.includes("en-US") || p.languages.includes("en-GB"),
  },
  {
    title: "ELO 2000+",
    Icon: RisingGraphIcon,
    enable: (p) => {
      p.rating[0] = Math.max(2000, p.rating[0])
      return p
    },
    isEnabled: (p) => p.rating[0] >= 2000,
  },
  {
    title: "Rapid Specialty",
    Icon: RabbitIcon,
    enable: (p) => {
      p.modes = [Mode.RAPID]
      return p
    },
    isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.RAPID),
  },
  {
    title: "Blitz Specialty",
    Icon: LightningIcon,
    enable: (p) => {
      p.modes = [Mode.BLITZ]
      return p
    },
    isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BLITZ),
  },
  {
    title: "Bullet Specialty",
    Icon: BulletIcon,
    enable: (p) => {
      p.modes = [Mode.BULLET]
      return p
    },
    isEnabled: (p) => p.modes.length === 1 && p.modes.includes(Mode.BULLET),
  },
  {
    title: "Titled Player",
    Icon: TrophyIcon,
    enable: (p) => {
      p.titles = Object.keys(Title) as Title[]
      return p
    },
    isEnabled: (p) => p.titles.length > 0,
  },
]

enum Direction {
  LEFT,
  RIGHT,
}

interface SortScrollProps {
  params: SearchParams
  onModal: () => void
  onSelect: (p: SearchParams) => void
}

export function SortScroll({ params, onModal, onSelect }: SortScrollProps) {
  const viewport = React.useRef<HTMLDivElement>(null)
  const [isFlush, setIsFlush] = React.useState([true, false])

  const scrollDir = (dir: Direction) => {
    const v = viewport.current
    if (!v) {
      return
    }
    const delta = v.clientWidth / 2
    const left = v.scrollLeft + (dir == Direction.RIGHT ? delta : -delta)
    v.scroll({ left, behavior: "smooth" })

    const isFlushLeft = left <= 1
    const isFlushRight = left + v.clientWidth >= v.scrollWidth
    setIsFlush([isFlushLeft, isFlushRight])
  }

  return (
    <div className="flex items-center gap-x-8">
      <div className="relative flex flex-grow overflow-hidden">
        <div
          ref={viewport}
          className="flex items-center gap-x-12 overflow-hidden"
        >
          {[...filters].map((e) => (
            <div
              key={e.title}
              className={clsx("flex-none cursor-pointer text-center", {
                "fill-amber-500 text-amber-500": e.isEnabled(params),
              })}
              onClick={() => onSelect(e.enable({ ...params }))}
            >
              <e.Icon className="mx-auto h-6 w-6" />
              <span className="text-xs">{e.title}</span>
            </div>
          ))}
        </div>
        <div
          className={clsx(
            "pointer-events-none absolute top-1/2 -translate-y-1/2 bg-gradient-to-r from-white to-transparent to-90% py-4 pr-60",
            isFlush[0] ? "hidden" : ""
          )}
        >
          <Button
            className="pointer-events-auto rounded-full border border-neutral-900 py-4"
            onClick={() => {
              scrollDir(Direction.LEFT)
            }}
            invert
          >
            <RightArrowIcon className="h-3 w-3 rotate-180 fill-white" />
          </Button>
        </div>
        <div
          className={clsx(
            "pointer-events-none absolute right-0 top-1/2 -translate-y-1/2 bg-gradient-to-r from-transparent from-10% to-white py-4 pl-60",
            isFlush[1] ? "hidden" : ""
          )}
        >
          <Button
            className="pointer-events-auto rounded-full border border-neutral-900 py-4"
            onClick={() => {
              scrollDir(Direction.RIGHT)
            }}
            invert
          >
            <RightArrowIcon className="h-3 w-3 fill-white" />
          </Button>
        </div>
      </div>
      <Button className="flex gap-x-2 py-4" onClick={onModal}>
        <SortIcon className="h-6 w-6 fill-white" />
        <span className="font-display">Sort</span>
      </Button>
    </div>
  )
}
