# -*- coding: utf-8 -*-
"""
Dialog to list ArrayStorage raster time series and add them as a layer.
"""

import os

from qgis.PyQt import uic, QtWidgets
from qgis.PyQt.QtWidgets import QDialogButtonBox, QMessageBox
from qgis.core import QgsProcessingException, QgsProject

from .arraystorage_core import (
    build_timeseries_layer,
    list_raster_timeseries,
    make_session,
)
from .arraystorage_settings import ArrayStorageSettingsStore
from qgis.core import QgsApplication, QgsAuthMethodConfig

FORM_CLASS_ARRAYSTORE_LIST, _ = uic.loadUiType(
    os.path.join(os.path.dirname(__file__), "arraystorage_dialog_list_timeseries.ui")
)


class ArrayStorageDialogListTimeseries(QtWidgets.QDialog, FORM_CLASS_ARRAYSTORE_LIST):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        try:
            self.buttonBox.accepted.disconnect()
        except Exception:
            pass
        self.buttonBox.accepted.connect(self._on_load_clicked)
        self.buttonBox.rejected.connect(self.reject)

        ok_btn = self.buttonBox.button(QDialogButtonBox.Ok)
        if ok_btn is not None:
            ok_btn.setText(self.tr("Fetch and add layer"))

        self.lineBaseUrl.setText("http://localhost:8013")
        self.comboConfig.currentIndexChanged.connect(self._apply_selected_config)
        self._reload_configs()

    def _show_error(self, title: str, msg: str) -> None:
        QMessageBox.critical(self, title, msg)

    def _on_load_clicked(self) -> None:
        if self.fetch_and_add_layer():
            self.accept()

    def _resolve_credentials_from_authcfg(
        self, authcfg: str | None
    ) -> tuple[str | None, str | None]:
        if not authcfg:
            return None, None
        try:
            cfg = QgsAuthMethodConfig()
            if QgsApplication.authManager().loadAuthenticationConfig(
                authcfg, cfg, True
            ):
                return cfg.config("username") or None, cfg.config("password") or None
        except Exception:
            pass
        return None, None

    def _reload_configs(self) -> None:
        store = ArrayStorageSettingsStore()
        configs = store.list()
        self.comboConfig.blockSignals(True)
        self.comboConfig.clear()
        for cfg in configs:
            label = f"{cfg.name} ({cfg.base_url})"
            self.comboConfig.addItem(label, cfg)
        self.comboConfig.blockSignals(False)
        if self.comboConfig.count() > 0:
            self.comboConfig.setCurrentIndex(0)
            self._apply_selected_config()

    def _apply_selected_config(self) -> None:
        idx = self.comboConfig.currentIndex()
        cfg = self.comboConfig.itemData(idx)
        if not cfg:
            return
        self.lineBaseUrl.setText(str(cfg.base_url or "").strip())
        user_from_auth, pass_from_auth = self._resolve_credentials_from_authcfg(
            getattr(cfg, "authcfg", None)
        )
        if user_from_auth:
            self.lineUser.setText(user_from_auth)
        if pass_from_auth:
            self.linePass.setText(pass_from_auth)

    def fetch_and_add_layer(self) -> bool:
        base_url = self.lineBaseUrl.text().strip()
        as_user = self.lineUser.text().strip() or None
        as_pass = self.linePass.text().strip() or None
        add_geom = self.chkAddGeometry.isChecked()

        if not base_url:
            self._show_error(
                self.tr("Missing Base URL"), self.tr("Base URL is required.")
            )
            return False

        try:
            session = make_session(as_user, as_pass)
            items = list_raster_timeseries(base_url, session, store_id=None)
            layer = build_timeseries_layer(items, add_geometry=add_geom)
            if not layer.isValid():
                raise QgsProcessingException("Generated layer is not valid.")

            QgsProject.instance().addMapLayer(layer)
            QMessageBox.information(
                self,
                self.tr("Layer added"),
                self.tr(
                    f"Added {layer.featureCount()} raster time series "
                    "from ArrayStorage to the project."
                ),
            )
            return True
        except QgsProcessingException as e:
            self._show_error(self.tr("Listing failed"), str(e))
            return False
        except Exception as e:
            self._show_error(
                self.tr("Listing failed"), self.tr(f"Unexpected error:\n{e}")
            )
            return False
