#ifndef VISUALS_HPP
#define VISUALS_HPP

namespace cheat_interface
{
	enum TracerStyle
	{
		SOLID,
		DOTTED,
		DASHED
	};

	struct DragState 
	{
		bool is_dragging = false;
		ImVec2 drag_offset = ImVec2( 0.f, 0.f );
	};

	class c_visual
	{
	private:

		auto get_weapon_color( enums::fort_rarity rarity ) -> ImColor 
		{
			switch ( rarity ) 
			{
				case enums::fort_rarity::Common: return ImColor( 163, 170, 176 );
				case enums::fort_rarity::Uncommon: return ImColor( 69, 150, 59 );
				case enums::fort_rarity::Rare: return ImColor( 10, 159, 230 );
				case enums::fort_rarity::Epic: return ImColor( 175, 112, 198 );
				case enums::fort_rarity::Legendary: return ImColor( 229, 133, 55 );
				case enums::fort_rarity::Mythic: return ImColor( 250, 195, 65 );
				case enums::fort_rarity::Transcendent: return ImColor( 255, 255, 255 );
				case enums::fort_rarity::Unattainable: return ImColor( 255, 255, 255 );
				case enums::fort_rarity::NumRarityValues: return ImColor( 255, 255, 255 );
				case enums::fort_rarity::EFortRarity_MAX: return ImColor( 255, 255, 255 );
				default: return ImColor( 255, 255, 255 );
			}

			return ImColor( 255, 255, 255 );
		}

		auto get_weapon_tier_name( enums::fort_rarity rarity ) -> std::string
		{
			switch ( rarity )
			{
			case enums::fort_rarity::Common: return "Common";
			case enums::fort_rarity::Uncommon: return "Uncommon";
			case enums::fort_rarity::Rare: return "Rare";
			case enums::fort_rarity::Epic: return "Epic";
			case enums::fort_rarity::Legendary: return "Legendary";
			case enums::fort_rarity::Mythic: return "Mythic";
			case enums::fort_rarity::Transcendent: return "Transcendent";
			case enums::fort_rarity::Unattainable: return "Unattainable";
			case enums::fort_rarity::NumRarityValues: return "NumRarityValues";
			case enums::fort_rarity::EFortRarity_MAX: return "EFortRarity_MAX";
			default: return "None";
			}

			return "None";
		}

		auto parse_rankcolor( int32_t Tier ) -> ImColor {
			switch ( Tier ) {
			case 0:
			case 1:
			case 2:
				return ImColor( 255, 119, 0, 255 ); // Bronze
			case 3:
			case 4:
			case 5:
				return ImColor( 204, 153, 233, 255 ); // Silver
			case 6:
			case 7:
			case 8:
				return ImColor( 233, 219, 14, 255 ); // Gold
			case 9:
			case 10:
			case 11:
				return ImColor( 14, 233, 211, 255 ); // Platinum
			case 12:
			case 13:
			case 14:
				return ImColor( 93, 46, 246, 255 ); // Diamond
			case 15:
				return ImColor( 243, 111, 186, 255 ); // Elite
			case 16:
				return ImColor( 252, 87, 55, 255 ); // Champion
			case 17:
				return ImColor( 138, 189, 182, 255 ); // Unreal
			default:
				return ImColor( 212, 212, 212, 255 ); // Default color
			}
		}

		auto parse_rank( int32_t tier ) -> std::string {
			if ( tier == 0 )
				return hash_str( "Bronze 1" );
			else if ( tier == 1 )
				return hash_str( "Bronze 2" );
			else if ( tier == 2 )
				return hash_str( "Bronze 3" );
			else if ( tier == 3 )
				return hash_str( "Silver 1" );
			else if ( tier == 4 )
				return hash_str( "Silver 2" );
			else if ( tier == 5 )
				return hash_str( "Silver 3" );
			else if ( tier == 6 )
				return hash_str( "Gold 1" );
			else if ( tier == 7 )
				return hash_str( "Gold 2" );
			else if ( tier == 8 )
				return hash_str( "Gold 3" );
			else if ( tier == 9 )
				return hash_str( "Platinum 1" );
			else if ( tier == 10 )
				return hash_str( "Platinum 2" );
			else if ( tier == 11 )
				return hash_str( "Platinum 3" );
			else if ( tier == 12 )
				return hash_str( "Diamond 1" );
			else if ( tier == 13 )
				return hash_str( "Diamond 2" );
			else if ( tier == 14 )
				return hash_str( "Diamond 3" );
			else if ( tier == 15 )
				return hash_str( "Elite" );
			else if ( tier == 16 )
				return hash_str( "Champion" );
			else if ( tier == 17 )
				return hash_str( "Unreal" );
			else
				return hash_str( "Unranked" );
		}

		auto parse_platformcolor( std::string platform ) -> ImColor {

			if ( platform == hash_str( "XBL" ) || platform == hash_str( "XSX" ) ) {
				return ImColor( 34 * 0.6f + 0.4f, 255 * 0.6f + 0.4f, 0 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "PS4" ) || platform == hash_str( "PS5" ) || platform == hash_str( "PSN" ) ) {
				return ImColor( 0 * 0.6f + 0.4f, 162 * 0.6f + 0.4f, 255 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "WIN" ) ) {
				return ImColor( 0 * 0.6f + 0.4f, 105 * 0.6f + 0.4f, 217 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "SWT" ) ) {
				return ImColor( 255 * 0.6f + 0.4f, 0 * 0.6f + 0.4f, 0 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "AND" ) ) {
				return ImColor( 0 * 0.6f + 0.4f, 255 * 0.6f + 0.4f, 76 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "MAC" ) ) {
				return ImColor( 255 * 0.6f + 0.4f, 255 * 0.6f + 0.4f, 255 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "LNX" ) ) {
				return ImColor( 255 * 0.6f + 0.4f, 213 * 0.6f + 0.4f, 0 * 0.6f + 0.4f );
			}
			else if ( platform == hash_str( "IOS" ) ) {
				return ImColor( 176 * 0.6f + 0.4f, 176 * 0.6f + 0.4f, 176 * 0.6f + 0.4f );
			}

			return ImColor( 255, 255, 255 );
		}

	private:

		DragState KeybindsDragState{};
		DragState SpectatorsDragState{};

		auto handle_drag( ImVec2& draw_position, const ImVec2& top_left_rect, const ImVec2& rect_size, const bool& menu, DragState& drag_state ) -> void
		{
			math::vector2 mouse_position = g_engine->get_cursor( );
			bool left_mouse_down = ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 );

			bool is_hovered = g_engine->is_hovered( math::vector2( top_left_rect.x, top_left_rect.y ), math::vector2( rect_size.x, rect_size.y ) );

			if ( is_hovered && left_mouse_down && !drag_state.is_dragging )
			{
				drag_state.drag_offset = ImVec2( mouse_position.x - draw_position.x, mouse_position.y - draw_position.y );
				drag_state.is_dragging = true;
			}

			if ( drag_state.is_dragging )
			{
				if ( left_mouse_down && menu )
				{
					draw_position.x = mouse_position.x - drag_state.drag_offset.x;
					draw_position.y = mouse_position.y - drag_state.drag_offset.y;
				}
				else
				{
					drag_state.is_dragging = false;
				}
			}
		}

	private:

		std::unordered_map<game::a_fort_player_pawn_athena*, bool> friendly_map;
		std::unordered_map<game::a_fort_player_pawn_athena*, bool> enemy_map;

	public:
		void render( );
		void render_world( );
		void render_indicators( );
		void render_other( );
	};

} inline std::shared_ptr<cheat_interface::c_visual> g_visual = std::make_shared<cheat_interface::c_visual>( );

#endif