import React, { useEffect, useState } from "react";
import { useForm } from "../actions/useForm";
import { TextField } from "@mui/material";
import SelectField from "./SelectField";
import InputField from "./InputField";
import Button from "@mui/material/Button";
import AdapterDateFns from "@mui/lab/AdapterDateFns";
import LocalizationProvider from "@mui/lab/LocalizationProvider";
import Box from "@mui/material/Box";
import DateTimePicker from "@mui/lab/DateTimePicker";
import Grid from "@mui/material/Grid";
import { useHistory } from "react-router-dom";
import { fetchTypes } from "../helpers/types";
import { fetchSigns } from "../helpers/signs";
import { postEmail } from "../helpers/emails";
import { makeStyles } from "@mui/styles";

// style for form wrapper
const useStyles = makeStyles(() => ({
  root: {
    "& .MuiFormControl-root": {
      width: "80%",
      margin: 10,
    },
  },
}));

// EmailForm wrapper
export function Form(props) {
  const classes = useStyles();
  const { children, ...other } = props;
  return (
    <form className={classes.root} autoComplete="off" {...other}>
      {props.children}
    </form>
  );
}

// initial email values
const initialFValues = {
  subject: "",
  sender: "",
  recipient: "",
  reply_to: "",
  date: new Date(),
  cc: "",
  body: "",
  type: 1,
  sign: [],
};

// Form is used for adding new emails
export default function EmailForm() {
  // hook for all types
  const [types, setTypes] = useState([]);
  // hook for all signs
  const [signs, setSigns] = useState([]);
  const history = useHistory();

  // on page mount load all types and signs
  useEffect(() => {
    fetchTypes().then((res) => setTypes(res));
    fetchSigns().then((res) => setSigns(res));
  }, []);

  // validation of inserted data
  const validate = (fieldValues = values) => {
    let temp = { ...errors };

    let type = fieldValues.type;

    // subject field cannot be empty
    temp.subject = fieldValues.subject ? "" : "Subject is required.";
    // recipient field cannot be empty
    temp.recipient = fieldValues.recipient ? "" : "Recipient is required.";
    // sender field cannot be empty
    temp.sender = fieldValues.sender ? "" : "Sender is required.";
    // body field cannot be empty
    temp.body = fieldValues.body ? "" : "Body is required.";

    if (type === 1 && fieldValues.sign.length !== 0) {
      // legitimate email cannot have signs
      temp.sign = "Legitimate email cannot have signs";
    } else if (type !== 1) {
      // phishing email should have at least one sigh
      temp.sign =
        fieldValues.sign.length !== 0
          ? ""
          : "Phishing e-mail has to own at least one sign.";
    } else {
      temp.sign = "";
    }

    if (!Date.parse(fieldValues.date)) {
      // if date is in bad format set error
      temp.date = "Date time in bad format";
    } else {
      temp.date = "";
    }

    setErrors({
      ...temp,
    });

    // return true if no errors has been set, otherwise false
    return Object.values(temp).every((x) => x === "");
  };

  const {
    values = initialFValues,
    setValues,
    errors,
    setErrors,
    handleInputChange,
  } = useForm(initialFValues, validate); // function handling values changing and changing errors

  // handler for submitting email
  const handleSubmit = (e) => {
    e.preventDefault();

    if (validate()) {
      // if input values are valid, create email and go to previous page
      postEmail(values).then(history.goBack());
    }
  };

  return (
    <Box>
      <Form onSubmit={handleSubmit} style={{ marginTop: 30 }}>
        <Grid container>
          <Grid item container justifyContent="center" xs={12} md={6}>
            {/* InputField field for subject of email */}
            <InputField
              name="subject"
              label="Subject"
              value={values.subject}
              onChange={handleInputChange}
              error={errors.subject}
            />
            {/* InputField field for sender of email */}
            <InputField
              label="Sender"
              name="sender"
              value={values.sender}
              onChange={handleInputChange}
              error={errors.sender}
            />
            {/* InputField field for recipient of email */}
            <InputField
              label="Recipient"
              name="recipient"
              value={values.recipient}
              onChange={handleInputChange}
              error={errors.recipient}
            />
            <InputField
              label="Reply-To"
              name="reply_to"
              value={values.reply_to}
              onChange={handleInputChange}
              error={errors.reply_to}
            />
            <LocalizationProvider dateAdapter={AdapterDateFns}>
              <DateTimePicker
                ampm={false}
                label="DateTime picker"
                validationError
                inputFormat="yyyy/MM/dd HH:mm:SS"
                value={values.date}
                onChange={(value) => setValues({ ...values, date: value })}
                renderInput={(params) => <TextField {...params} />}
              />
            </LocalizationProvider>
          </Grid>

          <Grid item container justifyContent="center" xs={12} md={6}>
            {/* InputField field for Cc of email */}
            <InputField
              label="Cc"
              name="cc"
              value={values.cc}
              onChange={handleInputChange}
              error={errors.cc}
            />
            {/* InputField field for body of email */}
            <InputField
              label="Body"
              name="body"
              value={values.body}
              multiline={true}
              onChange={handleInputChange}
              error={errors.body}
            />
            {/* SelectField field for selecting type of email */}
            <SelectField
              name="type"
              label="Type"
              value={values.type}
              onChange={handleInputChange}
              options={types}
              error={errors.type}
              type={"type"}
            />
            {/* SelectField field for multi selecting signs of emails */}
            <SelectField
              name="sign"
              label="Signs"
              value={values.sign}
              onChange={handleInputChange}
              options={signs}
              multiple={true}
              type={"sign"}
              error={errors.sign}
            />
          </Grid>
          <Grid item container xs={12} justifyContent="center">
            {/* Submit button */}
            <Button
              type="submit"
              size="large"
              variant="contained"
              sx={{ mt: 5 }}
            >
              Create
            </Button>
          </Grid>
        </Grid>
      </Form>
    </Box>
  );
}
