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

interface ImportDialogProps {
  isOpen: boolean
  onClose: () => void
}

const ImportDialog: FC<ImportDialogProps> = ({ isOpen, onClose }) => {
  const client = useClient()
  const host = useHost()

  const [loading, setLoading] = useState(false)

  const [file, setFile] = useState<File | undefined>()
  const text = file ? file.name : 'Choose file...'

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

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

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

    setLoading(true)
    authenticatedFetch(exportImportUrl(host || ''), {
      method: 'POST',
      body: data,
      credentials: 'include',
    })
      .then(result => result.json())
      .then((result: { status: string; detail: string }) => {
        if (result.status !== 'ok') {
          notify(`${result.status}: ${result.detail}`, JSON.stringify(result), {
            intent: 'danger',
            icon: 'error',
          })
          return
        }

        client.mutation(ReloadExercises, {}).toPromise()
        onClose()
      })
      .catch((error: { status: string; detail: string }) => {
        notify(`${error.status}: ${error.detail}`, JSON.stringify(error), {
          intent: 'danger',
          icon: 'error',
        })
      })
      .finally(() => {
        setFile(undefined)
        setLoading(false)
      })
  }

  return (
    <Dialog
      className={dialog}
      isOpen={isOpen}
      onClose={onClose}
      icon='import'
      title='Import'
    >
      <DialogBody>
        <p>
          <strong>
            Only import files exported from this platform using the export
            button. Do not upload logs!
          </strong>
        </p>
        <p>Importing will not affect current data.</p>
        <FileInput fill text={text} onInputChange={handleFileChange} />
      </DialogBody>
      <DialogFooter
        actions={
          <Button
            loading={loading}
            intent='primary'
            disabled={!file}
            onClick={handleImport}
          >
            Submit
          </Button>
        }
      />
    </Dialog>
  )
}

export default ImportDialog
