import React from 'react'
import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import { LOGGED_IN } from '../src/constants/ActionTypes.js'
import { goodComment1, goodError1, goodError3, goodComment4, goodError2 } from './GoodEventLibrary';
import { badNotification1 } from './BadEventLibrary';
import DetailedEvent from '../src/components/Event/DetailedEvent.js';

beforeEach(() => {
    Enzyme.configure({ adapter: new Adapter() });
})

describe('DetailedEvent', () => {
    /* a general wrapper used several times among the tests */
    function getWrapper(event) {
        return (
            Enzyme.shallow(
                <DetailedEvent
                    event={event}
                    investigationId="testInvestigationId"
                    reloadEvents={() => null}
                    toggleMode={() => null}
                    user={{
                        type: LOGGED_IN,
                        username: 'username',
                        sessionId: 'sessionId'
                    }} />)
        )
    }

    it('displays nothing when the event type is neither annotation nor notification', () => {
        let actualEvent = badNotification1;
        let myDetailedEvent = getWrapper(actualEvent);
        expect(myDetailedEvent.get(0)).toBe(null);
    })

    it('displays the event footer', () => {
        let actualEvent = goodComment4;
        let myDetailedEvent = getWrapper(actualEvent);
        expect(myDetailedEvent.find('EventFooter').exists()).toBe(true);
    })

    describe('On annotations', () => {
        it('displays the existing title of an annotation', () => {
            let actualEvent = goodComment1;
            let myDetailedEvent = getWrapper(actualEvent);

            expect(myDetailedEvent.find("AnnotationContent").dive().find('FormControl').prop("value")).toEqual('event title 1');
        })

        it('displays the last version of the title of an annotation', () => {
            let actualEvent = goodComment4;
            let myDetailedEvent = getWrapper(actualEvent);
            let expectedTitle = 'this is the title second version';

            expect(myDetailedEvent.find("AnnotationContent").dive().find('FormControl').prop("value")).toEqual(expectedTitle);
        })

        it('displays the editor in edition mode showing the current last comment for annotation', () => {
            let actualEvent = goodComment4;
            let myDetailedEvent = getWrapper(actualEvent);
            let expectedContent = [{
                format: 'plainText',
                text: 'new version of plain text'
            }, {
                format: 'html',
                text: '<p> new version of plain text </p>'
            }]

            expect(myDetailedEvent.find("AnnotationContent").dive().find('EventContentDisplayer').prop('isEditionMode')).toBe(true);
            expect(myDetailedEvent.find("AnnotationContent").dive().find('EventContentDisplayer').prop('content')).toEqual(expectedContent);
        })
    })


    describe('On notifications', () => {
        it("displays the original event content for a notification (which has no previous version) without using the rich text editor", () => {
            let actualEvent = goodError1;
            let myDetailedEvent = getWrapper(actualEvent);
            let expectedContent = [{
                format: 'plainText',
                text: 'beamline lost'
            }];

            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(0).prop('useRichTextEditor')).toBe(false);
            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(0).prop('content')).toEqual(expectedContent);
        })

        it("displays the original event content for a notification (which has a previous version) without using the rich text editor", () => {
            let actualEvent = goodError2;
            let myDetailedEvent = getWrapper(actualEvent);
            let expectedContent = [{
                format: "plainText",
                text: "beamline lost"
            }];

            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(0).prop('useRichTextEditor')).toBe(false);
            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(0).prop('content')).toEqual(expectedContent);
        })

        it('displays the editor without content for a notification which has never been commented', () => {
            let actualEvent = goodError1;
            let myDetailedEvent = getWrapper(actualEvent);
            let expectedContent = [{
                format: 'html',
                text: '<p> </p>'
            }];

            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(1).prop('useRichTextEditor')).toBe(true);
            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(1).prop('content')).toEqual(expectedContent);
        })

        it('displays the editor in edition mode showing the current last comment for notification', () => {
            let actualEvent = goodError3;
            let myDetailedEvent = getWrapper(actualEvent);
            let expectedContent = [{
                format: "html",
                text: "<p> this is a user comment on the error </p>"
            }];

            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(1).prop('useRichTextEditor')).toBe(true);
            expect(myDetailedEvent.find("NotificationContent").dive().find('EventContentDisplayer').at(1).prop('content')).toEqual(expectedContent);
        })
    })

    describe('canEnableSaveButton', () => {
        let myDetailedEvent = null;

        beforeEach(() => {
            let actualEvent = goodComment1;
            myDetailedEvent = getWrapper(actualEvent).instance();
        })

        it('isEditorContentValid states is false when hasText is not amongst arguments', () => {
            let actualChangesInEditor = {
                currentTextEqualsOriginal: true
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(false);
        })

        it("isEditorContentValid state is true when hasText is true and currentTextEqualsOriginal = false", () => {
            let actualChangesInEditor = {
                hasText: true,
                currentTextEqualsOriginal: false
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(true)
        })

        it('isEditorContentValid state is false when hasText is true and currentTextEqualsOriginal = true', () => {
            let actualChangesInEditor = {
                hasText: true,
                currentTextEqualsOriginal: true
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(false)
        })

        it('isEditorContentValid state is false when hasText is false and currentTextEqualsOriginal = false', () => {
            let actualChangesInEditor = {
                hasText: false,
                currentTextEqualsOriginal: false
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(false)
        })

        it('isEditorContentValid state is false when hasText is false and currentTextEqualsOriginal = true', () => {
            let actualChangesInEditor = {
                hasText: false,
                currentTextEqualsOriginal: true
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(false)
        })

        it('isEditorContentValid state is false when hasText is false and currentTextEqualsOriginal is null', () => {
            let actualChangesInEditor = {
                hasText: false,
                currentTextEqualsOriginal: null
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(false)
        })

        it('isEditorContentValid state is false when hasText is true and currentTextEqualsOriginal is null', () => {
            let actualChangesInEditor = {
                hasText: true,
                currentTextEqualsOriginal: null
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor)

            expect(myDetailedEvent.state.isEditorContentValid).toBe(false)
        })

        it('save button is enabled when event title has changed, editor not used', () => {
            //original title is 'event title 1'
            let newInputTitle = { props: { value: 'new title' } }
            myDetailedEvent.inputTitle = newInputTitle;

            myDetailedEvent.canEnableSaveButton();
            expect(myDetailedEvent.state.isSaveButtonEnabled).toBe(true);
        })

        it('save button is enabled when event title has not changed but editor content is not null and not the same as original  ', () => {
            //original title is 'event title 1'
            let actualInputTitle = { props: { value: 'event title 1' } }
            myDetailedEvent.inputTitle = actualInputTitle;
            let actualChangesInEditor = {
                hasText: true,
                currentTextEqualsOriginal: false
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor);
            expect(myDetailedEvent.state.isSaveButtonEnabled).toBe(true);
        })

        it('save button is enabled when event title has changed and editor content is not null and not the same as original  ', () => {
            //original title is 'event title 1'
            let actualInputTitle = { props: { value: 'new title' } }
            myDetailedEvent.inputTitle = actualInputTitle;
            let actualChangesInEditor = {
                hasText: true,
                currentTextEqualsOriginal: false
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor);
            expect(myDetailedEvent.state.isSaveButtonEnabled).toBe(true);
        })

        it('save button is disabled when event title has not changed and editor content is null ', () => {
            //original title is 'event title 1'
            let actualInputTitle = { props: { value: 'event title 1' } }
            myDetailedEvent.inputTitle = actualInputTitle;
            let actualChangesInEditor = {
                hasText: false,
                currentTextEqualsOriginal: false
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor);
            expect(myDetailedEvent.state.isSaveButtonEnabled).toBe(false);

            actualChangesInEditor = {
                hasText: false,
                currentTextEqualsOriginal: true
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor);
            expect(myDetailedEvent.state.isSaveButtonEnabled).toBe(false);
        })

        it('save button is disabled when event title has not changed and editor has text equal to original', () => {
            //original title is 'event title 1'
            let actualInputTitle = { props: { value: 'event title 1' } }
            myDetailedEvent.inputTitle = actualInputTitle;
            let actualChangesInEditor = {
                hasText: true,
                currentTextEqualsOriginal: true
            }
            myDetailedEvent.canEnableSaveButton(actualChangesInEditor);
            expect(myDetailedEvent.state.isSaveButtonEnabled).toBe(false);
        })

    })
})