import { interpolate as d3_interpolate } from 'd3-interpolate';
import { select as d3_select } from 'd3-selection';

import { uiEntityEditor } from './entity_editor';
import { uiPresetList } from './preset_list';
import { uiViewOnOSM } from './view_on_osm';


export function uiInspector(context) {
    var presetList = uiPresetList(context);
    var entityEditor = uiEntityEditor(context);
    var wrap = d3_select(null),
        presetPane = d3_select(null),
        editorPane = d3_select(null);
    var _state = 'select';
    var _entityIDs;
    var _newFeature = false;


    function inspector(selection, options = {}) {
        presetList
            .entityIDs(_entityIDs)
            .autofocus(_newFeature)
            .on('choose', inspector.setPreset)
            .on('cancel', function() {
                inspector.setPreset();
            });

        entityEditor
            .state(_state)
            .entityIDs(_entityIDs)
            .on('choose', inspector.showList);

        wrap = selection.selectAll('.panewrap')
            .data([0]);

        var enter = wrap.enter()
            .append('div')
            .classed('panewrap', true);
            //.style('right', shouldDefaultToPresetList() ? '-100%' : '0%');

        enter
            .append('div')
            .classed('preset-list-pane pane', true);

        enter
            .append('div')
            .classed('entity-editor-pane pane', true);

        wrap = wrap.merge(enter);
        presetPane = wrap.selectAll('.preset-list-pane');
        editorPane = wrap.selectAll('.entity-editor-pane');

        if (!options?.redrawEntityEditor) {
            // initial rendering, or new feature selected
            if (shouldDefaultToPresetList()) {
                wrap.style('right', '-100%');
                editorPane.classed('hide', true);
                presetPane.classed('hide', false)
                    .call(presetList);
            } else {
                wrap.style('right', '0%');
                presetPane.classed('hide', true);
                editorPane.classed('hide', false)
                    .call(entityEditor);
            }
        } else {
            // refreshing entity editor (e.g. when sidebar is resized)
            if (!editorPane.classed('hide')) {
                editorPane.call(entityEditor);
            }
        }

        function shouldDefaultToPresetList() {
            // always show the inspector on hover
            if (_state !== 'select') return false;

            // can only change preset on single selection
            if (_entityIDs.length !== 1) return false;

            var entityID = _entityIDs[0];
            var entity = context.hasEntity(entityID);
            if (!entity) return false;

            // default to inspector if there are already tags
            if (entity.hasNonGeometryTags()) return false;

            // prompt to select preset if feature is new and untagged
            if (_newFeature) return true;

            // all existing features except vertices should default to inspector
            if (entity.geometry(context.graph()) !== 'vertex') return false;

            // show vertex relations if any
            if (context.graph().parentRelations(entity).length) return false;

            // show vertex issues if there are any
            if (context.validator().getEntityIssues(entityID).length) return false;

            // show turn restriction editor for junction vertices
            if (entity.type === 'node' && entity.isHighwayIntersection(context.graph())) return false;

            // otherwise show preset list for uninteresting vertices
            return true;
        }

        var footer = selection.selectAll('.footer')
            .data([0]);

        footer = footer.enter()
            .append('div')
            .attr('class', 'footer')
            .merge(footer);

        footer
            .call(uiViewOnOSM(context)
                .what(context.hasEntity(_entityIDs?.length === 1 && _entityIDs[0]))
            );
    }

    inspector.showList = function(presets) {

        presetPane.classed('hide', false);

        wrap.transition()
            .styleTween('right', function() {
                return d3_interpolate('0%', '-100%');
            })
            .on('end', function () {
                editorPane.classed('hide', true);
            });

        if (presets) {
            presetList.presets(presets);
        }

        presetPane
            .call(presetList.autofocus(true));
    };

    inspector.setPreset = function(preset) {

        // upon setting multipolygon, go to the area preset list instead of the editor
        if (preset && preset.id === 'type/multipolygon') {
            presetPane
                .call(presetList.autofocus(true));

        } else {
            editorPane.classed('hide', false);
            wrap.transition()
                .styleTween('right', function() {
                    return d3_interpolate('-100%', '0%');
                })
                .on('end', function () {
                    presetPane.classed('hide', true);
                });

            if (preset) {
                entityEditor.presets([preset]);
            }
            editorPane
                .call(entityEditor);
        }

    };

    inspector.state = function(val) {
        if (!arguments.length) return _state;
        _state = val;
        entityEditor.state(_state);

        // remove any old field help overlay that might have gotten attached to the inspector
        context.container().selectAll('.field-help-body').remove();

        return inspector;
    };


    inspector.entityIDs = function(val) {
        if (!arguments.length) return _entityIDs;
        _entityIDs = val;
        return inspector;
    };


    inspector.newFeature = function(val) {
        if (!arguments.length) return _newFeature;
        _newFeature = val;
        return inspector;
    };


    return inspector;
}
