import * as React from 'react';
import * as CSS from 'csstype';

import { Form, FormGroup, ActionGroup, FileUpload, Avatar, Button, Tooltip } from "@patternfly/react-core";
import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons';
import { AccountServiceContext } from '../../account-service/AccountServiceContext';
import { ContentAlert } from '../ContentAlert';
import { Msg } from '../../widgets/Msg';


interface AvatarFormProps {
    accountUrl: string;
}

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

export class AvatarForm extends React.Component<AvatarFormProps, AvatarFormState> {
    static contextType = AccountServiceContext;
    context: React.ContextType<typeof AccountServiceContext>;
    private handleFileInputChange: any;

    constructor(props: AvatarFormProps, context: React.ContextType<typeof AccountServiceContext>) {
        super(props);
        this.context = context;

        var currentAvatar = props.accountUrl + "-avatar"
        this.state = {
            errors: {avatar: ''},
            imageBlob: null,
            filename: "",
            avatarUrl: currentAvatar,
            avatarSrc: currentAvatar,
            noAvatarSrc: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMiwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzNiAzNiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzYgMzY7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRjBGMEYwO30KCS5zdDF7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRDJEMkQyO30KCS5zdDJ7ZmlsbDojQjhCQkJFO30KCS5zdDN7ZmlsbDojRDJEMkQyO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjM2IiBoZWlnaHQ9IjM2Ii8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xNy43LDIwLjFjLTMuNSwwLTYuNC0yLjktNi40LTYuNHMyLjktNi40LDYuNC02LjRzNi40LDIuOSw2LjQsNi40UzIxLjMsMjAuMSwxNy43LDIwLjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMy4zLDM2bDAtNi43Yy0yLDAuNC0yLjksMS40LTMuMSwzLjVMMTAuMSwzNkgxMy4zeiIvPgo8cGF0aCBjbGFzcz0ic3QzIiBkPSJNMTAuMSwzNmwwLjEtMy4yYzAuMi0yLjEsMS4xLTMuMSwzLjEtMy41bDAsNi43aDkuNGwwLTYuN2MyLDAuNCwyLjksMS40LDMuMSwzLjVsMC4xLDMuMmg0LjcKCWMtMC40LTMuOS0xLjMtOS0yLjktMTFjLTEuMS0xLjQtMi4zLTIuMi0zLjUtMi42cy0xLjgtMC42LTYuMy0wLjZzLTYuMSwwLjctNi4xLDAuN2MtMS4yLDAuNC0yLjQsMS4yLTMuNCwyLjYKCUM2LjcsMjcsNS44LDMyLjIsNS40LDM2SDEwLjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0yNS45LDM2bC0wLjEtMy4yYy0wLjItMi4xLTEuMS0zLjEtMy4xLTMuNWwwLDYuN0gyNS45eiIvPgo8L3N2Zz4="
        }

        var reader = new FileReader()
        reader.onloadend = function (event: any) {
            var imgData = String(event.target!.result)
            this.imageScale(imgData, (blob: Blob) => {
                this.setState({
                    imageBlob: blob,
                    avatarSrc: URL.createObjectURL(blob)
                })
            })
        }.bind(this)
  
        this.handleFileInputChange = (file: File, filename: string) => {
            if (filename != "") {
                this.setState({ filename: filename })
                reader.readAsDataURL(file)
            } else {
                this.setState({
                    imageBlob: null,
                    filename: "",
                    avatarSrc: currentAvatar
                })
            }
        }
    }

    private 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)
        }
    }

    private handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
        event.preventDefault()
        const form = event.target as HTMLFormElement
        var formData = new FormData(form)
        formData.append("image", this.state.imageBlob)
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = () => {
            if (xhr.readyState == 4) {
                if (200 <= xhr.status && xhr.status <= 204) {
                    ContentAlert.success('avatarUpdatedMessage')
                } else {
                    ContentAlert.danger(xhr.response)
                }
                // force reload avatar
                this.setState({
                    errors: {avatar: ""},
                    imageBlob: null,
                    filename: "",
                    avatarSrc: this.state.avatarUrl
                })
            }
        }
        xhr.open(form.method, form.action, true);
        xhr.send(formData);
    }

    private handleError = (event: any) => {
        this.setState({
            errors: {avatar: Msg.localize('error-noAvatarFound')},
            avatarSrc: ""
        })
    }

    render() {
        const { filename, avatarUrl, avatarSrc, noAvatarSrc } = this.state
        const avatarStyle: CSS.Properties = {
            objectFit: 'cover',
            width: '150px', height: '150px',
            border: '1px solid lightgray',
            boxShadow: 'lightgray 6px 3px 10px 2px'
        }
        return (
            <Form id="avatarForm" method="post"
                action={avatarUrl} encType="multipart/form-data"
                onSubmit={event => this.handleSubmit(event)}
            >
                <FormGroup label={Msg.localize('avatarLabel')}
                    fieldId="avatar-current-or-preview"
                    helperTextInvalid={this.state.errors.avatar}
                    validated={this.state.errors.avatar === '' ? 'success' : 'error'}
                >
                    { avatarSrc !== ""
                        ? <Avatar src={avatarSrc} style={avatarStyle} alt="Avatar image preview" onError={this.handleError}/>
                        : <Avatar src={noAvatarSrc} style={avatarStyle} alt="No avatar found" />
                    }
                </FormGroup>

                <FormGroup
                    fieldId="avatar-upload"
                    label={<span>
                        <Msg msgKey="uploadLabel" />
                        {' '}
                        <Tooltip content={<Msg msgKey="avatarInfo" />}>
                            <OutlinedQuestionCircleIcon />
                        </Tooltip>                            
                    </span>}
                >
                    <FileUpload
                        id="simple-file"
                        filename={filename}
                        filenamePlaceholder={Msg.localize('dragdropInfo')}
                        browseButtonText={Msg.localize('browseButton')}
                        clearButtonText={Msg.localize('clearButton')}
                        onChange={this.handleFileInputChange}
                    />

                </FormGroup>

                <ActionGroup>
                    <Button
                        id="save-btn" type="submit"
                        variant="primary"
                        isDisabled={filename === ""}
                    >
                        <Msg msgKey="doSave" />
                    </Button>
                </ActionGroup>
            </Form>
        )
    }
}
