import React, { useEffect, useState } from "react"
import { graphql, useStaticQuery } from "gatsby"
import cls from "classnames"
import Select from "react-select"
import queryString from "querystring"
import * as styles from "./index.module.scss"
import Container from "@/components/container"
import MediaCard from "@/components/media-card"
import { ALL_CASE_SECTION } from "@/constants/case"
import Icon from "@/components/icon"
import EmptyList from "@/components/empty-list"
import { STORAGE_KEY } from "@/constants/common"

const SelectAttr = {
  isSearchable: false,
  className: styles.select,
  classNamePrefix: "select",
}

const CARD_DEFAULT_NUM = 8
const CARD_NEXT_PAGE_NUM = 8

const industries: string[] = []
const industryOptions: Option[] = [{ label: "全部行业", value: "all" }]
const scenes: string[] = []
const sceneOptions: Option[] = [{ label: "全部场景", value: "all" }]

type ParseParamsType = {
  industry: string
  scene: string
  setValue: (value: React.SetStateAction<Option>) => void
}

type ParseType = (option: Option) => ParseParamsType

const AllCase: React.FC = () => {
  const { allStrapiCustomerCases } = useStaticQuery<StrapiCustomerCasesQuery>(
    graphql`
      query strapiAllCustomerCases {
        allStrapiCustomerCases(sort: { fields: order, order: ASC }) {
          edges {
            node {
              id
              title
              description
              customUrl
              logo {
                id
                media {
                  url
                  width
                  height
                }
                alt
              }
              industry
              scene
            }
          }
        }
      }
    `
  )

  const cases = allStrapiCustomerCases.edges
  const [industryValue, setIndustryValue] = useState<Option>({
    label: "选择行业",
    value: "all",
  })
  const [scenesValue, setScenesValue] = useState<Option>({
    label: "选择场景",
    value: "all",
  })

  const handleChange = (parse: ParseType) => (option?: Option) => {
    if (!option) return

    const { industry, scene, setValue } = parse(option)

    window.history.replaceState(
      null,
      "",
      `?industry=${industry}&scene=${scene}`
    )

    setValue(option)
    sessionStorage.setItem(STORAGE_KEY.INDUSTRY, industry)
    sessionStorage.setItem(STORAGE_KEY.SCENE, scene)
  }

  const handleChangeIndustry = handleChange((option: Option) => ({
    industry: option.value,
    scene: scenesValue.value,
    setValue: setIndustryValue,
  }))
  const handleChangeScenes = handleChange((option: Option) => ({
    industry: industryValue.value,
    scene: option.value,
    setValue: setScenesValue,
  }))

  const [sliceNum, setSliceNum] = useState<number>(CARD_DEFAULT_NUM)
  const [renderCases, setRenderCases] = useState<
    { node: StrapiCustomerCases }[]
  >([])
  const [isShowMoreButton, setIsShowMoreButton] = useState<boolean>(false)
  const [isLoading, setIsLoading] = useState<boolean>(true)

  function creatOptions() {
    for (const item of cases) {
      if (item.node.industry && !industries.includes(item.node.industry)) {
        industries.push(item.node.industry)
        industryOptions.push({
          label: item.node.industry,
          value: item.node.industry,
        })
      }
      if (item.node.scene && !scenes.includes(item.node.scene)) {
        scenes.push(item.node.scene)
        sceneOptions.push({
          label: item.node.scene,
          value: item.node.scene,
        })
      }
    }
  }

  function queryUrl() {
    const { scene, industry } = queryString.parse(
      typeof window !== "undefined"
        ? window.location.search.replace("?", "")
        : ""
    ) as { [key: string]: string }
    const infactIndustry = industries.includes(industry) ? industry : "all"
    const infactScenes = scenes.includes(scene) ? scene : "all"
    setIndustryValue({
      label: infactIndustry === "all" ? "选择行业" : infactIndustry,
      value: infactIndustry,
    })
    setScenesValue({
      label: infactScenes === "all" ? "选择场景" : infactScenes,
      value: infactScenes,
    })
  }

  function filterCases() {
    const filteredCases = cases.filter(item => {
      return (
        (industryValue.value === "all" ||
          item.node.industry === industryValue.value) &&
        (scenesValue.value === "all" || item.node.scene === scenesValue.value)
      )
    })
    setRenderCases(filteredCases.slice(0, sliceNum))
    setIsShowMoreButton(filteredCases.length > sliceNum)
    setIsLoading(false)
  }

  const oldSliceNumKeyName = "casePageSliceNum"

  function addSliceNum() {
    const newSliceNum = sliceNum + CARD_NEXT_PAGE_NUM
    setSliceNum(newSliceNum)
    window?.sessionStorage.setItem(oldSliceNumKeyName, String(newSliceNum))
  }

  useEffect(() => {
    creatOptions()
    queryUrl()
    filterCases()
    const oldSliceNum = window?.sessionStorage.getItem(oldSliceNumKeyName) ?? CARD_NEXT_PAGE_NUM
    setSliceNum(Number(oldSliceNum))
  }, [])

  useEffect(() => {
    filterCases()
  }, [industryValue.value, scenesValue.value, sliceNum])

  return (
    <section className={styles.AllCase} id="case">
      <Container>
        <div className={styles.title}>
          <div className={styles.left}>
            <h2>{ALL_CASE_SECTION.title}</h2>
            <h5>{ALL_CASE_SECTION.desc}</h5>
          </div>
          <div
            className={cls(
              "is-flex is-justify-content-space-between is-align-items-center",
              styles.right
            )}
          >
            <div className={styles.selectOption}>
              <Select
                {...SelectAttr}
                value={industryValue}
                options={industryOptions}
                instanceId="industry"
                onChange={handleChangeIndustry}
              />
            </div>
            <Select
              {...SelectAttr}
              value={scenesValue}
              options={sceneOptions}
              instanceId="scene"
              onChange={handleChangeScenes}
            />
          </div>
        </div>
        {!renderCases.length ? (
          <div className={styles.emptyList}>{!isLoading && <EmptyList />}</div>
        ) : (
          <div>
            <div className={cls("columns is-flex-wrap-wrap", styles.content)}>
              {renderCases.map(item => {
                return (
                  <MediaCard
                    id={item.node.id}
                    image={{
                      alt: item.node.logo.alt,
                      media: item.node.logo.media,
                    }}
                    title={item.node.title}
                    description={item.node.description}
                    to={`/case/${item.node.customUrl ?? item.node.id}`}
                    key={item.node.id}
                    attrs={{
                      "data-industry": item.node.industry,
                      "data-scene": item.node.scene,
                    }}
                  />
                )
              })}
            </div>
            <div className={styles.moreButton}>
              {isShowMoreButton && (
                <button
                  className="button is-medium is-ghost is-primary"
                  onClick={addSliceNum}
                >
                  <span>{ALL_CASE_SECTION.more}</span>
                  <span className="icon">
                    <Icon name="chevron-right" />
                  </span>
                </button>
              )}
            </div>
          </div>
        )}
      </Container>
    </section>
  )
}

export default AllCase
