from abc import abstractmethod
from typing import Any, Callable, Optional

try:
	from typing import override
except ImportError:
	from typing_extensions import override  # noqa: F401

from PySide6.QtWidgets import (
	QWidget,
)

DEFAULT_VALUE_TEXT = "Veuillez selectionner une valeur."


# class InputWidget(QWidget):
class InputInterface:
	"""
	InputInterface is an abstract base class that defines the interface for input widgets in the application.
	Attributes:
		_value_changed_data_callback (Optional[Callable[[], Any]]): Callback function to be called when the data value changes.
		_value_changed_ui_callback (Optional[Callable[[], Any]]): Callback function to be called when the UI value changes.
	"""

	_value_changed_data_callback: Optional[Callable[[], Any]] = None
	_value_changed_ui_callback: Optional[Callable[[], Any]] = None

	# def __init__(self):
	# 	self._value_changed_data_callback = None
	# 	self._value_changed_ui_callback = None

	@abstractmethod
	def get_is_filled(self) -> bool:
		"""
		Checks whether all required input fields in the interface have been filled.

		Returns:
			bool: True if all required fields are filled, False otherwise.
		"""
		pass

	@abstractmethod
	def get_widget(self) -> QWidget:
		"""
		Returns the associated QWidget for this interface.

		Raises:
			NotImplementedError: This method should be implemented by subclasses to return a QWidget instance.
		"""
		raise NotImplementedError()

	def set_value_changed_data_callback(self, callback: Callable[[], Any]) -> None:
		"""
		Sets the callback function to be invoked when the value changes.

		Args:
			callback (Callable[[], Any]): A function to be called when the value changes.
				The callback should take no arguments and can return any value.

		Returns:
			None
		"""
		self._value_changed_data_callback = callback

	def set_value_changed_ui_callback(self, callback: Callable[[], Any]) -> None:
		"""
		Sets the callback function to be invoked when the UI value changes.

		Args:
			callback (Callable[[], Any]): A function to be called when the value changes in the UI.
		"""
		self._value_changed_ui_callback = callback

	def _handle_value_changed(self):
		"""
		Handles the event when the value changes.

		This method checks if UI and data callbacks are set, and if so, calls them.
		It is typically used to propagate value change events to both the user interface
		and the underlying data model.

		Callbacks:
			- self._value_changed_ui_callback: Called to update the UI when the value changes.
			- self._value_changed_data_callback: Called to update the data model when the value changes.
		"""
		if self._value_changed_ui_callback:
			self._value_changed_ui_callback()
		if self._value_changed_data_callback:
			self._value_changed_data_callback()

	@abstractmethod
	def set_resize_callback(self, callback: Callable[[int], Any]) -> None:
		"""
		Sets a callback function to be invoked when a resize event occurs.

		Args:
			callback (Callable[[int], Any]): A function that takes an integer (typically representing the new size)
				and performs an action when a resize event is triggered.

		Returns:
			None
		"""
		pass
