import {
  AnchorButton,
  Button,
  ButtonGroup,
  Divider,
  Spinner,
} from '@blueprintjs/core'
import type { IDocument } from '@cyntler/react-doc-viewer'
import DocViewer, {
  BMPRenderer,
  GIFRenderer,
  JPGRenderer,
  PNGRenderer,
  TIFFRenderer,
  VideoRenderer,
} from '@cyntler/react-doc-viewer'
import { css } from '@emotion/css'
import { useEffect, useMemo, type FC } from 'react'
import { useNavigate } from 'react-router-dom'
import Container from '../components/Container'
import ErrorMessage from '../components/ErrorMessage'
import Header from './plugins/Header'
import LoadingRenderer from './plugins/LoadingRenderer'
import { defaultFileLoader } from './plugins/loaders'
import PDFRenderer from './plugins/pdf'
import TXTRenderer from './plugins/txt'
import './viewer.global.css'

// this overrides default file loader with one that uses `csrfFetch`, it's a hack but it works
BMPRenderer.fileLoader = defaultFileLoader
GIFRenderer.fileLoader = defaultFileLoader
JPGRenderer.fileLoader = defaultFileLoader
PNGRenderer.fileLoader = defaultFileLoader
TIFFRenderer.fileLoader = defaultFileLoader

interface DocViewerProps {
  doc: Required<Omit<IDocument, 'fileData'>>
  loading?: boolean
  error?: Error
}

const grid = css`
  display: grid;
  grid-template-rows: 2rem 1fr;
  padding: 0.5rem;
  grid-gap: 1rem;
  height: 100vh;
`

const fileView = css`
  overflow-y: auto;
`

/*
 * use only in views, where it occupies full 100vh of the height without padding or margins!
 */
const DocViewerComponent: FC<DocViewerProps> = ({ doc, loading, error }) => {
  const docs: IDocument[] = useMemo(() => [doc], [doc])
  const nav = useNavigate()

  useEffect(() => {
    if (doc.fileName.endsWith('.pdf')) {
      ;(
        document.getElementById('pdf-renderer')?.querySelectorAll('a') || []
      ).forEach(x => {
        x.setAttribute('target', '_blank')
      })
    }
  }, [doc])

  const plugins = useMemo(
    () => [
      BMPRenderer,
      JPGRenderer,
      PDFRenderer,
      PNGRenderer,
      TIFFRenderer,
      TXTRenderer,
      GIFRenderer,
      VideoRenderer,
    ],
    []
  )

  const content = useMemo(() => {
    if (loading) {
      return <Spinner />
    }
    if (error) {
      return (
        <ErrorMessage>
          <h1>Error occurred!</h1>
          <p>{error.message}</p>
        </ErrorMessage>
      )
    }

    return (
      <Container className={fileView}>
        <DocViewer
          documents={docs}
          pluginRenderers={plugins}
          config={{
            pdfVerticalScrollByDefault: true,
            loadingRenderer: { overrideComponent: LoadingRenderer },
            header: {
              overrideComponent: () => <Header fileName={doc.fileName} />,
            },
          }}
        />
      </Container>
    )
  }, [doc.fileName, docs, error, loading, plugins])

  return (
    <div className={grid}>
      <div>
        <ButtonGroup minimal>
          <Button
            intent='primary'
            icon='arrow-left'
            onClick={() => {
              nav(-1)
            }}
          >
            Back
          </Button>
          <Divider />
          <AnchorButton
            icon='import'
            href={doc.uri}
            target='_blank'
            rel='noreferrer'
            loading={loading}
          >
            Download
          </AnchorButton>
        </ButtonGroup>
      </div>
      {content}
    </div>
  )
}

export default DocViewerComponent
