#ifndef CREDENTIALSEDITOR_HPP
#define CREDENTIALSEDITOR_HPP

#include "../filezilla/authentication/file_based_authenticator.hpp"

#include <wx/panel.h>
#include "eventex.hpp"

class wxSimplebook;
class wxChoicebook;
class wxCheckBox;
class PasswordEditor;
class wxTextCtrl;
class wxButton;
class wxComboBox;

class CredentialsEditor: public wxPanel
{
public:
	enum AuthMode {
		NoAuth,
		OwnPassword,
		SystemPassword,
	};

	using GetIdpPropertiesFunc = std::function<fz::expected<fz::authentication::identity_provider::user_properties, wxString> (const std::string &idp, const fz::authentication::identity_provider::parameters &params)>;

	using opt_identity_profile = std::optional<fz::authentication::file_based_authenticator::user_entry::identity_profile>;

	CredentialsEditor() = default;
	~CredentialsEditor() override;

	bool Create(wxWindow *parent);

	/// \brief Sets the credentials to be edited.
	/// *Doesn't* take ownership of the pointers.
	void SetCredentials(opt_identity_profile *identity, fz::authentication::credentials *credentials, bool *no_auth, const std::string &user_name);
	void SetGetIdpPropertiesFunc(GetIdpPropertiesFunc func);

	const std::optional<fz::expected<fz::authentication::identity_provider::user_properties, wxString>> &GetIdpProperties() const;

	bool TransferDataFromWindow() override;

	struct Event: wxEventEx<Event>
	{
		inline const static Tag ChangedMode;

		AuthMode GetMode() const
		{
			return mode_;
		}

	private:
		friend Tag;

		using wxEventEx::wxEventEx;

		Event(const Tag &tag, AuthMode mode)
			: wxEventEx(tag)
			, mode_(mode)
		{}

		AuthMode mode_;
	};

private:
	bool update_idp_properties(const std::string &idp, const fz::authentication::identity_provider::parameters &params);
	bool update_system_idp_properties(wxCheckBox *impersonate_check);
	bool update_local_idp_properties();
	bool update_none_idp_properties();

	bool act_on_idp_properties(wxCheckBox *impersonate_check);

	std::optional<fz::expected<fz::authentication::identity_provider::user_properties, wxString>> idp_properties_;

	wxChoicebook *creds_choices_{};
	PasswordEditor *password_editor_{};
	wxCheckBox *system_user_impersonate_{};
	opt_identity_profile *identity_{};
	fz::authentication::credentials *credentials_{};
	bool *no_auth_{};
	std::string user_name_;
	std::optional<fz::authentication::any_password> password_;
	wxString tmp_secret_;
	GetIdpPropertiesFunc get_idp_properties_func_;
};

#endif // CREDENTIALSEDITOR_HPP
