import {
  Button,
  Dialog,
  DialogBody,
  DialogFooter,
  FileInput,
} from '@blueprintjs/core'
import useApolloClient from '@inject/graphql/client/useApolloClient'
import { useHost } from '@inject/graphql/connection/host'
import { GetDefinitionsDocument } from '@inject/graphql/queries/GetDefinitions.generated'
import { GetExercisesDocument } from '@inject/graphql/queries/GetExercises.generated'
import { exportImportUrl } 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, FC } from 'react'
import { useState } from 'react'

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

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

  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) {
      return
    }

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

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

        client.refetchQueries({
          include: [GetExercisesDocument, GetDefinitionsDocument],
        })
        onClose()
      })
      .catch((err: { status: string; detail: string }) => {
        notify(`${err.status}: ${err.detail}`, {
          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
