import * as React from 'react';
import FramePayError from '../../framepay-error';
import BaseElement from './base-element';
import type { BankProps, BankState } from '../../../../types/elements';
import type { IframeElementEventMap } from '@rebilly/framepay';

export default class BankElement extends BaseElement<BankProps, BankState> {
    setupElement() {
        const { onReady, onChange, onFocus, onBlur, elementType } = this.props;

        const makeElement = () => {
            // elementNode already checked in BaseElement.handleSetupElement
            // just ts checks fix
            if (!this.elementNode) {
                throw FramePayError({
                    code: FramePayError.codes.elementMountError,
                    details: `BankElement invalid elementNode, elementType: ${
                        elementType || 'default'
                    }`,
                });
            }

            try {
                return this.props.Framepay.bankAccount.mount(
                    this.elementNode,
                    elementType,
                );
            } catch (e) {
                throw FramePayError({
                    code: FramePayError.codes.elementMountError,
                    details: `BankElement error in remote api call, elementType: ${
                        elementType || 'default'
                    }`,
                    trace: e,
                });
            }
        };

        const element = makeElement();

        try {
            element.on('ready', () => {
                this.setState({ ready: true }, () => {
                    if (onReady) {
                        onReady();
                    }
                });
            });

            element.on('change', (data: IframeElementEventMap['change'][0]) => {
                if (onChange) {
                    onChange(data);
                }
            });

            element.on('focus', () => {
                if (onFocus) {
                    onFocus();
                }
            });

            element.on('blur', () => {
                if (onBlur) {
                    onBlur();
                }
            });

            this.setState({ element });
        } catch (e) {
            throw FramePayError({
                code: FramePayError.codes.elementMountError,
                details: `BankElement events binding error, elementType: ${
                    elementType || 'default'
                }`,
                trace: e,
            });
        }
    }
}
