import { Button, Checkbox, FormControl, FormControlLabel, TextField } from "@material-ui/core";
import React, { useEffect, useState } from "react";
import { Redirect } from "react-router";
import { useParams } from "react-router-dom";
import { ENVS } from "../../../utils/key-envs";
import { ManifestsProvider, useManifestsContext } from "../../Contexts/ManifestsContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext";
import { DropDownList } from "../../Controls/DropDownList";
import { RoleWrap } from "../../Controls/RoleWrap";
import { Permissions } from "../../../utils/roles";
import useStyles from "../../useStyles";
import { NumberField } from "../../Controls/NumberField";

const manifestTypes = [
  { value: "standard", label: "Standard" },
  { value: "forced", label: "Forced" },
];

const activeStates = [
  { value: true, label: "Active" },
  { value: false, label: "Archived" },
];

const booleanStates = [
  { value: true, label: "True" },
  { value: false, label: "False" },
];

const emptyManifest = {
  name: "",
  version: "",
};

const MainForm = () => {

  const { manifest_id } = useParams();
  const classes = useStyles();

  const [manifest, setManifest] = useState(null);
  const [redirect, setRedirect] = useState(null);

  const { getManifest, busy, migrateManifest, updateManifest } = useManifestsContext();
  const {
    token: {
      idToken: { jwtToken: token },
    },
    groups,
    providers,
  } = useUserContext();

  const { setMessage, setTitle, setSitePath } = useStatusContext();

  const [name, setName] = useState("");
  const [releaseNotes, setReleaseNotes] = useState("");
  const [type, setType] = useState("");
  const [active, setActive] = useState(true); // So !active = archived
  const [rollback, setRollback] = useState(true);
  const [env, setEnv] = useState("current");
  const [updateDuration, setUpdateDuration] = useState(0);
  const [maxAttempts, setMaxAttempts] = useState(0);
  const [notifySAP, setNotifySAP] = useState(false);

  const changeName = (e) => {
    setName(e.target.value);
  }

  const changeReleaseNotes = (e) => {
    setReleaseNotes(e.target.value);
  }

  const changeType = (e) => {
    setType(e.target.value);
  };

  const changeActive = (e) => {
    setActive(e.target.value === 'true')
  }

  const changeRollback = (e) => {
    setRollback(e.target.value === 'true')
  }

  const changeEnv = (e) => {
    setEnv(e.target.value)
  }

  const changeUpdateDuration = (value) => {
    if (value < 0) {
      return;
    }
    setUpdateDuration(value);
  }

  const changeMaxAttempts = (value) => {
    if (value < 0) {
      return;
    }
    setMaxAttempts(value);
  }

  const changeNotifySAP = (event) => {
    setNotifySAP(event.target.checked);
  }

  const onSubmit = async (e) => {
    e.preventDefault();
    try {
      const result = await updateManifest(manifest_id, {
        name,
        release_notes: releaseNotes,
        type,
        active,
        rollback,
        env,
        update_duration: parseInt(updateDuration),
        max_attempts: parseInt(maxAttempts),
        notify_sap: notifySAP,
      }, token);
      if (!result || result.error) return;

      setMessage(`Updated manifest ${manifest_id}`);
      setRedirect(`/package-status/${manifest_id}`);

    } catch (e) {
      setMessage(`Failed to update manifest ${manifest_id}`);
    }
  }

  const manifestMigrate = async (e) => {
    e.preventDefault();
    try {
      const result = await migrateManifest(manifest_id, token)
      if (!result || result.error) return;
      setMessage(`Manifest Migrated ${manifest_id}`)
    } catch (e) {
      setMessage(`Failed to update manifest ${manifest_id}`)
    }
  }

  useEffect(() => {
    (async () => {
      try {
        const result = await getManifest(manifest_id, token);
        if (result.error) {
          throw new Error(`Get manifest error. ${result.message}`);
        } else {
          setManifest(result);
          setName(result.name);
          setReleaseNotes(result.release_notes);
          setType(result.type);
          setActive(result.active);
          setRollback(result.rollback);
          setEnv(result.env ?? "current");
          setUpdateDuration(result.update_duration);
          setMaxAttempts(result.max_attempts);
          setNotifySAP(result.notify_sap);
        }
      } catch (e) {
        setMessage(e.message);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [token]);

  useEffect(() => {
    const curManifest = manifest ? manifest : emptyManifest;

    setTitle("Update Package");
    setSitePath([
      {
        label: "Deployments",
        link: "/packages",
      },
      {
        label: `Update Package ${curManifest.name} ${curManifest.version}`,
      },
    ]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [manifest]);

  if (redirect && redirect.length > 0) {
    return <Redirect to={redirect} />;
  }

  if (manifest === null) return <div>Loading Manifest...</div>;

  return (
    <div className={classes.paper}>
      <FormControl className={classes.form} fullWidth noValidate>
        <TextField
          id="id"
          name="id"
          label="ID"
          variant="outlined"
          margin="normal"
          inputProps={{
            maxLength: "20",
            readOnly: true,
          }}
          disabled
          value={manifest.id}
          required
          fullWidth
        />
        <TextField
          id="name"
          name="name"
          label="Name"
          variant="outlined"
          margin="normal"
          inputProps={{
            maxLength: "255",
          }}
          value={name}
          required
          fullWidth
          onChange={changeName}
        />
        <TextField
          id="release_notes"
          name="release_notes"
          label="Release Notes"
          variant="outlined"
          margin="normal"
          inputProps={{
            maxLength: "255",
          }}
          value={releaseNotes}
          fullWidth
          onChange={changeReleaseNotes}
        />
        <DropDownList label="Type" data={manifestTypes} classes={classes} onChange={changeType} value={type} />
        <DropDownList label="Active" data={activeStates} classes={classes} onChange={changeActive} value={active} />
        <DropDownList label="Rollback" data={booleanStates} classes={classes} onChange={changeRollback} value={rollback} />
        {
          ENVS.length > 1 && <DropDownList label="ECC Keys" data={ENVS} classes={classes} onChange={changeEnv} value={env} />
        }
        <NumberField
          name="Update Duration"
          value={updateDuration}
          setValue={changeUpdateDuration}
        />
        <NumberField
          name="Max Attempts"
          value={maxAttempts}
          setValue={changeMaxAttempts}
        />
        <FormControlLabel control={
          <Checkbox
            checked={notifySAP}
            onChange={changeNotifySAP}
          />
        } label="Notify SAP for OTA Campaign" />
        <Button
          type="submit"
          aria-label="send command"
          disabled={busy || manifest == null}
          fullWidth
          variant="contained"
          color="primary"
          className={classes.submit}
          onClick={onSubmit}
        >
          {busy ? "Updating..." : "Update"}
        </Button>
        <RoleWrap
          groups={groups}
          providers={providers}
          rolesPerProvider={Permissions.ManifestMigration}
        >
          <Button
            type="button"
            aria-label="migrate manifest"
            disabled={busy || manifest == null}
            fullWidth
            variant="contained"
            color="secondary"
            className={classes.submit}
            onClick={manifestMigrate}
          >
            {busy ? "Migrating..." : "Migrate"}
          </Button>
        </RoleWrap>

      </FormControl>
    </div>
  );
}

const ManifestUpdate = () => (
  <ManifestsProvider>
    <MainForm />
  </ManifestsProvider>
);

export default ManifestUpdate;
