import React, { Component } from 'react';

import { FramePayProvider, withFramePayCardComponent } from '../../../build';
import {
    deepMerge,
    prettyDebugRender,
    ReactVersion,
    renderFixture,
} from './util';
import './style.css';

const params = {
    publishableKey: 'pk_sandbox_c6cqKLddciVikuBOjhcng-rLccTz70NT4W_qZ_h',
    style: {
        base: {
            color: 'green',
            fontSize: '12px',
            webkitFontSmoothing: 'auto',
            fontFeatureSettings: 'test',
            fontStyle: 'italic',
            fontVariant: 'normal',
            fontStretch: 'none',
            fontSomething: 'not-included',
            fontOtherThing: 'not-included',
            lineHeight: '20px',
        },
        invalid: {
            fontWeight: 'bold',
        },
    },
    classes: {
        base: 'rebilly-framepay',
        focus: 'rebilly-framepay-focus',
        valid: 'rebilly-framepay-valid',
        invalid: 'rebilly-framepay-invalid',
        buttons: 'rebilly-framepay-buttons',
        webkitAutofill: 'rebilly-framepay-webkit-autofill',
    },
    icon: {
        foobar: 123,
        display: true,
        color: 'blue',
    },
    riskMetadata: {
        browserData: {
            colorDepth: '48',
            isJavaEnabled: 'true',
            language: 'en',
            screenHeight: '100',
            screenWidth: '100',
            timeZoneOffset: '0',
        },
        extraData: {
            kountFraudSessionId: 'kountFraudSessionId123',
        },
        fingerprint: 'fingerprint123',
    },
};

class CardElementComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            events: {
                onReady: null,
                onError: null,
                onChange: null,
                onFocus: null,
                onBlur: null,
            },
            billingAddress: {
                firstName: 'first-name-value',
                lastName: 'last-name-value',
                address: 'address-value',
                country: 'GB',
                region: 'region-value',
            },
            token: {
                error: null,
                data: null,
            },
        };
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleSubmit(e) {
        e.preventDefault();
        /**
         *
         * @see https://www.rebilly.com/docs/dev-docs/framepay-global-reference/#framepay.createtoken
         *
         */
        const billingAddress = {
            ...this.state.billingAddress,
        };
        if (billingAddress.emails) {
            billingAddress.emails = [
                {
                    label: 'Email',
                    value: billingAddress.emails,
                },
            ];
        }
        if (billingAddress.phoneNumbers) {
            billingAddress.phoneNumbers = [
                {
                    label: 'Phone Number',
                    value: billingAddress.phoneNumbers,
                },
            ];
        }

        this.props.Framepay.createToken(this.formNode, { billingAddress })
            .then((data) => {
                this.deepUpdateState({ token: { error: false, data } });
            })
            .catch((err) => {
                this.deepUpdateState({ token: { error: true, data: err } });
            });
    }

    deepUpdateState(data) {
        this.setState((prevState) => {
            return deepMerge(prevState, data);
        });
    }

    render() {
        return (
            <div>
                <h2>{this.props.title}</h2>
                <h3>FramePay version: {this.props.Framepay.version}</h3>
                <div className="flex-wrapper">
                    {prettyDebugRender(this.state)}
                    <div className="example-2">
                        <form
                            id="form"
                            ref={(node) => (this.formNode = node)}
                            method="post"
                            onSubmit={this.handleSubmit}
                        >
                            <fieldset>
                                <div className="field">
                                    <input
                                        type="text"
                                        name="firstName"
                                        placeholder="First Name"
                                        defaultValue={
                                            this.state.billingAddress.firstName
                                        }
                                        onChange={(e) => {
                                            this.deepUpdateState({
                                                billingAddress: {
                                                    firstName: e.target.value,
                                                },
                                            });
                                        }}
                                    />
                                </div>
                                <div className="field">
                                    <input
                                        type="text"
                                        name="lastName"
                                        placeholder="Last Name"
                                        defaultValue={
                                            this.state.billingAddress.lastName
                                        }
                                        onChange={(e) => {
                                            this.deepUpdateState({
                                                billingAddress: {
                                                    lastName: e.target.value,
                                                },
                                            });
                                        }}
                                    />
                                </div>
                                <div className="field">
                                    <input
                                        type="text"
                                        name="email"
                                        placeholder="Email"
                                        defaultValue={
                                            this.state.billingAddress.emails
                                        }
                                        onChange={(e) => {
                                            this.deepUpdateState({
                                                billingAddress: {
                                                    emails: e.target.value,
                                                },
                                            });
                                        }}
                                    />
                                </div>
                                <div className="field">
                                    <input
                                        type="text"
                                        name="phone"
                                        placeholder="Phone"
                                        defaultValue={
                                            this.state.billingAddress
                                                .phoneNumbers
                                        }
                                        onChange={(e) => {
                                            this.deepUpdateState({
                                                billingAddress: {
                                                    phoneNumbers:
                                                        e.target.value,
                                                },
                                            });
                                        }}
                                    />
                                </div>
                                <div className="field">
                                    <this.props.CardElement
                                        onError={(err) =>
                                            this.deepUpdateState({
                                                events: { onError: err },
                                            })
                                        }
                                        onReady={() =>
                                            this.deepUpdateState({
                                                events: { onReady: true },
                                            })
                                        }
                                        onChange={(data) =>
                                            this.deepUpdateState({
                                                events: { onChange: data },
                                            })
                                        }
                                        onFocus={() =>
                                            this.deepUpdateState({
                                                events: { onFocus: true },
                                            })
                                        }
                                        onBlur={() =>
                                            this.deepUpdateState({
                                                events: { onBlur: true },
                                            })
                                        }
                                    />
                                </div>
                            </fieldset>
                            <button id="submit">Make Payment</button>
                        </form>
                    </div>
                </div>
            </div>
        );
    }
}

const CardElement = withFramePayCardComponent(CardElementComponent);

class App extends Component {
    deepUpdateState(data) {
        this.setState((prevState) => {
            return deepMerge(prevState, data);
        });
    }

    render() {
        return (
            <FramePayProvider
                {...params}
                onTokenReady={(token) =>
                    this.deepUpdateState({ error: false, data: token })
                }
            >
                <div>
                    {ReactVersion()}
                    <CardElement />
                </div>
            </FramePayProvider>
        );
    }
}

renderFixture(<App />);
