"""Dialog for issue creation"""

# standard
from functools import partial
from pathlib import Path

# PyQGIS
from qgis.core import Qgis
from qgis.gui import QgsMessageBar
from qgis.PyQt import uic
from qgis.PyQt.QtCore import Qt, QUrl
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QWidget
from qgis.utils import OverrideCursor

# project
from oslandia.constants import UTM_CONTENT_ISSUEBROWSER
from oslandia.gitlab_api.issue import IssuesRequestManager
from oslandia.gitlab_api.project import ProjectRequestManager
from oslandia.gui.mdl_project import ProjectListModel
from oslandia.gui.mdl_project_manager import ProjectListModelManager
from oslandia.gui.proxy_model_project import ProjectProxyModel
from oslandia.gui.wdg_issue import IssueWidget
from oslandia.toolbelt import PlgLogger
from oslandia.toolbelt.network_manager import NetworkRequestsManager
from oslandia.toolbelt.preferences import PlgOptionsManager
from oslandia.toolbelt.qgis_info import (
    get_active_plugin_info,
    get_installed_qgis_info_as_markdown,
)


class CreateIssueDialog(QDialog):
    def __init__(self, group_id: int, parent: QWidget | None = None):
        super().__init__(parent)
        with OverrideCursor(Qt.CursorShape.WaitCursor):
            ui_path = Path(__file__).resolve(True).parent / "dlg_create_issue.ui"
            uic.loadUi(ui_path, self)

            self.setWindowTitle(self.tr("Create issue"))

            self.plg_settings = PlgOptionsManager.get_plg_settings()
            self.ntwk_requester_blk = NetworkRequestsManager()
            self.project_request = ProjectRequestManager()
            self.mdl_project = ProjectListModelManager.get_model_for_group(group_id)

            self.proxy_mdl = ProjectProxyModel(self)
            self.proxy_mdl.setSourceModel(self.mdl_project)
            # Can't create issue in archived project
            self.proxy_mdl.show_archived(False)
            self.proxy_mdl.setSortCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)
            self.proxy_mdl.sort(ProjectListModel.NAME_COL, Qt.SortOrder.AscendingOrder)

            self.cbx_projects.setModel(self.proxy_mdl)
            self.cbx_projects.setModelColumn(ProjectListModel.NAME_COL)

            # Set current project  with last value used if defined in settings
            if self.plg_settings.issue_creation_last_project_id:
                self.set_current_project_id(
                    self.plg_settings.issue_creation_last_project_id
                )

            self.cbx_projects.currentIndexChanged.connect(self._project_changed)

            self.btn_box.button(QDialogButtonBox.StandardButton.Ok).clicked.connect(
                self.on_btn_submit
            )
            self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setDefault(True)
            self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setText(
                self.tr("Submit")
            )
            self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
            self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setToolTip(
                self.tr("Issue not valid.\nPlease fill mandatory parameters.")
            )

            self.wdg_issue_context_auth.load_settings()
            self.wdg_issue.issueChanged.connect(self._issue_changed)
            self.wdg_issue.set_display_mode(IssueWidget.DisplayMode.CREATE)

            # Simulate project changes for project_id definition in widgets
            self._project_changed()
            # make the dialog a window to allow resizing
            self.setWindowFlags(Qt.WindowType.Window)

        # QMessageBar
        self.message_bar = QgsMessageBar()
        layout = self.findChild(QVBoxLayout, "message_layout")
        layout.insertWidget(0, self.message_bar)

    def set_current_project_id(self, project_id: int) -> None:
        """Define current selected project

        :param project_id: project id
        :type project_id: int
        """
        with OverrideCursor(Qt.CursorShape.WaitCursor):
            self.mdl_project.wait_for_data_load()

            project_row = self.mdl_project.get_project_row(project_id)
            if project_row != -1:
                index = self.proxy_mdl.mapFromSource(
                    self.mdl_project.index(project_row, self.mdl_project.NAME_COL)
                )
                self.cbx_projects.setCurrentIndex(index.row())

    def _issue_changed(self) -> None:
        """Update submit button if issue is valid for creation"""
        with OverrideCursor(Qt.CursorShape.WaitCursor):
            if not self.wdg_issue.get_issue().valid_for_creation():
                self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
                    False
                )
                self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setToolTip(
                    self.tr("Issue not valid.\nPlease fill mandatory parameters.")
                )
            else:
                self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setEnabled(True)
                self.btn_box.button(QDialogButtonBox.StandardButton.Ok).setToolTip("")

    def _project_changed(self) -> None:
        """Update issue widget for current project"""
        with OverrideCursor(Qt.CursorShape.WaitCursor):
            self.wdg_issue.set_current_project_id(self.selected_project_id())

    def selected_project_id(self) -> int:
        """Get selected project id

        :return: selected project id
        :rtype: int
        """
        project_index = self.cbx_projects.currentIndex()
        return self.mdl_project.data(
            self.proxy_mdl.mapToSource(
                self.proxy_mdl.index(project_index, ProjectListModel.ID)
            )
        )

    def on_btn_submit(self) -> None:
        """Create issue"""
        self.wdg_issue_context_auth.save_settings()

        issue = self.wdg_issue.get_issue()

        description = issue.description

        if self.wdg_issue_context_auth.is_send_qgis_info_enabled():
            description += f"\n### {self.tr('QGIS Information')}\n"
            description += get_installed_qgis_info_as_markdown()

        if self.wdg_issue_context_auth.is_send_plugin_info_enabled():
            description += f"\n### {self.tr('Installed plugins informations')}\n"
            active_plugin_info = get_active_plugin_info()
            for plugin_name, version in active_plugin_info.items():
                description += f"\n * {plugin_name} : {version}"

        issue.description = description

        issue_manager = IssuesRequestManager()
        create_issue = issue_manager.create_issue(self.selected_project_id(), issue)

        self.wdg_issue.clear_issue()

        PlgLogger().log(
            message=f'Issue <b>"{create_issue.name}</b>" successfully created.',
            log_level=Qgis.MessageLevel.Success,
            push=True,
            duration=10,
            button=True,
            button_text=self.tr("Open on Gitlab..."),
            button_connect=partial(
                self.ntwk_requester_blk.open_url,
                QUrl(create_issue.web_url),
                UTM_CONTENT_ISSUEBROWSER,
            ),
            parent_location=self,
            nb_parent_max_for_message_bar=0,
        )
