/* eslint-disable no-console */
import { ApproxStructure, Assertions, Keys, UiFinder } from '@ephox/agar';
import { describe, it } from '@ephox/bedrock-client';
import { Cell, Fun } from '@ephox/katamari';
import { PlatformDetection } from '@ephox/sand';
import { SugarBody } from '@ephox/sugar';
import { TinyDom, TinyHooks, TinyUiActions } from '@ephox/wrap-mcagar';
import { assert } from 'chai';

import type Editor from 'tinymce/core/api/Editor';

describe('browser.tinymce.themes.silver.editor.SilverEditorTest', () => {
  const os = PlatformDetection.detect().os;
  const store = Cell<string[]>([ ]);
  const hook = TinyHooks.bddSetup<Editor>({
    toolbar: 'custom1 customtoggle1 dropdown1-with-text dropdown1-with-icon splitbutton1-with-text splitbutton2-with-icon',
    menubar: 'menutest',
    menu: {
      menutest: { title: 'test', items: 'x1' }
    },
    base_url: '/project/tinymce/js/tinymce',
    setup: (ed: Editor) => {
      ed.ui.registry.addButton('custom1', {
        type: 'button',
        icon: 'cut',
        onAction: () => {
          store.set(store.get().concat([ 'button1' ]));
        }
      });

      ed.ui.registry.addToggleButton('customtoggle1', {
        type: 'togglebutton',
        text: 'ToggleMe',
        onSetup: (toggleButtonApi) => {
          const f = () => {
            toggleButtonApi.setActive(!toggleButtonApi.isActive());
          };
          ed.on('customtoggle1-toggle', f);
          return () => ed.off('customtoggle1-toggle', f);
        },
        onAction: () => {
          store.set(store.get().concat([ 'button1' ]));
        }
      });

      ed.ui.registry.addMenuButton('dropdown1-with-text', {
        text: 'dropdown1',
        fetch: (callback) => callback([
          {
            type: 'menuitem',
            text: 'Fetch1',
            onAction: () => {
              console.log('fetching item1');
            }
          }
        ])
      });

      ed.ui.registry.addMenuButton('dropdown1-with-icon', {
        icon: 'bold',
        fetch: (callback) => callback([
          {
            type: 'menuitem',
            text: 'Fetch1',
            onAction: () => {
              console.log('fetching item1');
            }
          }
        ])
      });

      ed.ui.registry.addSplitButton('splitbutton1-with-text', {
        text: 'Delta',
        onItemAction: Fun.noop,
        fetch: (callback) => {
          callback([
            {
              type: 'choiceitem',
              text: 'Split1',
              value: 'split1'
            },
            {
              type: 'choiceitem',
              text: 'Split2',
              value: 'split2'
            }
          ]);
        },
        onSetup: (splitButtonApi) => {
          const f = () => {
            splitButtonApi.setActive(!splitButtonApi.isActive());
          };
          ed.on('splitbutton1-toggle', f);
          return () => ed.off('splitbutton1-toggle', f);
        },
        onAction: () => {
          console.log('triggering action instead');
        }
      });

      ed.ui.registry.addSplitButton('splitbutton2-with-icon', {
        icon: 'underline',
        onItemAction: Fun.noop,
        fetch: (callback) => {
          callback([
            {
              type: 'choiceitem',
              text: '2-Split1',
              value: '2-split1'
            },
            {
              type: 'choiceitem',
              text: '2-Split2',
              value: '2-split2'
            }
          ]);
        },
        onAction: () => {
          console.log('triggering action instead');
        }
      });

      ed.ui.registry.addMenuItem('x1', {
        icon: 'italic',
        text: 'Text with icon',
        shortcut: 'Meta+M',
        onAction: () => {
          console.log('Just Text click');
        }
      });
    }
  }, []);

  it('Check basic structure and actions', () => {
    const editor = hook.editor();
    Assertions.assertStructure(
      'Container structure',
      ApproxStructure.build((s, str, arr) => s.element('div', {
        classes: [ arr.has('tox-tinymce') ],
        children: [
          s.element('div', {
            classes: [ arr.has('tox-editor-container') ],
            children: [
              s.element('div', {
                classes: [ arr.has('tox-editor-header') ],
                children: [
                  s.element('div', {
                    classes: [ arr.has('tox-promotion') ]
                  }),
                  s.element('div', {
                    classes: [ arr.has('tox-menubar') ],
                    attrs: { role: str.is('menubar') },
                    children: [
                      // Dropdown via text
                      s.element('button', {
                        classes: [ arr.has('tox-mbtn'), arr.has('tox-mbtn--select') ],
                        children: [
                          s.element('span', {
                            classes: [ arr.has('tox-mbtn__select-label') ],
                            html: str.is('test')
                          }),
                          s.element('div', {
                            classes: [ arr.has('tox-mbtn__select-chevron') ],
                            children: [
                              s.element('svg', {})
                            ]
                          })
                        ]
                      })
                    ]
                  }),

                  s.element('div', {
                    classes: [ arr.has('tox-toolbar-overlord') ],
                    attrs: { role: str.is('group') },
                    children: [
                      s.element('div', {
                        classes: [ arr.has('tox-toolbar__primary') ],
                        attrs: { role: str.is('group') },
                        children: [
                          s.element('div', {
                            classes: [ arr.has('tox-toolbar__group') ],
                            children: [
                              // Basic button
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn') ]
                              }),

                              // Toggle button
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn'), arr.not('tox-btn--enabled') ]
                              }),

                              // Dropdown via text
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn'), arr.has('tox-tbtn--select') ],
                                children: [
                                  s.element('span', {
                                    classes: [ arr.has('tox-tbtn__select-label') ],
                                    html: str.is('dropdown1')
                                  }),
                                  s.element('div', {
                                    classes: [ arr.has('tox-tbtn__select-chevron') ],
                                    children: [
                                      s.element('svg', {})
                                    ]
                                  })
                                ]
                              }),

                              // Dropdown via icon
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn'), arr.has('tox-tbtn--select') ],
                                children: [
                                  s.element('span', {
                                    // NOTE: Not sure what this should be?
                                    classes: [],
                                    children: [
                                      s.element('svg', {})
                                    ]
                                  }),
                                  s.element('div', {
                                    classes: [ arr.has('tox-tbtn__select-chevron') ],
                                    children: [
                                      s.element('svg', {})
                                    ]
                                  })
                                ]
                              }),

                              // Splitbutton with text
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn') ],
                                children: [
                                  s.element('span', {
                                    classes: [ arr.has('tox-tbtn__select-label') ],
                                    html: str.is('Delta')
                                  })
                                ]
                              }),

                              // Splitbutton chevron with text
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn'), arr.has('tox-split-button__chevron') ],
                                children: [
                                  s.element('svg', {})
                                ]
                              }),

                              // Splitbutton with icon
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn') ],
                                children: [
                                  s.element('span', {
                                    children: [
                                      s.element('svg', {})
                                    ]
                                  })
                                ]
                              }),

                              // Splitbutton chevron with icon
                              s.element('button', {
                                classes: [ arr.has('tox-tbtn'), arr.has('tox-split-button__chevron') ],
                                children: [
                                  s.element('svg', {})
                                ]
                              })
                            ]
                          })
                        ]
                      })
                    ]
                  }),
                  s.element('div', {
                    classes: [ arr.has('tox-anchorbar') ]
                  })
                ]
              }),
              s.element('div', {
                classes: [ arr.has('tox-sidebar-wrap') ],
                children: [
                  s.element('div', {
                    classes: [ arr.has('tox-edit-area') ],
                    children: [
                      s.element('iframe', {})
                    ]
                  }),
                  s.element('div', {
                    classes: [ arr.has('tox-sidebar') ]
                  })
                ]
              }),
              s.element('div', {
                classes: [ arr.has('tox-bottom-anchorbar') ]
              })
            ]
          }),
          s.element('div', {
            classes: [ arr.has('tox-view-wrap') ]
          }),
          s.element('div', {
            classes: [ arr.has('tox-statusbar') ]
          }),
          s.element('div', {
            classes: [ arr.has('tox-throbber') ]
          })
        ]
      })),
      TinyDom.container(editor)
    );

    TinyUiActions.clickOnToolbar(editor, 'button');
    assert.deepEqual(store.get(), [ 'button1' ], 'Button should have been triggered');
  });

  it('TBA: Menu appearing from menubar should have svg icons', async () => {
    const editor = hook.editor();
    TinyUiActions.clickOnMenu(editor, 'button[role="menuitem"]:contains("test")');
    await UiFinder.pWaitForVisible('Waiting for menu to appear', SugarBody.body(), '[role="menu"]');
    const activeItem = UiFinder.findIn(SugarBody.body(), '[role="menu"] .tox-collection__item--active').getOrDie();
    Assertions.assertStructure(
      'Checking item has svg icon and text',
      ApproxStructure.build((s, str, arr) => s.element('div', {
        classes: [ arr.has('tox-collection__item') ],
        children: [
          s.element('div', {
            classes: [ arr.has('tox-collection__item-icon') ],
            children: [
              s.element('svg', {})
            ]
          }),
          s.element('div', {
            classes: [ arr.has('tox-collection__item-label') ],
            html: str.is('Text with icon')
          }),
          s.element('div', {
            classes: [ arr.has('tox-collection__item-accessory') ],
            html: str.is(os.isMacOS() || os.isiOS() ? '\u2318' + 'M' : 'Ctrl' + '+M')
          })
        ]
      })),
      activeItem
    );
    TinyUiActions.keyup(editor, Keys.escape());
    UiFinder.notExists(SugarBody.body(), '[role="menu"]');
  });

  it('TBA: Clicking on a toggle button should not toggle. It is up to the setActive api to do that', () => {
    const editor = hook.editor();
    const button = TinyUiActions.clickOnToolbar(editor, '.tox-tbtn:contains("ToggleMe")');
    Assertions.assertStructure('ToggleMe button should not be pressed',
      ApproxStructure.build((s, str, arr) => s.element('button', {
        attrs: {
          'aria-pressed': str.is('false')
        },
        classes: [ arr.not('tox-tbtn--enabled') ]
      })),
      button
    );
  });

  it('TBA: Using the api should toggle a toggle button', () => {
    const editor = hook.editor();
    editor.dispatch('customtoggle1-toggle');
    const button = UiFinder.findIn(TinyDom.container(editor), '.tox-tbtn:contains("ToggleMe")').getOrDie();
    Assertions.assertStructure('ToggleMe button should be pressed',
      ApproxStructure.build((s, str, arr) => s.element('button', {
        attrs: {
          'aria-pressed': str.is('true')
        },
        classes: [ arr.has('tox-tbtn--enabled') ]
      })),
      button
    );
  });

  it('TBA: Clicking on a split button primary part should not toggle. It is up to the setActive api to do that', () => {
    const editor = hook.editor();
    TinyUiActions.clickOnToolbar(editor, 'button.tox-tbtn:contains("Delta")');
    const button = UiFinder.findIn(TinyDom.container(editor), 'button.tox-tbtn:contains("Delta")').getOrDie();
    Assertions.assertStructure('Delta button should not be pressed',
      ApproxStructure.build((s, str, arr) => s.element('button', {
        classes: [ arr.not('tox-tbtn--enabled') ]
      })),
      button
    );
  });

  it('TBA: Using the api should toggle a split button', () => {
    const editor = hook.editor();
    editor.dispatch('splitbutton1-toggle');
    const button = UiFinder.findIn(TinyDom.container(editor), 'button.tox-tbtn:contains("Delta")').getOrDie();
    Assertions.assertStructure('Delta button should be pressed',
      ApproxStructure.build((s, str, arr) => s.element('button', {
        classes: [ arr.has('tox-tbtn--enabled') ]
      })),
      button
    );
  });
});
