import { checkFileSize } from '@/utils'
import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  FileInput,
} from '@blueprintjs/core'
import { css } from '@emotion/css'
import { useHost } from '@inject/graphql/connection/host'
import { ReloadTable } from '@inject/graphql/mutations.client'
import { uploadUsersUrl } from '@inject/shared/config'
import { dialog } from '@inject/shared/css/dialog'
import { notify } from '@inject/shared/notification/engine'
import { notifyNoncommmit } from '@inject/shared/notification/var/notifications'
import authenticatedFetch from '@inject/shared/utils/authenticatedFetch'
import type { ChangeEvent } from 'react'
import { useState } from 'react'
import { useClient } from 'urql'

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

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

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

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

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

    setLoading(true)
    authenticatedFetch(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

        notifyNoncommmit(res.detail)
        setOpen(false)
        client.mutation(ReloadTable, {}).toPromise()
        setFile(undefined)
      })
      .catch((error: { status: string; detail: string }) =>
        notify(`${error.status} - ${error.detail}`, JSON.stringify(error), {
          intent: 'danger',
        })
      )
      .finally(() => setLoading(false))
  }
  return (
    <>
      <Button
        minimal
        active={open}
        onClick={() => {
          setOpen(true)
        }}
        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
