# Copyright (c) 2025, UChicago Argonne, LLC
# BSD OPEN SOURCE LICENSE. Full license can be found in LICENSE
# Copyright (c) 2025, UChicago Argonne, LLC
# BSD OPEN SOURCE LICENSE. Full license can be found in LICENSE
"""
This code was extracted from https://github.com/leixingyu/jsonEditor
The original code was licensed under the MIT license at the time of its copy (18/Aug/2023)
"""

import ast

from qgis.PyQt import QtCore, QtWidgets

from .qjsonnode import QJsonNode


class QJsonView(QtWidgets.QTreeView):
    dragStartPosition = None

    def __init__(self):
        """
        Initialization
        """
        super(QJsonView, self).__init__()

        self._clipBroad = ""

        # set flags
        self.setSortingEnabled(True)
        self.setDragEnabled(True)
        self.setAcceptDrops(True)
        self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
        self.setUniformRowHeights(True)

        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.openContextMenu)

    def setModel(self, model):
        """
        Extend: set the current model and sort it

        :param model: QSortFilterProxyModel. model
        """
        super(QJsonView, self).setModel(model)
        self.model().sort(0, QtCore.Qt.AscendingOrder)

    def openContextMenu(self):
        """
        Custom: create a right-click context menu
        """
        return

    # helper methods

    def getSelectedIndices(self):
        """
        Custom: get source model indices of the selected item(s)

        :return: list of QModelIndex. selected indices
        """
        indices = self.selectionModel().selectedRows()
        return [self.model().mapToSource(index) for index in indices]

    def asDict(self, indices):
        """
        Custom: serialize specified model indices to dictionary

        :param indices: list of QModelIndex. root indices
        :return: dict. output dictionary
        """
        output = {}
        if not indices:
            output = self.model().sourceModel().asDict()
        else:
            for index in indices:
                output.update(self.model().sourceModel().asDict(index))
        return output

    # overwrite drag and drop

    def remove(self, indices):
        """
        Custom: remove node(s) of specified indices

        :param indices: QModelIndex. specified indices
        """
        for index in indices:
            currentNode = index.internalPointer()
            position = currentNode.row()

            # let the model know we are removing
            self.model().sourceModel().removeChild(position, index.parent())

    def add(self, text=None, index=QtCore.QModelIndex()):  # noqa: B008
        """
        Custom: add node(s) under the specified index

        :param text: str. input text for de-serialization
        :param index: QModelIndex. parent index
        """
        # populate items with a temp root
        root = QJsonNode.load(ast.literal_eval(text))

        self.model().sourceModel().addChildren(root.children, index)
        self.model().sort(0, QtCore.Qt.AscendingOrder)

    def clear(self):
        """
        Custom: clear the entire view
        """
        self.model().sourceModel().clear()

    def copy(self):
        """
        Custom: copy the selected indices by store the serialized value
        """
        selected = self.asDict(self.getSelectedIndices())
        self._clipBroad = str(selected)
