import React, {useState} from 'react';
import {
  Card,
  Menu,
  Result,
  Button,
  Input,
  Form,
  Dropdown,
  Anchor,
  PageHeader,
  DatePicker,
  Checkbox,
  Radio,
  Col,
  Row,
  Rate,
} from 'antd';
import update from 'immutability-helper';
import {useMutation} from '@apollo/client';
import {DownOutlined} from '@ant-design/icons';

import {useForm} from 'antd/lib/form/Form';
import {useAuth0} from '@auth0/auth0-react';
import moment from 'moment';
import {
  DeleteOutlined,
  MinusCircleOutlined,
  PlusOutlined,
} from '@ant-design/icons';

import {ADD_FORM} from './query';
import NetPromoterScore from '../Form/NetPromoterScore';

const formItemLayout = {
  labelCol: {
    xs: {span: 24},
    sm: {span: 4},
  },
  wrapperCol: {
    xs: {span: 24},
    sm: {span: 20},
  },
};

const formItemLayoutWithOutLabel = {
  wrapperCol: {
    xs: {span: 24, offset: 0},
    sm: {span: 20, offset: 4},
  },
};

const radioStyle = {
  display: 'block',
  height: '30px',
  lineHeight: '30px',
};

const dateFormat = 'YYYY/MM/DD';

function QuestionCard({question, updateQuestion, deleteQuestion}: any) {
  return (
    <div>
      <Card
        bordered={false}
        actions={[
          <DeleteOutlined
            key="setting"
            onClick={e => {
              deleteQuestion();
            }}
          />,
        ]}
      >
        <Input
          placeholder="Enter your question here"
          allowClear
          value={question.title}
          onChange={e => updateQuestion({...question, title: e.target.value})}
        />
        <Checkbox
          onChange={e =>
            updateQuestion({...question, required: e.target.checked})
          }
        >
          Required
        </Checkbox>
        <div>{createQuestionField({question, updateQuestion})}</div>
      </Card>
    </div>
  );
}

function SingleChoiceQuestionField({question, updateQuestion, options}: any) {
  return (
    <Form name="dynamic_form_item" {...formItemLayoutWithOutLabel}>
      <Form.List name="names">
        {(fields, {add, remove}) => {
          return (
            <div>
              {fields.map((field, index) => (
                <Form.Item
                  {...(index === 0
                    ? formItemLayout
                    : formItemLayoutWithOutLabel)}
                  label={index === 0 ? 'Options' : ''}
                  required={false}
                  key={field.key}
                >
                  <div>
                    <Row>
                      <Col span={16}>
                        <div>
                          <Radio style={radioStyle} value={1}>
                            <Form.Item
                              {...field}
                              validateTrigger={['onChange', 'onBlur']}
                              rules={[
                                {
                                  required: true,
                                  whitespace: true,
                                  message: 'Please input option',
                                },
                              ]}
                              noStyle
                            >
                              <Input
                                placeholder="Please input option"
                                style={{width: '60%'}}
                                value={options[index]}
                                onChange={e => {
                                  let newOptions = [...options];
                                  newOptions[index] = e.target.value;
                                  updateQuestion({
                                    ...question,
                                    options: newOptions,
                                  });
                                }}
                              />
                            </Form.Item>
                          </Radio>
                        </div>
                      </Col>
                      <Col span={8}>
                        <div>
                          {fields.length > 1 ? (
                            <MinusCircleOutlined
                              className="dynamic-delete-button"
                              style={{margin: '0 8px'}}
                              onClick={() => {
                                remove(field.name);
                                let newOptions = update(options, {
                                  $splice: [[field.name, 1]],
                                });
                                updateQuestion({
                                  ...question,
                                  options: newOptions,
                                });
                              }}
                            />
                          ) : null}
                        </div>
                      </Col>
                    </Row>
                  </div>
                </Form.Item>
              ))}
              <Form.Item>
                <Button
                  type="dashed"
                  onClick={() => {
                    add();
                    updateQuestion({
                      ...question,
                      options: [...options, ''],
                    });
                  }}
                  style={{width: '60%'}}
                >
                  <PlusOutlined /> Add option
                </Button>
              </Form.Item>
            </div>
          );
        }}
      </Form.List>
    </Form>
  );
}

function createQuestionField({question, updateQuestion}: any) {
  switch (question.type) {
    case 'SingleChoice':
      const options = question.options || [];
      return SingleChoiceQuestionField({question, updateQuestion, options});
    case 'Date':
      return (
        <DatePicker
          defaultValue={moment('2015/01/01', dateFormat)}
          format={dateFormat}
          disabled
        />
      );
    case 'Rating':
      let count = question.count || 3;
      return (
        <>
          <p>Maximum rating</p>
          <Radio.Group
            options={['3', '5', '10']}
            value={count}
            onChange={e => {
              count = e.target.value;
              updateQuestion({...question, count: e.target.value});
            }}
          />
          <Rate count={count} allowHalf />
        </>
      );
    case 'Text':
      return (
        <Input.TextArea placeholder="Short answer here" allowClear disabled />
      );
    case 'NetPromoterScore':
      return <NetPromoterScore disabled />;
  }
}

function FormCreator() {
  const [questions, setQuestions] = useState<any>([]);
  const [formSubmitted, setFormSubmitState] = useState(false);
  const [formURL, setFormURL] = useState('');
  const [surveyTitle, setSurveyTitle] = useState('');
  const [formHook] = useForm();
  const {user} = useAuth0();

  const [sendToClient] = useMutation(ADD_FORM);

  const getCard = (i: number) => {
    const question = questions[i];
    const params = {
      question: question,
      updateQuestion: (question: any) =>
        setQuestions(update(questions, {$splice: [[i, 1, question]]})),
      deleteQuestion: () =>
        setQuestions(update(questions, {$splice: [[i, 1]]})),
    };
    return <QuestionCard {...params} />;
  };
  const menu = (
    <Menu onClick={e => setQuestions(questions.concat({type: e.key}))}>
      <Menu.Item key="Text">Short Answer</Menu.Item>
      <Menu.Item key="SingleChoice">Multiple Choice</Menu.Item>
      <Menu.Item key="Date">Date</Menu.Item>
      <Menu.Item key="Rating">Rating</Menu.Item>
      <Menu.Item key="NetPromoterScore">Net Promoter Score</Menu.Item>
    </Menu>
  );

  if (formSubmitted) {
    return (
      <Card type="inner">
        <Result
          status="success"
          title="Thank you!"
          subTitle={
            <Anchor>
              <Anchor.Link href={formURL} title="Your form is live." />
            </Anchor>
          }
        />
      </Card>
    );
  } else
    return (
      <PageHeader ghost={true} title="Create a survey">
        <Form form={formHook}>
          <Card
            actions={[
              <Dropdown overlay={menu}>
                <Button>
                  Add Question <DownOutlined />
                </Button>
              </Dropdown>,
              <Button
                type="primary"
                onClick={async () => {
                  const values = await formHook.validateFields();
                  console.log('validation ' + values.name);
                  for (let index = 0; index < questions.length; index++) {
                    if ('options' in questions[index]) {
                      let newOptions = questions[index].options.map(
                        (value: any, index: any) => {
                          return {order: index, title: value};
                        }
                      );
                      questions[index].options = newOptions;
                    }
                    questions[index].order = index;
                    if (!('required' in questions[index])) {
                      questions[index].required = false;
                    }
                  }
                  var form = {
                    title: surveyTitle,
                    fields: questions,
                    creator: {email: user.email},
                  };

                  console.log('Form: ', form);

                  try {
                    var result = await sendToClient({
                      variables: {
                        form: form,
                      },
                    });

                    console.log(result);
                    let id = result.data.addForm.form[0].id;
                    let url =
                      window.location.href.replace('/create', '') +
                      '/form/' +
                      id;
                    setFormURL(url);
                    setFormSubmitState(true);
                  } catch (error) {
                    console.log(error);
                  }
                }}
              >
                Create
              </Button>,
            ]}
          >
            <Form.Item
              label="Survey Title"
              name="survey title"
              rules={[{required: true, message: 'Please input Survey title'}]}
            >
              <Input
                placeholder="Enter your survey title"
                onChange={e => {
                  setSurveyTitle(e.target.value);
                }}
              />
            </Form.Item>
            {questions.map((question: any, index: number) => (
              <div key={index}>
                <Card>{getCard(index)}</Card>
              </div>
            ))}
          </Card>
        </Form>
      </PageHeader>
    );
}

export default FormCreator;