import React from 'react';
import _ from 'lodash';
import cronstrue from 'cronstrue';
import * as Yup from 'yup';
import { Formik, Form, Field } from 'formik';
import { Grid, TextField, Button, Link } from '@material-ui/core';
import { post } from '../../requests';
import { Event } from '../../types';

interface PropTypes {
  mutate: () => void;
}

interface Fields {
  name: string;
  schedule: string;
  attendanceId: string;
  conferenceId: string;
}

const describeCrontab = (crontab: string) => {
  try {
    return cronstrue.toString(crontab);
  } catch {
    return false;
  }
};

const validationSchema = Yup.object({
  name: Yup.string().required('This field is required'),
  conferenceId: Yup.string().required('This field is required'),
  attendanceId: Yup.string(),
  schedule: Yup.string()
    .required('This field is required')
    .test('cron', 'Invalid crontab', value => !!describeCrontab(value || ''))
});

const EventForm: React.FC<PropTypes> = ({ mutate }) => {

  const describeSchedule = (schedule: string) => {
    const description = describeCrontab(schedule);
    if (description) return `Event will run ${_.lowerFirst(description)}`;
    const link = <Link href="https://crontab.guru">crontab.guru</Link>;
    return (
      <>
        The schedule is invalid. Check out {link} for more help with cron scheduling.
      </>
    );
  };

  const handleSubmit = (fields: Fields, { resetForm }: any) => {
    const { name, schedule, attendanceId, conferenceId } = fields;

    if (schedule && conferenceId) {
      const event: Partial<Event> = {
        type: 'class',
        schedule,
        context: {
          name,
          attendanceId,
          conferenceId,
          participants: []
        }
      };

      return post('/events', event).then(() => {
        mutate();
        resetForm();
      });
    }
  }

  return (
    <Formik
      initialValues={{ name: '', schedule: '* * * * *', attendanceId: '', conferenceId: '' }}
      validationSchema={validationSchema}
      onSubmit={handleSubmit}
    >
      {({ values, errors, touched, isValid }) => (
        <Form autoComplete="off">
          <Grid container spacing={2}>
            <Grid item sm={6} xs={12}>
              <Field
                name="name"
                label="Name"
                value={values.name}
                error={touched.name && !!errors.name}
                helperText={touched.name && errors.name}
                variant="outlined"
                fullWidth
                required
                as={TextField}
              />
            </Grid>
            <Grid item sm={6} xs={12}>
              <Field
                name="schedule"
                label="Schedule"
                value={values.schedule}
                error={touched.schedule && !!errors.schedule}
                helperText={
                  (touched.schedule && errors.schedule) || "Should be a valid crontab, for example: 30 12 * * Mon"
                }
                variant="outlined"
                fullWidth
                required
                as={TextField}
              />
            </Grid>
            <Grid item sm={6} xs={12}>
              <Field
                name="conferenceId"
                label="Conference ID"
                value={values.conferenceId}
                error={touched.conferenceId && !!errors.conferenceId}
                helperText={touched.conferenceId && errors.conferenceId}
                variant="outlined"
                fullWidth
                required
                as={TextField}
              />
            </Grid>
            <Grid item sm={6} xs={12}>
              <Field
                name="attendanceId"
                label="Attendance ID"
                value={values.attendanceId}
                variant="outlined"
                fullWidth
                as={TextField}
              />
            </Grid>
            <Grid item xs={12}>
              {describeSchedule(values.schedule)}
            </Grid>
            <Grid item sm={2} xs={12}>
              <Button
                type="submit"
                disabled={!isValid}
                variant="contained"
                size="large"
                color="primary"
                fullWidth
              >
                Create event
              </Button>
            </Grid>
          </Grid>
        </Form>
      )}
    </Formik>
  );
};

export default EventForm;
