#include "capesdk.h"
#include "twitchsdk/chat/chatapi.h"

namespace TwitchInGames {
	struct ChannelImpl {
		struct ChatChannelListener : public ttv::chat::IChatChannelListener {
			void ChatChannelStateChanged(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::ChatChannelState state, TTV_ErrorCode ec);
			void ChatChannelInfoChanged(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::ChatChannelInfo const& channelInfo);
			void ChatChannelRestrictionsChanged(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::ChatChannelRestrictions const& restrictions);
			void ChatChannelLocalUserChanged(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::ChatUserInfo const& userInfo);
			void ChatChannelMessagesReceived(ttv::UserId userId, ttv::ChannelId channelId, std::vector<ttv::chat::LiveChatMessage> const& messageList);
			void ChatChannelSubscriptionNoticeReceived(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::SubscriptionNotice const& notice);
			void ChatChannelFirstTimeChatterNoticeReceived(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::FirstTimeChatterNotice const& notice);
			void ChatChannelRaidNoticeReceived(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::RaidNotice const& notice);
			void ChatChannelUnraidNoticeReceived(ttv::UserId userId, ttv::ChannelId channelId, ttv::chat::UnraidNotice const& notice);
			void ChatChannelMessagesCleared(ttv::UserId userId, ttv::ChannelId channelId);
			void ChatChannelUserMessagesCleared(ttv::UserId userId, ttv::ChannelId channelId, ttv::UserId clearUserId);
			void ChatChannelHostTargetChanged(ttv::UserId userId, ttv::ChannelId channelId, std::string const& targetChannelName, uint32_t numViewers);
			void ChatChannelNoticeReceived(ttv::UserId userId, ttv::ChannelId channelId, std::string const& noticeId, std::map<std::string, std::string> const& params);

			ChatChannelListener(Chat::Channel& channel, Chat::Channel::ReceiveCallback receiveCallback) : channel(channel), receiveCallback(receiveCallback) {}

		private:
			Chat::Channel& channel;
			Chat::Channel::ReceiveCallback receiveCallback;
		};

		ChannelImpl(Chat::Channel& channel, ChatImpl& chatImpl, ttv::ChannelId channelId, Chat::Channel::ReceiveCallback receiveCallback);
		~ChannelImpl();
		std::future<void> Send(string_t message);

	private:
		std::shared_ptr<ChatChannelListener> chatChannelListener;
		std::shared_ptr<ttv::chat::IChatChannel> chatChannel;
	};
}
