import { EMPTY_ARRAY } from '../../Utilities/Constants/GeneralConstants';
import ObjectFactory from '../../Utilities/ObjectFactory';
import { AnnotationsService } from '../../Utilities/Services/AnnotationsService';
/**
 * @ReduxAction A Comment has been added
 */
export const COMMENT_ADD = 'COMMENT_ADD';
/**
 * @ReduxAction A Comment Thread has been added
 */
export const COMMENT_THREAD_ADD = 'COMMENT_THREAD_ADD';
/**
 * @ReduxAction A Comment Thread has been removed
 */
export const COMMENT_THREAD_DELETE = 'COMMENT_THREAD_DELETE';
/**
 * @ReduxAction A Comment has been edited
 */
export const COMMENT_EDIT = 'COMMENT_EDIT';
/**
 * @ReduxAction A Comment has been deleted
 */
export const COMMENT_DELETE = 'COMMENT_DELETE';
/**
 * @ReduxAction Comments Module is ready
 */
export const COMMENTS_READY = 'COMMENTS_READY';
/**
 * @ReduxAction Comments have been loaded
 */
export const COMMENTS_THREADS_LOAD = 'COMMENTS_THREADS_LOAD';
export const CommentThreadsLoad = ({ commentThreads, }) => ({
    type: COMMENTS_THREADS_LOAD,
    commentThreads,
});
export const CommentAdd = ({ comment, cellAddress, }) => ({
    type: COMMENT_ADD,
    comment,
    cellAddress,
});
export const CommentThreadAdd = ({ commentThread, }) => ({
    type: COMMENT_THREAD_ADD,
    commentThread,
});
export const CommentThreadDelete = ({ cellAddress: cellAddress, }) => ({
    type: COMMENT_THREAD_DELETE,
    cellAddress: cellAddress,
});
export const CommentEdit = ({ comment, cellAddress, }) => ({
    type: COMMENT_EDIT,
    comment,
    cellAddress,
});
export const CommentsDelete = ({ commentUuid, cellAddress, }) => ({
    type: COMMENT_DELETE,
    cellAddress,
    commentUuid,
});
export const GetCellCommentSelector = (state, address) => {
    if (!address) {
        return undefined;
    }
    return (state?.CommentThreads ?? []).find((commentThread) => {
        return AnnotationsService.isSameAddress(commentThread, address);
    });
};
const initialState = {
    CommentThreads: EMPTY_ARRAY,
};
export const CommentsReducer = (state = initialState, action) => {
    switch (action.type) {
        case COMMENT_ADD: {
            const addAction = action;
            const commentThread = state.CommentThreads ?? [];
            const cellCommentIndex = commentThread.findIndex((cellComments) => {
                return AnnotationsService.isSameAddress(cellComments, addAction.cellAddress);
            });
            let comments = [...commentThread];
            if (cellCommentIndex === -1) {
                // new comments
                comments.push({
                    ...ObjectFactory.CreateEmptyCommentThread(addAction.cellAddress),
                    Comments: [addAction.comment],
                });
            }
            else {
                const existing = {
                    ...commentThread[cellCommentIndex],
                    Comments: [...commentThread[cellCommentIndex].Comments, addAction.comment],
                };
                comments[cellCommentIndex] = existing;
            }
            return { ...state, CommentThreads: comments };
        }
        case COMMENT_THREAD_ADD: {
            return {
                ...state,
                CommentThreads: [
                    ...(state.CommentThreads ?? []),
                    action.commentThread,
                ],
            };
        }
        case COMMENT_THREAD_DELETE: {
            const deleteAction = action;
            return {
                ...state,
                CommentThreads: (state.CommentThreads ?? []).filter((cellComments) => !AnnotationsService.isSameAddress(cellComments, deleteAction.cellAddress)),
            };
        }
        case COMMENT_EDIT: {
            const editAction = action;
            let edited = false;
            const adaptableCellComments = (state.CommentThreads ?? []).map((cellComments) => {
                if (AnnotationsService.isSameAddress(cellComments, editAction.cellAddress)) {
                    // found the place
                    edited = true;
                    return {
                        ...cellComments,
                        Comments: cellComments.Comments.map((comment) => {
                            if (comment.Uuid === editAction.comment.Uuid) {
                                return editAction.comment;
                            }
                            return comment;
                        }),
                    };
                }
            });
            return {
                ...state,
                CommentThreads: adaptableCellComments,
            };
        }
        case COMMENT_DELETE: {
            const deleteAction = action;
            const adaptableCellComments = (state.CommentThreads ?? [])
                .map((cellComments) => {
                if (AnnotationsService.isSameAddress(cellComments, deleteAction.cellAddress)) {
                    // found the place
                    const newComments = cellComments.Comments.filter((comment) => comment.Uuid !== deleteAction.commentUuid);
                    if (newComments.length === 0) {
                        return null;
                    }
                    const newCellComments = {
                        ...cellComments,
                        Comments: newComments,
                    };
                    return newCellComments;
                }
                return cellComments;
            })
                .filter((cellComments) => cellComments !== null);
            return {
                ...state,
                CommentThreads: adaptableCellComments,
            };
        }
        case COMMENTS_THREADS_LOAD: {
            return {
                ...state,
                CommentThreads: action.commentThreads,
            };
        }
        default:
            return state;
    }
};
