import React, { Component } from 'react'
import PropTypes from 'prop-types'

import { isMobile } from 'react-device-detect'
import axios from 'axios'
import http from 'http'
import https from 'https'

import { routes } from './constants'
import * as constants from './constants'
import { defaultStyles } from './config'

import PrivacyNotice from './PrivacyNotice.jsx'
import DocumentSelection from './DocumentSelection.jsx'
import WebcamCapture from './WebcamCapture.jsx'
import ConfirmationScreen from './ConfirmationScreen.jsx'
import Selfie from './Selfie.jsx'
import Upload from './Upload.jsx'
import Response from './Response.jsx'

class Controller extends Component {

    constructor(props) {
        super(props)

        this.state = {
            config: this.props.config,
            screen: routes.PRIVACY_SCREEN,
            documentType: constants.OTHER,
            images: {},
            loading: false
        }
    }
    
    componentDidUpdate(prevProps, prevState) {
        if (prevProps.config != this.props.config) {
            this.setState({
                config: this.props.config
            })
        }
    }
    
    componentDidMount() {
        if(this.state.config.privacy.show === true &&
           localStorage.getItem('TermsAndConditions') !== "true") {
            this.setState({
                screen: routes.PRIVACY_SCREEN,
            }, this.forceUpdate())
        } else {
            this.setState({
                screen: routes.DOCUMENT_SCREEN,
            }, this.forceUpdate())
        }
    }

    switchScreen = (nextScreen) => {
        this.setState({
            screen: nextScreen
        }, this.forceUpdate())
    }
    
    setDocumentType = (type) => {
        this.setState({
            documentType: type
        })
    }
    
    processImage = (image) => {
        this.setState({
            loading: true
        })
        
        var Jimp = require('jimp')
        Jimp.read(image).then((image) => {
            var x = 50
            var y = 25
            var width = image.bitmap.width - 100
            var height = image.bitmap.height - (window.innerHeight / 4.5)
            if(isMobile) {
                x = 25
                width = image.bitmap.width - 50
                height = image.bitmap.height - (window.innerHeight / 1.5)
            }
            
            if(this.state.documentType === constants.SELFIE) {
                x = 100
                y = 25
                width = image.bitmap.width - 200
                height = image.bitmap.height - (window.innerHeight / 4)
                if(isMobile) {
                    x = 50
                    width = image.bitmap.width - 100
                    height = image.bitmap.height - (window.innerHeight / 2)
                }
            }
            
            image.crop(x, y, width, height).getBase64Async(Jimp.MIME_JPEG).then((image) => {
                fetch(image).then(res => res.blob()).then(imageBlob => {
                    this.setState({
                        loading: false
                    })
                    
                    var images = this.state.images
                    if(this.state.documentType === constants.SELFIE) {
                        images.user_selfie_base64 = image.replace("data:image/jpeg;base64,", "")
                        images.user_selfie = imageBlob
                        this.setState({
                            images: images
                        });
                        this.switchScreen(routes.UPLOAD_SCREEN)
                        this.callEynAPI()
                    }
                    if(this.state.documentType === constants.ID_FRONT) {
                        images.identity_document_image_front_base64 = image.replace("data:image/jpeg;base64,", "")
                        images.identity_document_image_front = imageBlob
                        this.setState({
                            images: images,
                            documentType: constants.ID_BACK
                        })
                        return
                    }
                    if(this.state.documentType === constants.ID_BACK ||
                       this.state.documentType === constants.VISA ||
                       this.state.documentType === constants.PASSPORT ||
                       this.state.documentType === constants.OTHER) {
                        images.identity_document_image_mrz_base64 = image.replace("data:image/jpeg;base64,", "")
                        images.identity_document_image_mrz = imageBlob
                        this.setState({
                            images: images
                        }, this.switchScreen(routes.CONFIRMATION_SCREEN))
                    }
                })
            })
        })
    }
    
    callEynAPI = async () => {
        this.setState({
            loading: true
        })

        var startTime = Math.floor(Date.now())
        var payload = {}
        
        if ('identity_document_image_front_base64' in this.state.images) {
            payload.document_front_base64_encoded = this.state.images.identity_document_image_front_base64
            payload.document_back_base64_encoded = this.state.images.identity_document_image_mrz_base64
        } else {
            payload.document_front_base64_encoded = this.state.images.identity_document_image_mrz_base64
        }
        payload.selfie_base64_encoded = this.state.images.user_selfie_base64
        payload.eyn_ocr_token = this.state.config.apiSecret

        let axiosInstance = axios.create({
            timeout: 120000,
            httpAgent: new http.Agent({ keepAlive: true }),
            httpsAgent: new https.Agent({ keepAlive: true }),
            maxRedirects: 10,
            maxContentLength: 50 * 1000 * 1000
        })
        axiosInstance({
            url: this.state.config.baseUrl,
            method: "POST",
            data: payload
        }).then((response) => {
            var endTime = Math.floor(Date.now())
            var responseTime = (endTime - startTime) / 1000
            this.setState({
                response: response.data,
                responseTime: responseTime,
                loading: false
            })
            console.log(response)
            this.switchScreen(routes.RESPONSE_SCREEN)
        }).catch((error) => {
            this.setState({
                loading: false
            })
            console.log(error)
            this.props.enqueueSnackbar(
                "An error occured during the upload of your document. Please try again.", {
                variant: "error",
                anchorOrigin: {
                     vertical: 'bottom',
                     horizontal: 'center',
                 }})
        })
    }

    render() {
        return (
            <div>
                { /* Header */ }
                <div style={defaultStyles.container}>
                    <div style={defaultStyles.header}>
                        <table>
                        <tbody>
                        <tr>
                        <td>
                            <img
                                src={this.state.config.resources.images.logoTitle}
                                height="40"
                                alt="logo">
                            </img>
                        </td>
                        <td>
                            <p style={{
                                position: "absolute",
                                top: 0,
                                bottom: 0,
                                margin: "auto",
                                marginTop: 10,
                                whiteSpace: "nowrap",
                                fontWeight: 400
                            }}>
                                {this.state.config.title}
                            </p>
                        </td>
                        </tr>
                        </tbody>
                        </table>
                    </div>
                
                    { /* Privacy Notice */ }
                    { this.state.screen === routes.PRIVACY_SCREEN?
                    <PrivacyNotice
                        config={this.props.config}
                        switchScreen={() => { this.switchScreen(routes.DOCUMENT_SCREEN) }}
                    />
                    : <div></div>
                    }
            
                    { /* Document Selection */ }
                    { this.state.screen === routes.DOCUMENT_SCREEN?
                    <DocumentSelection
                        config={this.props.config}
                        selectDocument={(type) => {
                            this.setDocumentType(type)
                            this.switchScreen(routes.WEBCAM_SCREEN)
                        }}
                    />
                    : <div></div>
                    }
                
                    { /* Webcam Capture */ }
                    { this.state.screen === routes.WEBCAM_SCREEN?
                    <WebcamCapture
                        config={this.props.config}
                        loading={this.state.loading}
                        open={this.state.screen === routes.WEBCAM_SCREEN}
                        close={() => {}}
                        documentType={this.state.documentType}
                        processImage={(image) => { this.processImage(image) }}
                    />
                    : <div></div>
                    }
                
                    { /* Confirmation Screen */ }
                    { this.state.screen === routes.CONFIRMATION_SCREEN?
                    <ConfirmationScreen
                        config={this.props.config}
                        images={this.state.images}
                        confirm={() => {
                            this.setDocumentType(constants.SELFIE)
                            this.switchScreen(routes.SELFIE_SCREEN)
                        }}
                        retake={() => { this.switchScreen(routes.WEBCAM_SCREEN) }}
                    />
                    : <div></div>
                    }
                
                    { /* Selfie */ }
                    { this.state.screen === routes.SELFIE_SCREEN?
                    <Selfie
                        config={this.props.config}
                        takeSelfie={() => { this.switchScreen(routes.WEBCAM_SCREEN) }}
                    />
                    : <div></div>
                    }

                    { /* Upload */ }
                    { this.state.screen === routes.UPLOAD_SCREEN?
                    <Upload
                        config={this.props.config}
                    />
                    : <div></div>
                    }

                    { /* Response */ }
                    { this.state.screen === routes.RESPONSE_SCREEN?
                    <Response
                        config={this.props.config}
                        responseTime={this.state.responseTime}
                    />
                    : <div></div>
                    }

                </div>
            </div>
            )
    }
}

export default Controller;
