"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
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 });
/* eslint-disable react/jsx-props-no-spreading */
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const components_1 = require("../../themes/components");
const ConfigProvider_1 = require("../../utils/ConfigProvider");
const GiftedChat_1 = require("../../consolidatedLibraries/GiftedChat");
const react_native_user_avatar_1 = __importDefault(require("react-native-user-avatar"));
const styled_components_1 = require("styled-components");
const browser_utils_1 = require("../../utils/browser-utils");
const react_redux_1 = require("react-redux");
const APITypes_1 = require("../../types/APITypes");
const PeersService_1 = require("../../services/PeersService");
const MediaRoomService_1 = require("../../services/MediaRoomService");
const ImagePicker_1 = require("../../consolidatedLibraries/ImagePicker");
const DocumentPicker_1 = __importDefault(require("../../consolidatedLibraries/DocumentPicker"));
const graphql_hooks_1 = require("graphql-hooks");
const roomSlice_1 = require("../../store/roomSlice");
const keyboardViewSpace_1 = __importDefault(require("../keyboardViewSpace"));
const borderRadius_1 = __importDefault(require("../../themes/foundations/borderRadius"));
const OrientationContext_1 = require("../../services/OrientationContext");
const config_1 = __importDefault(require("../../utils/config"));
const logger_1 = require("../../utils/logger");
const permissions_1 = require("../../consolidatedLibraries/permissions");
// import { ReactNativeFile } from 'apollo-upload-client';
const UPLOAD_FILE = `
    mutation($file: Upload!, $roomName: String!) {
        uploadFile(file: $file, roomName: $roomName) {
            link
        }
    }
`;
const styles = {
    attachementButtons: {
        display: 'flex',
        flexDirection: 'row',
        backgroundColor: 'secondary.700',
        marginTop: 20,
        marginRight: 5,
        width: 100,
        height: 35,
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 30,
    },
    touchableIcons: {
        backgroundColor: 'secondary.700',
        borderRadius: 15,
        width: 30,
        height: 30,
        align: 'center',
        justify: 'center',
        mt: 8,
        mb: 8,
    },
    attachemenetView: {
        position: 'absolute',
        top: react_native_1.Platform.OS === 'ios' ? -130 : -15,
        left: react_native_1.Platform.OS === 'ios' ? 8 : 48,
        direction: react_native_1.Platform.OS === 'ios' ? 'column' : 'row',
    },
};
const AttachementParentContainerDecider = ({ children }) => react_native_1.Platform.OS === 'ios' ? (react_1.default.createElement(components_1.Box, Object.assign({}, styles.attachemenetView), children)) : (react_1.default.createElement(components_1.Flex, Object.assign({}, styles.attachemenetView), children));
const MobileChatTab = (props) => {
    const dispatch = react_redux_1.useDispatch();
    const { meeting, sessionConfig } = react_1.useContext(ConfigProvider_1.ConfigServiceContext);
    const chatAllowed = sessionConfig.permissions.chat.public.can_send;
    const { colors } = react_1.useContext(styled_components_1.ThemeContext);
    const windowDimensions = browser_utils_1.useWindowDimensions();
    const chatMessages = react_redux_1.useSelector((state) => state.room.chatMessages);
    const { selfPeer } = react_1.useContext(PeersService_1.PeersServiceContext);
    const { height, width } = browser_utils_1.useScale(sessionConfig.theme.dimensions || windowDimensions);
    const [text, onChangeText] = react_1.default.useState('');
    const [showAttachments, toggleAttachments] = react_1.default.useState(false);
    const { mediaRoom } = react_1.useContext(MediaRoomService_1.MediaRoomContext);
    const [loadingPicker, setLoadingPicker] = react_1.default.useState(false);
    const [messages, setMessages] = react_1.useState([]);
    const roomName = react_redux_1.useSelector((state) => state.room.roomName);
    const polls = react_redux_1.useSelector((state) => state.room.polls);
    // const userVotedFor = React.useState<VotedFor>({});
    const unread = chatMessages.filter((m) => m.read !== true);
    // const drawerHeight = Math.floor(height*2/3);
    const [uploadFile] = graphql_hooks_1.useMutation(UPLOAD_FILE);
    const { orientation } = react_1.default.useContext(OrientationContext_1.OrientationContext);
    const isLandscape = orientation === 'LANDSCAPE';
    function onVotedInAPoll(pollId, selectetAnswer, index) {
        mediaRoom.votePoll({
            index,
            pollId,
        });
    }
    react_1.useEffect(() => {
        const msgs = [...chatMessages];
        setMessages(msgs.reverse().map((m) => {
            const messageBase = {
                type: m.type,
                createdAt: m.time,
                _id: Math.round(Math.random() * 1000000),
                user: {
                    _id: m.userId,
                    name: m.displayName,
                },
            };
            if (m.type === APITypes_1.MessageTypes.text) {
                return Object.assign(Object.assign({}, messageBase), { text: m.message });
            }
            if (m.type === APITypes_1.MessageTypes.image) {
                return Object.assign(Object.assign({}, messageBase), { image: m.link });
            }
            if (m.type === APITypes_1.MessageTypes.file) {
                return Object.assign(Object.assign({}, messageBase), { text: m.name, link: m.link });
            }
            if (m.type === APITypes_1.MessageTypes.poll) {
                const { pollId } = m;
                const pollData = polls[pollId];
                const { options, question } = pollData;
                const selfId = selfPeer.userId;
                return Object.assign(Object.assign({}, messageBase), { text: question, polls: {
                        pollId,
                        options: options.map((el) => {
                            const selfVote = el.votes.find((v) => v.id === selfId);
                            if (selfVote) {
                                return Object.assign(Object.assign({}, el), { selected: true });
                            }
                            return Object.assign(Object.assign({}, el), { selected: false });
                        }),
                        onOptionSelected: onVotedInAPoll,
                    } });
            }
            return {};
        }));
    }, [chatMessages, polls]);
    react_1.useEffect(() => {
        // if (unread.length > 0) dispatch(markMessagesRead(null));
        if (unread.length > 0) {
            dispatch(roomSlice_1.markMessagesRead({
                [APITypes_1.MessageTypes.text]: true,
                [APITypes_1.MessageTypes.file]: true,
                [APITypes_1.MessageTypes.image]: true,
                [APITypes_1.MessageTypes.poll]: true,
            }));
        }
    }, [unread]);
    const onTextMessageSend = () => {
        if (text && text.trim()) {
            const t = {
                message: text,
                userId: selfPeer.userId,
                displayName: selfPeer.displayName,
                type: APITypes_1.MessageTypes.text,
                time: new Date().getTime(),
            };
            mediaRoom.sendMessage(t);
            onChangeText('');
        }
    };
    const sendImage = (link) => {
        const image = {
            displayName: selfPeer.displayName,
            type: APITypes_1.MessageTypes.image,
            link,
            userId: selfPeer.id,
            time: new Date().getTime()
        };
        mediaRoom.sendMessage(image);
    };
    const sendFile = (link, name, size) => {
        const file = {
            displayName: selfPeer.displayName,
            type: APITypes_1.MessageTypes.file,
            link,
            userId: selfPeer.id,
            name,
            size,
            time: new Date().getTime()
        };
        mediaRoom.sendMessage(file);
    };
    const getBlob = (fileUri) => __awaiter(void 0, void 0, void 0, function* () {
        const resp = yield fetch(fileUri);
        const imageBody = yield resp.blob();
        return imageBody;
    });
    function uploadItems(fileProps, presignedURL, uri) {
        return __awaiter(this, void 0, void 0, function* () {
            const fileBody = yield getBlob(uri);
            yield fetch(presignedURL, {
                method: 'PUT',
                headers: {
                    'Content-Type': fileProps.type,
                },
                body: fileBody,
            });
        });
    }
    function getPresignedURLs(fileProps) {
        return __awaiter(this, void 0, void 0, function* () {
            const fetchURL = `${config_1.default.apiBase}/v1/meetings/genPreSignedUploadUrl`;
            const presignedURLReq = yield fetch(fetchURL, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ roomName, filename: fileProps.name }),
            });
            const presignedURLs = (yield presignedURLReq.json()).data;
            const getPresignedURL = presignedURLs.getLocation;
            const putPresignedURL = presignedURLs.putLocation;
            return {
                getURL: getPresignedURL,
                putURL: putPresignedURL,
            };
        });
    }
    const uploadError = (errorMessage) => {
        react_native_1.Alert.alert('Error', `Error: ${errorMessage || 'Problem uploading image'}`, [{ text: 'OK' }]);
        setLoadingPicker(false);
    };
    const onSelectImage = () => {
        try {
            if (!loadingPicker) {
                setLoadingPicker(true);
                toggleAttachments(false);
                ImagePicker_1.launchImageLibrary({ mediaType: 'photo' }, (res) => __awaiter(void 0, void 0, void 0, function* () {
                    // For example user have not give permission to share images
                    const { uri, didCancel, errorCode, errorMessage, fileName, type, fileSize, } = res;
                    if (didCancel) {
                        setLoadingPicker(false);
                    }
                    else if (errorCode) {
                        logger_1.Logger.addEventInCurrentSpan("error", 'Error Uploading Image:', {
                            errorCode,
                            errorMessage
                        });
                        uploadError(errorMessage);
                    }
                    else {
                        const imgProps = {
                            name: fileName,
                            type,
                            uri,
                        };
                        if (fileSize > 5000000) {
                            react_native_1.Alert.alert('Error', 'Error: Cannot upload files greater than 5MB', [{ text: 'OK' }]);
                            return;
                        }
                        const presignedURLs = yield getPresignedURLs(imgProps);
                        yield uploadItems(imgProps, presignedURLs.putURL, imgProps.uri);
                        sendImage(presignedURLs.getURL);
                        setLoadingPicker(false);
                    }
                }));
            }
        }
        catch (error) {
            // console.log('Error Uploading Image:', error);
            uploadError();
        }
        finally {
            react_native_1.Keyboard.dismiss();
        }
    };
    const onSelectAttachement = () => __awaiter(void 0, void 0, void 0, function* () {
        if (!loadingPicker) {
            setLoadingPicker(true);
            toggleAttachments(false);
            try {
                const res = yield DocumentPicker_1.default.pick({
                    type: [DocumentPicker_1.default.types.allFiles],
                });
                const { uri, name, size } = res;
                const file = {
                    displayName: selfPeer.displayName,
                    type: APITypes_1.MessageTypes.file,
                    link: uri,
                    userId: selfPeer.id,
                    name,
                    size,
                };
                if (size > 5000000) {
                    react_native_1.Alert.alert('Error', 'Error: Cannot upload files greater than 5MB', [{ text: 'OK' }]);
                    return;
                }
                const presignedURLs = yield getPresignedURLs(file);
                yield uploadItems(file, presignedURLs.putURL, file.link);
                sendFile(presignedURLs.getURL, name, size);
                setLoadingPicker(false);
            }
            catch (err) {
                if (DocumentPicker_1.default.isCancel(err)) {
                    setLoadingPicker(false);
                }
                else {
                    uploadError();
                }
            }
            finally {
                react_native_1.Keyboard.dismiss();
            }
        }
    });
    const renderAttachments = () => showAttachments && (react_1.default.createElement(AttachementParentContainerDecider, null,
        react_1.default.createElement(components_1.Button, { onClick: onSelectImage },
            react_1.default.createElement(components_1.Box, Object.assign({}, styles.attachementButtons),
                react_1.default.createElement(components_1.Icon, { name: "image", fill: "textPrimary.100" }),
                react_1.default.createElement(components_1.Text, { ml: 8 }, " Images"))),
        react_1.default.createElement(components_1.Button, { onClick: onSelectAttachement },
            react_1.default.createElement(components_1.Box, Object.assign({}, components_1.mergeStyles(styles.attachementButtons, {
                width: react_native_1.Platform.OS === 'ios' ? 150 : 120,
            })),
                react_1.default.createElement(components_1.Icon, { name: "attach-file", fill: "textPrimary.100" }),
                react_1.default.createElement(components_1.Text, { ml: react_native_1.Platform.OS === 'ios' ? 8 : 0 },
                    ' ',
                    "Attachments")))));
    const renderBubble = (props) => {
        const { type, link, text } = props.currentMessage;
        return (react_1.default.createElement(GiftedChat_1.Bubble, Object.assign({}, props, { wrapperStyle: {
                left: {
                    backgroundColor: colors.secondary[800],
                    borderRadius: borderRadius_1.default.medium,
                    paddingVertical: 6,
                    paddingHorizontal: 3,
                },
                right: {
                    backgroundColor: colors.secondary[800],
                    borderRadius: borderRadius_1.default.medium,
                    paddingVertical: 6,
                    paddingHorizontal: 3,
                },
            }, textStyle: {
                left: {
                    color: colors.textPrimary[100],
                },
                right: {
                    color: colors.textPrimary[100],
                },
            } })));
    };
    return (react_1.default.createElement(components_1.Flex, { height: height - 50, align: "center", width: width },
        react_1.default.createElement(keyboardViewSpace_1.default, null,
            react_1.default.createElement(GiftedChat_1.GiftedChat, { messagesContainerStyle: {
                    paddingTop: 60,
                }, messages: messages, alwaysShowSend: true, renderAvatarOnTop: true, renderUsernameOnMessage: true, isKeyboardInternallyHandled: false, timeTextStyle: {
                    left: {
                        color: colors.textPrimary[400],
                    },
                    right: {
                        color: colors.textPrimary[400],
                    },
                }, renderAvatar: (props) => (react_1.default.createElement(react_native_user_avatar_1.default, { name: props.currentMessage.user.name.replace(/[^\w\s]/gi, ''), bgColor: colors.primary[700] })), renderBubble: renderBubble, renderInputToolbar: (props) => chatAllowed && (react_1.default.createElement(components_1.Flex, { width: isLandscape ? width - 60 : width - 20, direction: "row", justify: "space-between", align: "center", bg: "secondary.800", borderRadius: "50px", height: 50 },
                    react_1.default.createElement(components_1.Box, null,
                        react_1.default.createElement(components_1.Button, { onClick: () => {
                                if (!showAttachments) {
                                    permissions_1.setupPermissions(['externalStorage', 'photos', 'readExternalStorage']);
                                }
                                toggleAttachments(!showAttachments);
                            } },
                            react_1.default.createElement(components_1.Box, Object.assign({}, components_1.mergeStyles(styles.touchableIcons, {
                                ml: 8,
                            })), !showAttachments ? (react_1.default.createElement(components_1.Icon, { name: "plus-thick", fill: "textPrimary.100", boxSize: "sm" })) : (react_1.default.createElement(components_1.Icon, { name: "close", fill: "textPrimary.100", boxSize: "sm" })))),
                        renderAttachments()),
                    react_1.default.createElement(react_native_1.TextInput, { style: {
                            color: colors.textPrimary[300],
                            paddingHorizontal: 5,
                            height: 40,
                            width: isLandscape
                                ? width - 160
                                : width - 120,
                        }, onChangeText: onChangeText, value: text }),
                    react_1.default.createElement(components_1.Button, { onClick: onTextMessageSend, height: 40, width: 40, disabled: !(text && text.trim()) },
                        react_1.default.createElement(components_1.Box, Object.assign({}, components_1.mergeStyles(styles.touchableIcons, {
                            backgroundColor: `${text && text.trim()
                                ? 'primary.500'
                                : 'secondary.700'}`,
                            mr: 8,
                        })),
                            react_1.default.createElement(components_1.Icon, { name: "send", fill: "textPrimary.100", boxSize: "md" }))))), user: {
                    _id: selfPeer.userId,
                    name: selfPeer.displayName,
                } }))));
};
exports.default = MobileChatTab;
//# sourceMappingURL=MobileChatTab.js.map