import React, { useState, FormEvent } from "react";
import {
  Grid,
  Card,
  CardContent,
  TextField,
  CardActions,
  Button,
  Typography,
  Box,
  CardHeader,
  Tabs,
  Tab,
  Select,
  MenuItem,
} from "@material-ui/core";
import {
  useUserDispatch,
  useUserState,
  update,
  selectProject,
  useProjectDispatch,
  useProjectState,
} from "../contexts";
import { usersService } from "../services";
import { useSnackbar } from "notistack";
import ProjectSelect from "../components/ProjectSelect";
import { TextValidator, ValidatorForm } from "react-material-ui-form-validator";
import { Role } from "../types";

const ProfilePage = () => {
  const { enqueueSnackbar } = useSnackbar();
  const { user } = useUserState();
  const authDispatch = useUserDispatch();
  const projectDispatch = useProjectDispatch();
  const { selectedProjectId } = useProjectState();
  const [email, setEmail] = useState(user?.email);
  const [firstName, setFirstName] = useState(user?.firstName);
  const [lastName, setLastName] = useState(user?.lastName);
  const [password, setPassword] = useState("");
  const [tabIndex, setTabIndex] = React.useState(0);

  const handleUserUpdateSubmit = (event: FormEvent) => {
    event.preventDefault();
    if (user && firstName && lastName && email) {
      update(authDispatch, {
        firstName,
        lastName,
        email,
      })
        .then(() =>
          enqueueSnackbar("User updated", {
            variant: "success",
          })
        )
        .catch((err) =>
          enqueueSnackbar(err, {
            variant: "error",
          })
        );
    }
  };

  const handlePasswordUpdateSubmit = (event: FormEvent) => {
    event.preventDefault();
    if (user && password) {
      usersService
        .changePassword(password)
        .then((isChanged) => {
          setPassword("");
        })
        .then(() =>
          enqueueSnackbar("Password updated", {
            variant: "success",
          })
        )
        .catch((err) =>
          enqueueSnackbar(err, {
            variant: "error",
          })
        );
    }
  };

  const errorForTwoChar = "Enter at least two characters.";

  return (
    <Box m={2}>
      <Grid container spacing={1}>
        <Grid item xs={6}>
          <Grid container spacing={1}>
            <Grid item xs={12}>
              <ValidatorForm onSubmit={handleUserUpdateSubmit} instantValidate>
                <Card variant="outlined">
                  <CardHeader title={"User details"} />
                  <CardContent>
                    <Grid container spacing={2}>
                      <Grid item xs={6}>
                        <TextValidator
                          validators={["minStringLength:2"]}
                          errorMessages={[errorForTwoChar]}
                          id="firstName"
                          name="firstName"
                          value={firstName}
                          label={"First name"}
                          type="text"
                          variant="outlined"
                          required
                          fullWidth
                          inputProps={{
                            onChange: (event: any) =>
                              setFirstName(
                                (event.target as HTMLInputElement).value
                              ),
                            "data-testid": "firstName",
                          }}
                        />
                      </Grid>
                      <Grid item xs={6}>
                        <TextValidator
                          validators={["minStringLength:2"]}
                          errorMessages={[errorForTwoChar]}
                          id="lastName"
                          name="lastName"
                          value={lastName}
                          label={"Last name"}
                          type="text"
                          variant="outlined"
                          required
                          fullWidth
                          inputProps={{
                            onChange: (event: any) =>
                              setLastName(
                                (event.target as HTMLInputElement).value
                              ),
                            "data-testid": "lastName",
                          }}
                        />
                      </Grid>
                      <Grid item xs={12}>
                        <TextValidator
                          validators={["isEmail"]}
                          errorMessages={["Enter valid email address"]}
                          id="email"
                          name="email"
                          value={email}
                          label={"Email address"}
                          type="text"
                          variant="outlined"
                          required
                          fullWidth
                          inputProps={{
                            onChange: (event: any) =>
                              setEmail(
                                (event.target as HTMLInputElement).value
                              ),
                            "data-testid": "email",
                          }}
                        />
                      </Grid>
                      <Grid item xs={12}>
                        <Select
                          id="role"
                          labelId="role"
                          displayEmpty
                          fullWidth
                          disabled
                          value={user?.role}
                        >
                          {Object.entries(Role).map(([key, value]) => (
                            <MenuItem key={key} value={key}>
                              {value}
                            </MenuItem>
                          ))}
                        </Select>
                      </Grid>
                    </Grid>
                  </CardContent>
                  <CardActions>
                    <Grid container justifyContent="center">
                      <Grid item>
                        <Button
                          type="submit"
                          color="primary"
                          variant="outlined"
                          data-testid="submit"
                        >
                          Update
                        </Button>
                      </Grid>
                    </Grid>
                  </CardActions>
                </Card>
              </ValidatorForm>
            </Grid>
            <Grid item xs={12}>
              <ValidatorForm
                onSubmit={handlePasswordUpdateSubmit}
                instantValidate
              >
                <Card variant="outlined">
                  <CardHeader title="Change password" />
                  <CardContent>
                    <Grid container spacing={2}>
                      <Grid item xs={12}>
                        <TextValidator
                          validators={["minStringLength:2"]}
                          errorMessages={[errorForTwoChar]}
                          id="password"
                          name="password"
                          value={password}
                          label={"New password"}
                          type="password"
                          variant="outlined"
                          required
                          fullWidth
                          inputProps={{
                            onChange: (event: any) =>
                              setPassword(
                                (event.target as HTMLInputElement).value
                              ),
                            "data-testid": "password",
                          }}
                        />
                      </Grid>
                    </Grid>
                  </CardContent>
                  <CardActions>
                    <Grid container justifyContent="center">
                      <Grid item>
                        <Button
                          type="submit"
                          color="primary"
                          variant="outlined"
                          data-testid="submit"
                        >
                          Update
                        </Button>
                      </Grid>
                    </Grid>
                  </CardActions>
                </Card>
              </ValidatorForm>
            </Grid>
          </Grid>
        </Grid>
        <Grid item xs={6}>
          <Grid container spacing={1}>
            <Grid item xs={12}>
              <Card variant="outlined">
                <CardHeader title={"Api key"} />
                <CardContent>
                  <Typography>{user?.apiKey}</Typography>
                </CardContent>
              </Card>
            </Grid>
            <Grid item xs={12}>
              <Card variant="outlined">
                <CardHeader title={"Configuration examples"} />
                <CardContent>
                  <ProjectSelect
                    onProjectSelect={(id) => selectProject(projectDispatch, id)}
                  />
                  <Tabs
                    variant="fullWidth"
                    value={tabIndex}
                    indicatorColor="primary"
                    textColor="primary"
                    onChange={(
                      event: React.ChangeEvent<{}>,
                      newValue: number
                    ) => {
                      setTabIndex(newValue);
                    }}
                  >
                    <Tab label="Config file" />
                    <Tab label="ENV variables" />
                  </Tabs>
                  <div role="tabpanel" hidden={tabIndex !== 0}>
                    {tabIndex === 0 && (
                      <Box p={3}>
                        <TextField
                          id="configFile"
                          name="configFile"
                          variant="outlined"
                          disabled
                          value={`{
    "apiUrl": "${window._env_.REACT_APP_API_URL}",
    "apiKey": "${user?.apiKey}",
    "project": "${selectedProjectId ?? "Default project"}",
    "branchName": "master",
    "ciBuildId": "commit_sha",
    "enableSoftAssert": false
}`}
                          multiline
                          rows={8}
                          fullWidth
                          helperText="Save as vrt.json in project root. Could be overridden with ENV variables"
                        />
                      </Box>
                    )}
                  </div>
                  <div role="tabpanel" hidden={tabIndex !== 1}>
                    {tabIndex === 1 && (
                      <Box p={3}>
                        <TextField
                          id="envVariables"
                          name="envVariables"
                          variant="outlined"
                          disabled
                          value={`
  VRT_APIURL="${window._env_.REACT_APP_API_URL}"
  VRT_APIKEY="${user?.apiKey}"
  VRT_PROJECT="${selectedProjectId ?? "Default project"} "
  VRT_BRANCHNAME="master"
  VRT_CIBUILDID="commit_sha"
  VRT_ENABLESOFTASSERT=false
  `}
                          multiline
                          rows={8}
                          fullWidth
                          helperText="Add Environment variables inside CI environment"
                        />
                      </Box>
                    )}
                  </div>
                </CardContent>
              </Card>
            </Grid>
          </Grid>
        </Grid>
      </Grid>
    </Box>
  );
};

export default ProfilePage;