When i open another song. the other one used to stop playing. But right now it is not working correct. When i run a song. and if i try to run another one both songs keeps running. Fix it please -> these are my classes ->package com.example.musicapp.ViewModel

import android.content.Context
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import com.example.musicapp.Data.Song
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.gson.Gson
import com.example.musicapp.Data.Repository.DeezerRepository
import com.google.android.exoplayer2.MediaItem
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow


class PlayerViewModel(private val context: Context) : ViewModel() {
    var currentPlayer = mutableStateOf<SimpleExoPlayer?>(null)
    var currentSong = mutableStateOf<Song?>(null)
    var isPlaying = mutableStateOf(false)

    private val sharedPreferences = context.getSharedPreferences("music_app", Context.MODE_PRIVATE)
    private val gson = Gson()
    private val _favorites = MutableStateFlow<List<Song>>(emptyList())
    val favorites: StateFlow<List<Song>> = _favorites.asStateFlow()


    fun createExoPlayer(context: Context): SimpleExoPlayer {
        return SimpleExoPlayer.Builder(context).build()
    }

    fun playSong(context: Context, song: Song) {
        currentPlayer.value?.let {
            if (currentSong.value?.id == song.id) {
                if (isPlaying.value) {
                    pauseSong()
                } else {
                    resumeSong()
                }
                return
            } else {
                it.pause()
                it.release()
            }
        }

        currentSong.value = song
        val player = createExoPlayer(context)
        player.setMediaItem(MediaItem.fromUri(song.preview))
        player.prepare()
        player.play()
        isPlaying.value = true
        currentPlayer.value = player
    }

    fun pauseSong() {
        currentPlayer.value?.pause()
        isPlaying.value = false
    }

    fun resumeSong() {
        currentPlayer.value?.play()
        isPlaying.value = true
    }

    override fun onCleared() {
        super.onCleared()
        currentPlayer.value?.release()
    }

    // Add a private function to load favorites from SharedPreferences
    private fun loadFavorites(): List<Song> {
        val json = sharedPreferences.getString("favorites", "[]") ?: "[]"
        val type = object : TypeToken<List<Song>>() {}.type
        return gson.fromJson(json, type)
    }

    // Save favorites to SharedPreferences
    private fun saveFavorites() {
        sharedPreferences.edit().putString("favorites", gson.toJson(_favorites.value)).apply()
    }
    // Update addFavoriteSong and removeFavoriteSong functions to save favorites after making changes
    fun addFavoriteSong(song: Song) {
        _favorites.value = _favorites.value.toMutableList().apply { add(song) }
        saveFavorites()
    }

    fun removeFavoriteSong(song: Song) {
        _favorites.value = _favorites.value.toMutableList().apply { remove(song) }
        saveFavorites()
    }

    fun isFavorite(song: Song): Boolean {
        return _favorites.value.contains(song)
    }

}
,package com.example.musicapp.ViewModel

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.musicapp.Data.AlbumDetails
import com.example.musicapp.Data.Repository.DeezerRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class AlbumDetailsViewModel : ViewModel() {
    private val deezerRepository = DeezerRepository()

    private val _albumDetails = MutableStateFlow<AlbumDetails?>(null)
    val albumDetails: StateFlow<AlbumDetails?>
        get() = _albumDetails

    fun fetchAlbumDetails(albumId: Int) {
        viewModelScope.launch {
            try {
                val albumDetails = deezerRepository.getAlbumDetails(albumId)
                _albumDetails.value = albumDetails
            } catch (e: Exception) {
                Log.e("AlbumDetailsViewModel", "Failed to fetch album details: " + e.message)
            }
        }
    }
},package com.example.musicapp.Interface

import TopBar
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.musicapp.Data.Song
import com.example.musicapp.ViewModel.AlbumDetailsViewModel
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavController
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import coil.compose.rememberImagePainter
import coil.transform.CircleCropTransformation
import com.example.musicapp.ViewModel.PlayerViewModel
import com.example.musicapp.R
import androidx.compose.runtime.remember
import androidx.lifecycle.ViewModelStoreOwner
import com.example.musicapp.Data.Repository.DeezerRepository


@Composable
fun AlbumDetailScreen(albumId: Int,
                      navController: NavController,
                      localViewModelStoreOwner: ViewModelStoreOwner
) {
    val context = LocalContext.current
    val deezerRepository = remember { DeezerRepository() } // memoize to avoid re-initialization
    val albumDetailsViewModel: AlbumDetailsViewModel = viewModel()

    // Replace the previous playerViewModel assignment with this code:
    val playerViewModel = remember { PlayerViewModel(context) }
    albumDetailsViewModel.fetchAlbumDetails(albumId)
    val albumDetails = albumDetailsViewModel.albumDetails.collectAsState().value
    albumDetails?.let { details ->
        Scaffold(
            topBar = {
                TopBar(title = details.title)
            },
            content = { padding ->
                Column(
                    modifier = Modifier.padding(padding)
                ) {
                    LazyColumn {
                        itemsIndexed(details.songs) { _, song -> // Use itemsIndexed instead of items
                            AlbumDetailItem(song, navController, playerViewModel)
                        }
                    }
                }
            }
        )
    }
}

@Composable
fun AlbumDetailItem(song: Song, navController: NavController, playerViewModel: PlayerViewModel) {
    val context = LocalContext.current
    val playerViewModel = remember { PlayerViewModel(context) }


    Row(
        modifier = Modifier
            .padding(horizontal = 16.dp, vertical = 8.dp)
            .background(
                color = Color.Black.copy(alpha = 0.5f),
                shape = RoundedCornerShape(8.dp)
            )
            .border(
                width = 1.dp,
                color = Color.LightGray,
                shape = RoundedCornerShape(8.dp)
            )

    ) {
        val painter = rememberImagePainter(
        data = song.album.cover_medium,
        builder = {
            crossfade(true)
            transformations(CircleCropTransformation())
        }
    )

        Image(
            painter = painter,
            contentDescription = song.title,
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .size(100.dp)
                .align(Alignment.CenterVertically)
        )

        Column(
            modifier = Modifier
                .weight(1f)
                .padding(start = 16.dp)
                .align(Alignment.CenterVertically)
        ) {
            Text(
                text = song.title,
            style = MaterialTheme.typography.subtitle1,
            color = Color.White
            )
            Text(
                text = "${song.duration}",
            style = MaterialTheme.typography.caption,
            color = Color.White
            )
        }

        IconButton(
            onClick = {
                if (playerViewModel.currentSong.value?.id == song.id) {
                    if (playerViewModel.isPlaying.value) {
                        playerViewModel.pauseSong()
                    } else {
                        playerViewModel.resumeSong()
                    }
                } else {
                    playerViewModel.playSong(context, song)
                }
            },
            modifier = Modifier
                .align(Alignment.CenterVertically)
                .padding(8.dp)

        ) {
            Icon(
                painter = painterResource(id = if (playerViewModel.currentSong.value?.id == song.id && playerViewModel.isPlaying.value) R.drawable.pause else R.drawable.play_buttton),
                contentDescription = if (playerViewModel.currentSong.value?.id == song.id && playerViewModel.isPlaying.value) "Pause" else "Play",
            modifier = Modifier.size(24.dp)
            )
        }
        IconButton(
            onClick = {
                if (playerViewModel.isFavorite(song)) {
                    playerViewModel.removeFavoriteSong(song)
                } else {
                    playerViewModel.addFavoriteSong(song)
                }
            },
            modifier = Modifier
                .align(Alignment.CenterVertically)
                .padding(8.dp)
        ) {
            Icon(
                painter = painterResource(id = if (playerViewModel.isFavorite(song)) R.drawable.heart_full else R.drawable.heart_empty),
                contentDescription = if (playerViewModel.isFavorite(song)) "Favorite" else "Not Favorite",
            modifier = Modifier.size(24.dp)
            )
        }
    }
},package com.example.musicapp.Interface

import MusicCategoriesScreen
import TopBar
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import com.example.musicapp.ui.theme.MusicAppTheme
import com.example.musicapp.ViewModel.CategoriesViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MusicAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    MainScreen()
                }
            }
        }
    }
}
@Composable
fun FirstScreen(modifier: Modifier = Modifier) {
    val categoriesViewModel: CategoriesViewModel = viewModel()
    val categories by categoriesViewModel.categories.collectAsState()
    Scaffold(
        content = { padding ->
            Column(
                modifier = modifier.padding(padding)
            ) {
                // Add your UI components here
                MusicCategoriesScreen(categories = categories, topBar = { TopBar(title = "Music Categories") })
            }
        }
    )
}


@Composable
fun SecondScreen(modifier: Modifier = Modifier) {
    Scaffold(
        topBar = {
            // No top bar title
        },
        content = { padding ->
            Column(
                modifier = modifier.padding(padding)
            ) {
                Text(text = "This is the second screen")
            }
        }
    )
}


@Composable
fun MainScreen() {
    val navController = rememberNavController()
    val localViewModelStoreOwner = LocalViewModelStoreOwner.current

    Scaffold(
        bottomBar = {
            BottomNavigationBar(navController)
        },
        content = { padding ->
            NavHost(navController, startDestination = "musicCategories") {
            composable("musicCategories") {
            val categoriesViewModel: CategoriesViewModel = viewModel()
            val categories by categoriesViewModel.categories.collectAsState()

            MusicCategoriesScreen(
                categories = categories,
                onCategorySelected = { category ->
                    navController.navigate("artistsDetail/${category.id}")
                },
                topBar = { TopBar(title = "Music Categories") },
                modifier = Modifier.padding(padding)
            )
        }
            composable("artistsDetail/{categoryId}") { backStackEntry ->
            val categoryId = backStackEntry.arguments?.getString("categoryId")?.toIntOrNull()
            if (categoryId != null) {
                ArtistsScreen(navController, categoryId)
            }
        }
            composable("artistDetail/{artistId}") { backStackEntry ->
            val artistId = backStackEntry.arguments?.getString("artistId")?.toIntOrNull()
            if (artistId != null) {
                ArtistDetailScreen(artistId, navController)
            }
        }
            composable("albumDetail/{albumId}") { backStackEntry ->
            val albumId = backStackEntry.arguments?.getString("albumId")?.toIntOrNull()
            if (albumId != null) {
                if (localViewModelStoreOwner != null) {
                    AlbumDetailScreen(albumId, navController, localViewModelStoreOwner)
                }
            }
        }
            composable("favorites") {
            FavoritesScreen(navController)
        }
        }
        }
    )
}

@Composable
fun BottomNavigationBar(navController: NavController) {
    val navBackStackEntry = navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry.value?.destination?.route

    BottomNavigation {
        BottomNavigationItem(
            icon = { Icon(Icons.Filled.Home, contentDescription = null) },
            selected = currentRoute == "musicCategories",
            onClick = {
                navController.navigate("musicCategories") {
                // Corrected line:
                popUpTo("musicCategories") {
                inclusive = true
            }
                launchSingleTop = true
            }
            }
        )
        BottomNavigationItem(
            icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
            selected = currentRoute == "favorites",
            onClick = {
                navController.navigate("favorites") {
                // Corrected line:
                popUpTo("musicCategories") {
                inclusive = true
            }
                launchSingleTop = true
            }
            }
        )
    }
}