package com.example.musicapp.ViewModel

import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider

class PlayerViewModelFactory(private val context: Context) : ViewModelProvider.NewInstanceFactory() {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(PlayerViewModel::class.java)) {
            return PlayerViewModel(context) as T
        }
        throw IllegalArgumentException("Unknown ViewModel class")
    }
},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 androidx.compose.runtime.MutableState
import com.google.android.exoplayer2.MediaItem
import com.google.gson.reflect.TypeToken

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 = mutableStateOf(emptyList<Song>())
    val favorites: MutableState<List<Song>> = _favorites // Change the type to MutableState (import required)


    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.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.lifecycle.viewmodel.compose.viewModel
import androidx.compose.material.*
import androidx.compose.ui.platform.LocalContext
import androidx.navigation.NavController
import com.example.musicapp.ViewModel.PlayerViewModel
import com.example.musicapp.ViewModel.PlayerViewModelFactory
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import com.example.musicapp.Data.Song


@Composable
fun FavoritesScreen(navController: NavController) {
    val context = LocalContext.current
    val playerViewModel = viewModel<PlayerViewModel>(factory = PlayerViewModelFactory(context))
    val favorites by playerViewModel.favorites.collectAsState()

    Scaffold(
        topBar = { TopBar(title = "Favorites") },
        content = { padding ->
            Column(modifier = Modifier.padding(padding)) {
                FavoritesList(favorites, navController, playerViewModel)
            }
        }
    )
}

@Composable
fun FavoritesList(
    favorites: List<Song>,
    navController: NavController,
    playerViewModel: PlayerViewModel
) {
    LazyColumn {
        items(favorites.size) { index ->
            val song = favorites[index]
            AlbumDetailItem(song, navController, playerViewModel)
        }
    }
}
,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 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()

    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) {
                AlbumDetailScreen(albumId, navController)
            }
        }
            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
            }
            }
        )
    }
},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.runtime.collectAsState
import androidx.compose.runtime.getValue
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.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
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.Data.AlbumDetails
import com.example.musicapp.ViewModel.PlayerViewModel
import com.example.musicapp.R



@Composable
fun AlbumDetailScreen(albumId: Int, navController: NavController) {
    val albumDetailsViewModel: AlbumDetailsViewModel = viewModel()
    val playerViewModel: PlayerViewModel = viewModel()
    albumDetailsViewModel.fetchAlbumDetails(albumId)
    val albumDetails by albumDetailsViewModel.albumDetails.collectAsState()

    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

    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())

            if (song.album.cover_medium == null) {
                this.placeholder(R.drawable.no_image)

            }
        }
    )

        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 ?: "Unknown title",
            style = MaterialTheme.typography.subtitle1,
            color = Color.White
            )
            Text(
                text = "${song.duration}" ?: "Unknown 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)
            )
        }
    }
}->these are some of my classes separated with ",". FavoritesScreen has issues because of collectAsState. I want you to change FavoriteScreen use something different but similar functionality instead of collectAsState