import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  FileInput,
} from '@blueprintjs/core'
import { css } from '@emotion/css'
import useApolloClient from '@inject/graphql/client/useApolloClient'
import { useHost } from '@inject/graphql/connection/host'
import { GetTagsDocument } from '@inject/graphql/queries/GetTags.generated'
import { GetUsersDocument } from '@inject/graphql/queries/GetUsers.generated'
import { uploadUsersUrl } from '@inject/shared/config'
import { dialog } from '@inject/shared/css/dialog'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import csrfFetch from '@inject/shared/utils/csrfFetch'
import type { ChangeEvent } from 'react'
import { useState } from 'react'

const body = css`
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
`

const UsersUploader = () => {
  const [open, setOpen] = useState<boolean>(false)
  const [file, setFile] = useState<File>()
  const [loading, setLoading] = useState<boolean>(false)
  const { notify } = useNotifyContext()
  const host = useHost()
  const client = useApolloClient()

  const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      setFile(e.target.files[0])
    }
  }

  const handleSubmit = () => {
    if (!file) {
      return
    }

    const data = new FormData()
    data.append('file', file)

    setLoading(true)
    csrfFetch(uploadUsersUrl(host || ''), {
      method: 'POST',
      body: data,
      credentials: 'include',
    })
      .then(res => res.json())
      .then((res: { status: string; detail: string }) => {
        // TODO: remove when all users are imported

        // TODO: make this a warning when some users are skipped

        notify(res.detail)
        setOpen(false)
        client.refetchQueries({ include: [GetUsersDocument, GetTagsDocument] })
        setFile(undefined)
      })
      .catch((err: { status: string; detail: string }) =>
        notify(`${err.status} - ${err.detail}`, {
          intent: 'danger',
        })
      )
      .finally(() => setLoading(false))
  }
  return (
    <>
      <Button
        minimal
        active={open}
        onClick={() => {
          setOpen(true)
        }}
        fill
        alignText='left'
        icon='upload'
      >
        Upload users
      </Button>

      <Dialog
        className={dialog}
        title='Upload users'
        isOpen={open}
        onClose={() => setOpen(false)}
        icon='upload'
      >
        <DialogBody className={body}>
          <FileInput
            text={file ? file.name : 'Choose file...'}
            onInputChange={handleFileChange}
            fill
          />
        </DialogBody>
        <DialogFooter
          actions={
            <Button
              onClick={handleSubmit}
              intent='primary'
              disabled={!file}
              title={file ? undefined : 'Upload a csv file'}
              loading={loading}
            >
              Submit
            </Button>
          }
        />
      </Dialog>
    </>
  )
}

export default UsersUploader
