// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use serde::{Serialize, Deserialize};

use crate::world::{colour::Colour, player::PlayerName};
use crate::utils::{ToStr, max_len::{MaxLenString, MaxLenStr}};

#[derive(Clone, Serialize, Deserialize)]
pub enum ClientTextInput {
	Chat(ChatType, TextIoString),
	Command(TextIoString),
	Extension(Box<[u8]>),
}

#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ChatType {
	Team, // Routed to all players in the team (equivalent to global if no teams)
	Global, // Routed to all players
}

impl ToStr for ChatType {
	fn to_str(self) -> &'static str {
		match self {
			ChatType::Team => "team",
			ChatType::Global => "global",
		}
	}
}

#[derive(Clone, Serialize, Deserialize)]
pub enum ServerTextOutput {
	// Name and colour aren't redundant as players should be able to chat while spectating
	Chat(ChatType, PlayerName, Colour, TextIoString), // Chat message from a player
	Admin(TextIoString), // A human-generated message from the server admin
	Server(TextIoString), // An automatic message from the server
	Command(TextIoString), // The exact command a user entered, the server sends this to acknowledge receiving a command
	CommandResponse(TextIoString), // An automatic message from the server responding to a command
}

pub const MAX_LEN: usize = 4096; // Within the limit the message streams accept
pub type TextIoStr<'a> = MaxLenStr<'a, MAX_LEN>;
pub type TextIoString = MaxLenString<MAX_LEN>;

macro_rules! from_const {
	( $s:expr ) => {
		{
			use crate::protocol::message::text_io::TextIoStr;
			const { TextIoStr::new($s).unwrap() }.owned()
		}
	};
}

pub(crate) use from_const;
