/**
* DevExtreme (ui.grid_core.context_menu.js)
* Version: 22.1.7 (build 23032-0308)
* Build date: Wed Feb 01 2023
*
* Copyright (c) 2012 - 2023 Developer Express Inc. ALL RIGHTS RESERVED
* Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
*/
import $ from '../../core/renderer';
import { getPublicElement } from '../../core/element';
import { noop } from '../../core/utils/common';
import { each } from '../../core/utils/iterator';
import modules from './ui.grid_core.modules';
import ContextMenu from '../context_menu';

const CONTEXT_MENU = 'dx-context-menu';

const viewName = {
    'columnHeadersView': 'header',
    'rowsView': 'content',
    'footerView': 'footer',
    'headerPanel': 'headerPanel'
};
const VIEW_NAMES = ['columnHeadersView', 'rowsView', 'footerView', 'headerPanel'];

const ContextMenuController = modules.ViewController.inherit({
    init: function() {
        this.createAction('onContextMenuPreparing');
    },

    getContextMenuItems: function(dxEvent) {
        if(!dxEvent) {
            return false;
        }

        const that = this;
        const $targetElement = $(dxEvent.target);
        let $element;
        let $targetRowElement;
        let $targetCellElement;
        let menuItems;

        each(VIEW_NAMES, function() {
            const view = that.getView(this);
            $element = view && view.element();

            if($element && ($element.is($targetElement) || $element.find($targetElement).length)) {
                $targetCellElement = $targetElement.closest('.dx-row > td, .dx-row > tr');
                $targetRowElement = $targetCellElement.parent();
                const rowIndex = view.getRowIndex($targetRowElement);
                const columnIndex = $targetCellElement[0] && $targetCellElement[0].cellIndex;
                const rowOptions = $targetRowElement.data('options');
                const options = {
                    event: dxEvent,
                    targetElement: getPublicElement($targetElement),
                    target: viewName[this],
                    rowIndex: rowIndex,
                    row: view._getRows()[rowIndex],
                    columnIndex: columnIndex,
                    column: rowOptions?.cells?.[columnIndex]?.column
                };

                options.items = view.getContextMenuItems && view.getContextMenuItems(options);

                that.executeAction('onContextMenuPreparing', options);
                that._contextMenuPrepared(options);
                menuItems = options.items;

                if(menuItems) {
                    return false;
                }
            }
        });

        return menuItems;
    },
    _contextMenuPrepared: noop
});

const ContextMenuView = modules.View.inherit({
    _renderCore: function() {
        const that = this;
        const $element = that.element().addClass(CONTEXT_MENU);

        this.setAria('role', 'presentation', $element);

        this._createComponent($element,
            ContextMenu, {
                onPositioning: function(actionArgs) {
                    const event = actionArgs.event;
                    const contextMenuInstance = actionArgs.component;
                    const items = that.getController('contextMenu').getContextMenuItems(event);

                    if(items) {
                        contextMenuInstance.option('items', items);
                        event.stopPropagation();
                    } else {
                        actionArgs.cancel = true;
                    }
                },
                onItemClick: function(params) {
                    params.itemData.onItemClick && params.itemData.onItemClick(params);
                },

                cssClass: that.getWidgetContainerClass(),
                target: that.component.$element()
            });
    }
});

export const contextMenuModule = {
    defaultOptions: function() {
        return {
            onContextMenuPreparing: null
        };
    },
    controllers: {
        contextMenu: ContextMenuController
    },
    views: {
        contextMenuView: ContextMenuView
    }
};
