"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useVgsCollect = exports.useVgsShow = void 0;
const classnames_1 = __importDefault(require("classnames"));
const react_1 = require("react");
const RoomstayThemeEngine_1 = __importDefault(require("../providers/RoomstayThemeEngine"));
const AsyncAuth_1 = require("../util/AsyncAuth");
const CurrentHotelHook_1 = require("./CurrentHotelHook");
let vgsShowLoader = null;
let VGSShow;
let vgsCollectLoader = null;
const getVGSVaultKey = (vaultName = 'standard') => {
    var _a, _b, _c, _d, _e, _f;
    const { hotel } = (0, CurrentHotelHook_1.useCurrentHotel)();
    const members = (_c = (_b = (_a = hotel === null || hotel === void 0 ? void 0 : hotel.vgs) === null || _a === void 0 ? void 0 : _a.vaultNames) === null || _b === void 0 ? void 0 : _b.members) !== null && _c !== void 0 ? _c : 'tntjyo5u2pi';
    const standard = (_f = (_e = (_d = hotel === null || hotel === void 0 ? void 0 : hotel.vgs) === null || _d === void 0 ? void 0 : _d.vaultNames) === null || _e === void 0 ? void 0 : _e.standard) !== null && _f !== void 0 ? _f : 'tntmupn9ras';
    switch (vaultName) {
        case 'members':
            return members;
        case 'standard':
        default:
            return standard;
    }
};
window.VGSCollect = window.VGSCollect || {};
/**
 * TODO: This only works for the Members vault right now
 *
 * Need to:
 * - Update the serializer
 * - Handle errors better
 */
const useVgsShow = (props) => {
    const vgsKeys = getVGSVaultKey('members');
    const [randomId] = (0, react_1.useState)(btoa((Math.random() * Math.random() * Date.now()).toString()).replace(/=/gi, ''));
    const [isLoading, setIsLoading] = (0, react_1.useState)(false);
    const targetRef = (0, react_1.useRef)(null);
    (0, react_1.useEffect)(() => {
        if (vgsShowLoader === null) {
            vgsShowLoader = (() => __awaiter(void 0, void 0, void 0, function* () {
                try {
                    yield RoomstayThemeEngine_1.default.loadScript('https://js.verygoodvault.com/vgs-show/2.0.2/show.js', 'vgs-show');
                    VGSShow = window.VGSShow.create(vgsKeys, (state) => { }).setEnvironment('live');
                }
                catch (ex) {
                    console.error('Unable to load vgs-show ' + ex.message);
                }
            }))();
        }
    }, []);
    const handleReveal = () => __awaiter(void 0, void 0, void 0, function* () {
        const Auth = yield (0, AsyncAuth_1.getAuth)();
        if (VGSShow && (targetRef === null || targetRef === void 0 ? void 0 : targetRef.current)) {
            targetRef.current.classList.add(randomId);
            setIsLoading(true);
            Auth.currentAuthenticatedUser().then((cognitoData) => {
                const jwtToken = cognitoData.signInUserSession.idToken.jwtToken;
                const revealer = VGSShow.request({
                    name: props.name,
                    method: 'POST',
                    path: '/members/vgs-auth',
                    payload: {
                        [props.name]: `${props.value}`,
                    },
                    headers: {
                        Authorization: jwtToken,
                    },
                    serializers: [VGSShow.SERIALIZERS.replace('(\\d{4})(\\d{4})(\\d{4})(\\d{4})', '$1 $2 $3 $4')],
                    htmlWrapper: 'text',
                    jsonPathSelector: `${props.name}`,
                });
                // TODO: Handle failure on reveal
                revealer.on('revealSuccess', () => {
                    setIsLoading(false);
                });
                revealer.on('revealFail', () => {
                    setIsLoading(false);
                });
                if (targetRef.current)
                    targetRef.current.innerHTML = '';
                revealer.render(`.${randomId}`, props.styles);
            });
        }
    });
    (0, react_1.useEffect)(() => {
        handleReveal();
    }, [VGSShow, targetRef, props.name, props.value]);
    return { targetRef, isLoading };
};
exports.useVgsShow = useVgsShow;
const useVgsCollect = (fields, vaultType = 'standard') => {
    const vaultKey = getVGSVaultKey(vaultType);
    const refs = fields.map(() => {
        return (0, react_1.useRef)(null);
    });
    const getDefaultStateFromFields = () => {
        return fields.map((field) => {
            return {
                isFocused: false,
                isValid: false,
                name: field.name,
                label: field.label,
                type: field.type,
                vgsInput: null,
            };
        });
    };
    const mapInputConfigToVGS = (config) => {
        return Object.assign(Object.assign({ name: config.name, type: config.type }, config.vgsProps), { disabled: config.vgsProps.disabled || undefined });
    };
    const getClassesFormInput = (index, extendedClasses) => {
        var _a;
        const field = inputState[index];
        const config = fields[index];
        if (!field)
            return '';
        return (0, classnames_1.default)('c-input', 'c-input--vgs', extendedClasses, {
            '--selected': field.isFocused,
            '--success': field.isValid !== null && field.isValid,
            '--error': field.isValid !== null && !field.isValid,
            '--disabled': !!((_a = config === null || config === void 0 ? void 0 : config.vgsProps) === null || _a === void 0 ? void 0 : _a.disabled),
        });
    };
    const [vgsLoaded, setVgsLoaded] = (0, react_1.useState)(false);
    const [vgsForm, setVgsForm] = (0, react_1.useState)(null);
    const [inputState, setInputState] = (0, react_1.useState)(getDefaultStateFromFields());
    /** Loading VGS, or seeing if it's been loaded before, and binding onto that. */
    (0, react_1.useEffect)(() => {
        let cancelled = false;
        if (vgsCollectLoader === null) {
            vgsCollectLoader = (() => __awaiter(void 0, void 0, void 0, function* () {
                yield RoomstayThemeEngine_1.default.loadScript('https://js.verygoodvault.com/vgs-collect/2.18.1/vgs-collect.js', 'vgs-collect');
                if (!cancelled) {
                    setVgsLoaded(true);
                }
            }))();
        }
        else {
            vgsCollectLoader.then(() => {
                if (!cancelled) {
                    setVgsLoaded(true);
                }
            });
        }
        return () => {
            cancelled = true;
        };
    }, []);
    (0, react_1.useEffect)(() => {
        for (const ref of refs) {
            if (!(ref === null || ref === void 0 ? void 0 : ref.current)) {
                // Means we've still to wait for all the refs to bind
                return;
            }
        }
        if (vgsLoaded && !vgsForm) {
            const form = window.VGSCollect.create(vaultKey, 'live', (state) => {
                setInputState((oldState) => {
                    const newState = [...oldState];
                    for (const input of newState) {
                        const vgsState = state[input.name];
                        if (vgsState) {
                            input.isFocused = vgsState.isFocused;
                            input.isValid = !vgsState.isEmpty ? vgsState.isValid : null;
                            if (input.type === 'card-number') {
                                input.cardType = vgsState.cardType;
                            }
                        }
                    }
                    return newState;
                });
            });
            setVgsForm(form);
            setInputState((oldState) => {
                const newState = [...oldState];
                for (let i = 0; i < newState.length; i++) {
                    const input = newState[i];
                    const inputConfig = fields[i];
                    input.vgsInput = form.field(refs[i].current, mapInputConfigToVGS(inputConfig));
                }
                return newState;
            });
        }
    }, [vgsLoaded, vgsForm, refs]);
    const triggerFieldUpdate = () => {
        var _a, _b;
        for (const ref of refs) {
            if (!(ref === null || ref === void 0 ? void 0 : ref.current)) {
                // Means we've still to wait for all the refs to bind
                return;
            }
        }
        if (!vgsForm) {
            // Means VGS Collect has not loaded yet.
            return;
        }
        for (let i = 0; i < inputState.length; i++) {
            const input = inputState[i];
            const inputConfig = fields[i];
            if (input.vgsInput) {
                (_b = (_a = input.vgsInput).update) === null || _b === void 0 ? void 0 : _b.call(_a, mapInputConfigToVGS(inputConfig));
            }
        }
    };
    return {
        fields: fields.map((item, index) => {
            return {
                ref: refs[index],
                state: inputState[index],
                getClasses: (extendedClasses) => getClassesFormInput(index, extendedClasses),
            };
        }),
        triggerFieldUpdate,
        vgsForm,
    };
};
exports.useVgsCollect = useVgsCollect;
//# sourceMappingURL=VGSHooks.js.map