import {
  Form,
  FormGroup,
  ActionGroup,
  FileUpload,
  Avatar,
  Button,
  HelperText,
  HelperTextItem
} from "@patternfly/react-core";
import { useState, CSSProperties } from "react";
import { useTranslation } from "react-i18next";
import { useEnvironment } from "../root/KeycloakContext";
import { useAlerts, HelpItem } from "ui-shared";

interface AvatarFormProps {
  accountUrl: string;
}

interface AvatarFormState {
  errors: any;
  imageBlob: any;
  filename: string;
  avatarUrl: string;
  avatarSrc: string;
  noAvatarSrc: string;
}

export const AvatarForm = ({accountUrl} : AvatarFormProps) => {
  const { t } = useTranslation();
  const context = useEnvironment();
  const urlparts = accountUrl.indexOf('?') > 0 ? accountUrl.split('?') : accountUrl;
  const currentAvatarUrl = Array.isArray(urlparts) ? urlparts[0] + "-avatar?" + urlparts[1] : urlparts + "-avatar";
  const noavatar = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMiwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzNiAzNiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzYgMzY7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRjBGMEYwO30KCS5zdDF7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRDJEMkQyO30KCS5zdDJ7ZmlsbDojQjhCQkJFO30KCS5zdDN7ZmlsbDojRDJEMkQyO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjM2Ii8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xNy43LDIwLjFjLTMuNSwwLTYuNC0yLjktNi40LTYuNHMyLjktNi40LDYuNC02LjRzNi40LDIuOSw2LjQsNi40UzIxLjMsMjAuMSwxNy43LDIwLjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMy4zLDM2bDAtNi43Yy0yLDAuNC0yLjksMS40LTMuMSwzLjVMMTAuMSwzNkgxMy4zeiIvPgo8cGF0aCBjbGFzcz0ic3QzIiBkPSJNMTAuMSwzNmwwLjEtMy4yYzAuMi0yLjEsMS4xLTMuMSwzLjEtMy41bDAsNi43aDkuNGwwLTYuN2MyLDAuNCwyLjksMS40LDMuMSwzLjVsMC4xLDMuMmg0LjcKCWMtMC40LTMuOS0xLjMtOS0yLjktMTFjLTEuMS0xLjQtMi4zLTIuMi0zLjUtMi42cy0xLjgtMC42LTYuMy0wLjZzLTYuMSwwLjctNi4xLDAuN2MtMS4yLDAuNC0yLjQsMS4yLTMuNCwyLjYKCUM2LjcsMjcsNS44LDMyLjIsNS40LDM2SDEwLjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0yNS45LDM2bC0wLjEtMy4yYy0wLjItMi4xLTEuMS0zLjEtMy4xLTMuNWwwLDYuN0gyNS45eiIvPgo8L3N2Zz4=";
  const initialState = {
    errors: {avatar: ""},
    imageBlob: null,
    filename: "",
    avatarUrl: currentAvatarUrl,
    avatarSrc: currentAvatarUrl,
    noAvatarSrc: noavatar
  };
  const [state, setState] = useState<AvatarFormState>(initialState);
  const { addAlert, addError } = useAlerts();

  const reader = new FileReader();
  let currentFilename = "";
  reader.onloadend = (event: any) => {
    var imgData = String(event.target!.result)
    imageScale(imgData, (blob: Blob) => {
      setState({
        errors: {avatar: ""},
        imageBlob: blob,
        filename: currentFilename,
        avatarUrl: currentAvatarUrl,
        avatarSrc: URL.createObjectURL(blob),
        noAvatarSrc: noavatar
      })
    })
  };

  const handleFileInputChange = (_: any, file: File) => {
    if (file != null && file.name != "") {
      if (file.type.startsWith("image")) {
        currentFilename = file.name;
        reader.readAsDataURL(file);
      } else {
        console.error("Wrong file type: " + file.type);
      }
    }
  };

  const handleClear = (_: any) => {
    setState(initialState);
  };

  const imageScale = (imgData: string, callback: any) => {
    var img = new Image()
    img.src = imgData
    img.onload = (event: Event) => {
      var canvas = document.createElement("canvas")
      var ctx = canvas.getContext("2d")
      ctx!.drawImage(img, 0, 0)

      var MAX_WIDTH = 250
      var MAX_HEIGHT = 250
      var width = img.width
      var height = img.height

      if (width > height) {
        if (width > MAX_WIDTH) {
          height *= MAX_WIDTH / width
          width = MAX_WIDTH
        }
      } else {
        if (height > MAX_HEIGHT) {
          width *= MAX_HEIGHT / height
          height = MAX_HEIGHT
        }
      }
      canvas.width = width
      canvas.height = height
      ctx = canvas.getContext("2d")
      ctx!.drawImage(img, 0, 0, width, height)
      canvas.toBlob(callback)
    }
  }

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
    event.preventDefault()
    const form = event.target as HTMLFormElement
    var formData = new FormData(form)
    formData.append("image", state.imageBlob)
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = () => {
      if (xhr.readyState == 4) {
        if (200 <= xhr.status && xhr.status <= 204) {
          addAlert(t("avatarUpdatedMessage"));
          // force reload avatar
          setState(initialState);
        } else {
          addError(xhr.response);
        }
      }
    }
    xhr.open(form.method, form.action, true);
    xhr.send(formData);
  }

  const handleError = (event: any) => {
    setState({
      errors: {avatar: t('error-noAvatarFound')},
      imageBlob: null,
      filename: "",
      avatarUrl: "",
      avatarSrc: "",
      noAvatarSrc: noavatar
    })
  };

  const { filename, avatarUrl, avatarSrc, noAvatarSrc } = state;
  const avatarStyle = {
      objectFit: 'cover',
      width: '150px', height: '150px',
      border: '1px solid lightgray',
      boxShadow: 'lightgray 6px 3px 10px 2px'
  } as CSSProperties;

  return (
    <Form id="avatarForm" method="post"
      action={avatarUrl} encType="multipart/form-data"
      onSubmit={handleSubmit}
    >
      <FormGroup label={t('avatarLabel')} fieldId="avatar-current-or-preview">
        <HelperText>
          {state.errors.avatar !== ""
            && <HelperTextItem variant="error" hasIcon>{state.errors.avatar}</HelperTextItem>
          }
        </HelperText>
        { avatarSrc !== ""
            ? <Avatar src={avatarSrc} style={avatarStyle} alt="Avatar image preview" onError={handleError}/>
            : <Avatar src={noAvatarSrc} style={avatarStyle} alt="No avatar found" />
        }
      </FormGroup>
      <FormGroup
        fieldId="avatar-upload"
        label={t('uploadLabel')}
        labelIcon={
          <HelpItem
            helpText={t("avatarInfo")}
            fieldLabelId="uploadLabel"
          />
        }
      >
        <FileUpload
          id="simple-file"
          filename={filename}
          filenamePlaceholder={t('dragdropInfo')}
          browseButtonText={t('browseButton')}
          onFileInputChange={handleFileInputChange}
          clearButtonText={t('clearButton')}
          onClearClick={handleClear}
        />
      </FormGroup>
      <ActionGroup>
        <Button
          id="save-btn" type="submit"
          variant="primary"
          isDisabled={filename === ""}
        >
          {t('doSave')}
        </Button>
      </ActionGroup>
    </Form>
  )
};

export default AvatarForm;