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.ExoPlayer
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import androidx.compose.runtime.mutableStateOf


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 = _favorites


    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 = _favorites.value.toMutableList().apply { add(song) }
        saveFavorites() // Don’t forget to save the updated list
    }

    fun removeFavoriteSong(song: Song) {
        _favorites = _favorites.value.toMutableList().apply { remove(song) }
        saveFavorites() // Don’t forget to save the updated list
    }

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

},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.material.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import com.example.musicapp.ViewModel.PlayerViewModel
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import com.example.musicapp.ViewModel.PlayerViewModelFactory

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

    Scaffold(
        topBar = { TopBar(title = "Favorites") },
        content = { padding ->
            Column(modifier = Modifier.padding(padding)) {
                LazyColumn {
                    items(favorites) { song ->
                        AlbumDetailItem(song, navController, playerViewModel)
                    }
                }
            }
        }
    )
},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.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
import java.lang.Math.log

// Remove this line as it seems like it’s trying to call an unavailable method
//suspend fun getAlbumDetails(albumId: Int): AlbumDetails {
//    …
//}

@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 {
                        items(details.songs) { song ->
                            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)
            )
        }
    }
},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
            }
            }
        )
    }
} -> these are some of my classes separated with "," . Errors -><html>Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:<br/>public fun &lt;T&gt; StateFlow&lt;TypeVariable(T)&gt;.collectAsState(context: CoroutineContext = ...): State&lt;TypeVariable(T)&gt; defined in androidx.compose.runtime:21,Type mismatch: inferred type is Int but Song was expected:29,Val cannot be reassigned:84,Type mismatch: inferred type is MutableList<Song> but MutableState<List<Song>> was expected:84,Type mismatch: inferred type is MutableList<Song> but MutableState<List<Song>> was expected:84,Val cannot be reassigned:89,Type mismatch: inferred type is MutableList<Song> but MutableState<List<Song>> was expected:89,Type mismatch: inferred type is MutableList<Song> but MutableState<List<Song>> was expected:89,'create' overrides nothing:8. Fix errors