import PropTypes from 'prop-types'
import { useState, useEffect } from 'react'
import axios from 'axios'
import { useMediaQuery } from 'react-responsive'
import {
  Form,
  Input,
  Button,
  Typography,
  Flex,
  Steps,
  Descriptions,
  Divider
} from 'antd'
import { useMessageContext } from '../../context/MessageContext'

import config from '../../../../config'

const { Title } = Typography

const initialNewUserForm = {
  username: '',
  name: '',
  firstName: '',
  lastName: '',
  email: ''
}

const NewUser = ({ onOk, reset }) => {
  const { showError } = useMessageContext()
  const [newUserLoading, setNewUserLoading] = useState(false)
  const [currentStep, setCurrentStep] = useState(0)
  const [nextEnabled, setNextEnabled] = useState(false)
  const [newUserForm] = Form.useForm()
  const [newUserFormValues, setNewUserFormValues] = useState(initialNewUserForm)
  const isMobile = useMediaQuery({ maxWidth: 768 })

  const newUserFormUpdateValues = Form.useWatch([], newUserForm)

  useEffect(() => {
    newUserForm
      .validateFields({
        validateOnly: true
      })
      .then(() => setNextEnabled(true))
      .catch(() => setNextEnabled(false))
  }, [newUserForm, newUserFormUpdateValues])

  const summaryItems = [
    {
      key: 'username',
      label: 'Username',
      children: newUserFormValues.username
    },
    {
      key: 'name',
      label: 'Full Name',
      children: newUserFormValues.name || 'n/a'
    },
    {
      key: 'firstName',
      label: 'First Name',
      children: newUserFormValues.firstName || 'n/a'
    },
    {
      key: 'lastName',
      label: 'Last Name',
      children: newUserFormValues.lastName || 'n/a'
    },
    {
      key: 'email',
      label: 'Email',
      children: newUserFormValues.email || 'n/a'
    }
  ]

  useEffect(() => {
    if (reset) {
      newUserForm.resetFields()
    }
  }, [reset, newUserForm])

  const handleNewUser = async () => {
    setNewUserLoading(true)
    try {
      await axios.post(`${config.backendUrl}/users`, newUserFormValues, {
        withCredentials: true
      })
      onOk()
    } catch (error) {
      showError('Error creating new user: ' + error.message)
    } finally {
      setNewUserLoading(false)
    }
  }

  const steps = [
    {
      title: 'Details',
      key: 'details',
      content: (
        <>
          <Form.Item
            label='Username'
            name='username'
            rules={[
              {
                required: true,
                message: 'Please enter a username.'
              },
              {
                min: 3,
                message: 'Username must be at least 3 characters.'
              }
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label='Full Name'
            name='name'
            rules={[
              {
                required: true,
                message: 'Please enter a full name.'
              }
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label='First Name'
            name='firstName'
            rules={[
              {
                required: true,
                message: 'Please enter a first name.'
              }
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label='Last Name'
            name='lastName'
            rules={[
              {
                required: true,
                message: 'Please enter a last name.'
              }
            ]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label='Email'
            name='email'
            style={{ marginBottom: 8 }}
            rules={[
              {
                required: true,
                message: 'Please enter an email address.'
              },
              {
                type: 'email',
                message: 'Please enter a valid email address.'
              }
            ]}
          >
            <Input />
          </Form.Item>
        </>
      )
    },
    {
      title: 'Summary',
      key: 'summary',
      content: <Descriptions column={1} items={summaryItems} size={'small'} />
    }
  ]

  return (
    <Flex gap='middle'>
      {!isMobile && (
        <div style={{ minWidth: '160px' }}>
          <Steps
            current={currentStep}
            items={steps}
            direction='vertical'
            style={{ width: 'fit-content' }}
          />
        </div>
      )}

      {!isMobile && <Divider type='vertical' style={{ height: 'unset' }} />}

      <Flex vertical gap='middle' style={{ flexGrow: 1 }}>
        <Title level={2} style={{ marginTop: 0, marginBottom: 4 }}>
          New User
        </Title>
        <Form
          name='basic'
          autoComplete='off'
          form={newUserForm}
          onFinish={handleNewUser}
          onValuesChange={(changedValues) =>
            setNewUserFormValues((prevValues) => ({
              ...prevValues,
              ...changedValues
            }))
          }
          initialValues={initialNewUserForm}
        >
          <div style={{ minHeight: '260px' }}>{steps[currentStep].content}</div>
        </Form>

        <Flex justify='end'>
          <Button
            style={{ margin: '0 8px' }}
            onClick={() => {
              setCurrentStep((prev) => prev - 1)
              setNextEnabled(true)
            }}
            disabled={currentStep === 0}
          >
            Previous
          </Button>

          {currentStep < steps.length - 1 ? (
            <Button
              type='primary'
              disabled={!nextEnabled}
              onClick={() => {
                setCurrentStep((prev) => prev + 1)
                setNextEnabled(false)
              }}
            >
              Next
            </Button>
          ) : (
            <Button
              type='primary'
              loading={newUserLoading}
              onClick={() => {
                newUserForm.submit()
              }}
            >
              Done
            </Button>
          )}
        </Flex>
      </Flex>
    </Flex>
  )
}

NewUser.propTypes = {
  onOk: PropTypes.func.isRequired,
  reset: PropTypes.bool
}

export default NewUser
