import { Fragment } from 'react';
import { connect } from 'react-redux';
import { change, Field, formValueSelector } from 'redux-form';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import Alert from 'react-bootstrap/Alert';
import { FaPlus, FaTrashAlt, FaUndo } from 'react-icons/fa';
import FormTextArea from '../shared/forms/textarea';
import FormCheckbox from '../shared/forms/checkbox';
import Segment from '../shared/segment';

function FormOptions(props) {
  const {
    fields,
    meta: { error },
    change,
    isIncorrectOption,
    showOptionHints,
    isHintOption
  } = props;

  return (
    <div className='mt-4'>
      <div>
        <label className='text-large text-bold'>
          {'گزینه‌ها: '}
          <span className='text-danger'>*</span>
        </label>
      </div>
      {error && error.length && (
        <Alert variant='danger' className='text-center'>
          {error.map((e, index) => (
            <p key={index} className='m-0'>
              {index + 1}) {e}
            </p>
          ))}
        </Alert>
      )}

      {fields.map((member, index) => {
        return (
          <div key={index} className='my-3'>
            <Segment>
              <div className='d-flex justify-content-between align-items-baseline mb-0'>
                <p className='text-bold'>{`گزینه ${index + 1}`}</p>
                <div>
                  <Button
                    variant='outline-warning'
                    size='sm'
                    onClick={resetOption.bind(null, change, member)}
                  >
                    <FaUndo />
                  </Button>{' '}
                  <Button
                    variant='outline-danger'
                    size='sm'
                    onClick={fields.remove.bind(null, index)}
                  >
                    <FaTrashAlt />
                  </Button>
                </div>
              </div>
              <Field
                horizontal
                required
                name={`${member}.text`}
                component={FormTextArea}
                label='متن'
                placeholder=''
                disabled={isHintOption(index)}
              />
              <Form.Row className='justify-content-between align-items-baseline'>
                {!isIncorrectOption(index) && (
                  <Field
                    required
                    name={`${member}.isCorrect`}
                    component={FormCheckbox}
                    label='گزینه درست'
                    disabled={isIncorrectOption(index)}
                  />
                )}
                <div className='ml-auto'>
                  {showOptionHints(index) &&
                    optionHints.map((optionHint, index) => (
                      <Fragment key={optionHint.id}>
                        {index > 0 && ' '}
                        <Button
                          variant='outline-secondary'
                          onClick={handleOptionHintClick.bind(null, change, member, optionHint)}
                        >
                          {optionHint.text}
                        </Button>
                      </Fragment>
                    ))}
                </div>
              </Form.Row>
            </Segment>
          </div>
        );
      })}
      <div className='mt-3 mb-5 text-center'>
        <Button variant='outline-success' onClick={createNewOption.bind(null, fields)}>
          {'افزودن گزینه جدید '}
          <FaPlus />
        </Button>
      </div>
    </div>
  );
}

const MIN_OPTIONS_COUNT = 2;

const optionHints = [
  { id: 1, text: 'هیچ‌', value: 'هیچ‌کدام', weight: 0 },
  { id: 2, text: '1,2', value: 'گزینه‌های 1 و 2', weight: 20 },
  { id: 3, text: '1,3', value: 'گزینه‌های 1 و 3', weight: 20 },
  { id: 4, text: '2,3', value: 'گزینه‌های 2 و 3', weight: 20 },
  { id: 5, text: 'همه', value: 'همه موارد', weight: 10 }
];
const optionHintValues = optionHints.map(({ value }) => value);

function isRealOptionText(text) {
  return !!text && !optionHintValues.includes(text);
}

function handleOptionHintClick(change, member, optionHint) {
  change('create-card', `${member}.text`, optionHint.value);
  change('create-card', `${member}.weight`, optionHint.weight);
}

function resetOption(change, member) {
  change('create-card', `${member}.text`, '');
  change('create-card', `${member}.weight`, 100);
  change('create-card', `${member}.isCorrect`, false);
}

function createNewOption(fields) {
  fields.push({ text: '', isCorrect: false, weight: 100 });
}

function isIncorrectOption(options, index) {
  if (!options || options.length === 0) return false;
  const firstCorrectOptionIndex = options.findIndex(option => option.isCorrect);
  return firstCorrectOptionIndex >= 0 && !options[index].isCorrect;
}

function showOptionHints(options, index) {
  if (!options || options.length === 0) return false;
  const realOptionCount = options.filter(({ text }) => isRealOptionText(text)).length;
  return realOptionCount >= MIN_OPTIONS_COUNT && !isRealOptionText(options[index].text);
}

function isHintOption(options, index) {
  return optionHintValues.includes(options[index].text);
}

function mapStateToProps(state) {
  const selector = formValueSelector('create-card');
  const options = selector(state, 'options');
  return {
    showOptionHints: showOptionHints.bind(null, options),
    isIncorrectOption: isIncorrectOption.bind(null, options),
    isHintOption: isHintOption.bind(null, options)
  };
}

export default connect(mapStateToProps, { change })(FormOptions);
