import { useCallback, useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import {
  Button,
  FormControl,
  FormErrorMessage,
  FormLabel,
  Heading,
  Input,
} from '@chakra-ui/react'
import { useSWRConfig } from 'swr'
import {
  Field,
  FieldAttributes,
  FieldProps,
  Form,
  Formik,
  FormikHelpers,
} from 'formik'
import * as Yup from 'yup'
import cx from 'classnames'
import { Helmet } from 'react-helmet-async'
import WorkspaceAPI from '@/client/api/workspace'
import OrganizationSelector from '@/components/common/organization-selector'
import StorageInput from '@/components/common/storage-input'
import { gigabyteToByte } from '@/helpers/convert-storage'

type FormValues = {
  name: string
  organizationId: string
  storageCapacity: number
}

const NewWorkspacePage = () => {
  const navigate = useNavigate()
  const { mutate } = useSWRConfig()
  const [isLoading, setIsLoading] = useState(false)
  const formSchema = Yup.object().shape({
    name: Yup.string().required('Name is required').max(255),
    organizationId: Yup.string().required('Organization is required'),
    storageCapacity: Yup.number()
      .required('Storage capacity is required')
      .positive()
      .integer()
      .min(1, 'Invalid storage usage value'),
  })

  const handleSubmit = useCallback(
    async (
      { name, organizationId, storageCapacity }: FormValues,
      { setSubmitting }: FormikHelpers<FormValues>,
    ) => {
      setSubmitting(true)
      setIsLoading(true)
      try {
        const result = await WorkspaceAPI.create({
          name,
          organizationId,
          storageCapacity,
        })
        mutate(`/workspaces/${result.id}`, result)
        mutate(`/workspaces`)
        setSubmitting(false)
        navigate(`/workspace/${result.id}/file/${result.rootId}`)
      } catch (e) {
        setIsLoading(false)
      } finally {
        setSubmitting(false)
      }
    },
    [navigate, mutate],
  )

  return (
    <>
      <Helmet>
        <title>New Workspace</title>
      </Helmet>
      <div className={cx('flex', 'flex-col', 'gap-3.5')}>
        <Heading className={cx('text-heading')}>New Workspace</Heading>
        <Formik
          enableReinitialize={true}
          initialValues={{
            name: '',
            organizationId: '',
            storageCapacity: gigabyteToByte(100),
          }}
          validationSchema={formSchema}
          validateOnBlur={false}
          onSubmit={handleSubmit}
        >
          {({ errors, touched, isSubmitting, setFieldValue }) => (
            <Form>
              <div className={cx('flex', 'flex-col', 'gap-3.5')}>
                <div className={cx('flex', 'flex-col', 'gap-1.5')}>
                  <Field name="name">
                    {({ field }: FieldAttributes<FieldProps>) => (
                      <FormControl
                        maxW="400px"
                        isInvalid={errors.name && touched.name ? true : false}
                      >
                        <FormLabel>Name</FormLabel>
                        <Input {...field} disabled={isSubmitting} autoFocus />
                        <FormErrorMessage>{errors.name}</FormErrorMessage>
                      </FormControl>
                    )}
                  </Field>
                  <Field name="organizationId">
                    {({ field }: FieldAttributes<FieldProps>) => (
                      <FormControl
                        maxW="400px"
                        isInvalid={
                          errors.organizationId && touched.organizationId
                            ? true
                            : false
                        }
                      >
                        <FormLabel>Organization</FormLabel>
                        <OrganizationSelector
                          onConfirm={(value) =>
                            setFieldValue(field.name, value.id)
                          }
                        />
                        <FormErrorMessage>
                          {errors.organizationId}
                        </FormErrorMessage>
                      </FormControl>
                    )}
                  </Field>
                  <Field name="storageCapacity">
                    {(props: FieldAttributes<FieldProps>) => (
                      <FormControl
                        maxW="400px"
                        isInvalid={
                          errors.storageCapacity && touched.storageCapacity
                            ? true
                            : false
                        }
                      >
                        <FormLabel>Storage capacity</FormLabel>
                        <StorageInput {...props} />
                        <FormErrorMessage>
                          {errors.storageCapacity}
                        </FormErrorMessage>
                      </FormControl>
                    )}
                  </Field>
                </div>
                <div
                  className={cx('flex', 'flex-row', 'items-center', 'gap-1')}
                >
                  <Button
                    type="submit"
                    variant="solid"
                    colorScheme="blue"
                    isDisabled={isSubmitting || isLoading}
                    isLoading={isSubmitting || isLoading}
                  >
                    Create
                  </Button>
                  <Button as={Link} to="/workspace" variant="solid">
                    Cancel
                  </Button>
                </div>
              </div>
            </Form>
          )}
        </Formik>
      </div>
    </>
  )
}

export default NewWorkspacePage
