import browser from "webextension-polyfill"
import { memo, useEffect, useMemo } from "react"
import { useAutoCallback } from "hooks.macro"
import { groupBy } from "lodash"
import { useTranslation } from "react-i18next"
import { gql, useQuery } from "~/generated/graphql"
import type * as types from "~/generated/graphql"
import { useChromeEvent } from "~/shared/hooks/useChromeEvent"
import { Popup } from "./components/style"
import { StateToggles } from "./components/StateToggles"
import { Sections } from "./components/Sections"
import { Footer } from "./components/Footer"
import { usePopupContext } from "./index"

export type Data = types.GetPopupFilesQuery["files"][number]

export const GET_SECTIONS = gql<"GetPopupFiles">`
  query GetPopupFiles($url: String!) {
    preferences {
      enabled
    }
    files(filter: { url: $url, isGlobal: false, state: None }) {
      id
      name
      icon
      enabled
      tags
    }
  }
`

export const PopupApp = memo(({ container }: { container: HTMLElement }) => {
  const { i18n } = useTranslation()
  const { url } = usePopupContext()
  const { data: { files } = {}, refetch } = useQuery(GET_SECTIONS, {
    variables: { url },
  })

  useEffect(() => {
    document.documentElement.lang = i18n.language
  }, [i18n.language])

  useChromeEvent(
    browser.runtime.onMessage,
    useAutoCallback((msg: { updatePopup?: boolean }) => {
      msg.updatePopup && void refetch()
    }),
  )

  useEffect(() => {
    // https://bugs.chromium.org/p/chromium/issues/detail?id=317880
    document.body.style.minHeight = getComputedStyle(container).height
    setTimeout(() => {
      ;(document.activeElement as HTMLElement).blur()
      document.body.style.marginBottom = 1 + Math.random() / 3 + "px"
    }, 0)
  }, [container])

  const list = useMemo(
    () => Object.entries(groupBy(files ?? [], _ => _.tags[0] ?? "")),
    [files],
  )

  if (!files) {
    return null
  }

  return (
    <Popup.Container>
      <StateToggles />
      <Sections files={list} />
      <Footer />
    </Popup.Container>
  )
})
