package com.player.musicoo.innertube.requests

import com.player.musicoo.innertube.Innertube
import com.player.musicoo.innertube.models.BrowseResponse
import com.player.musicoo.innertube.models.ContinuationResponse
import com.player.musicoo.innertube.models.GridRenderer
import com.player.musicoo.innertube.models.MusicCarouselShelfRenderer
import com.player.musicoo.innertube.models.MusicShelfRenderer
import com.player.musicoo.innertube.models.SectionListRenderer
import com.player.musicoo.innertube.models.bodies.BrowseBody
import com.player.musicoo.innertube.models.bodies.ContinuationBody
import com.player.musicoo.innertube.utils.runCatchingNonCancellable
import com.player.musicoo.util.LogTag
import io.ktor.client.call.body
import io.ktor.client.request.post
import io.ktor.client.request.setBody

suspend fun Innertube.moSingerListPage(browseId: String): Result<Innertube.SingerDetailsPage>? =
    runCatchingNonCancellable {
        val response = client.post(browse) {
            setBody(BrowseBody(browseId = browseId))
        }.body<BrowseResponse>()

        val list: MutableList<Innertube.SingerDetailsListPage> = mutableListOf()

        val musicImmersiveHeaderRenderer = response.header
            ?.musicImmersiveHeaderRenderer

        val title = musicImmersiveHeaderRenderer
            ?.title
            ?.text

        val thumbnail = musicImmersiveHeaderRenderer
            ?.thumbnail
            ?.musicThumbnailRenderer
            ?.thumbnail
            ?.thumbnails
            ?.let {
                it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
            }?.url

        val description = musicImmersiveHeaderRenderer
            ?.description
            ?.text

        val sectionListRendererContents = response
            .contents
            ?.singleColumnBrowseResultsRenderer
            ?.tabs
            ?.firstOrNull()
            ?.tabRenderer
            ?.content
            ?.sectionListRenderer
            ?.contents

        if (sectionListRendererContents != null) {
            for (content: SectionListRenderer.Content in sectionListRendererContents) {
                var title = ""
                var browseId = ""
                var params = ""
                var pageType = ""
                val musicShelfRendererContents: MutableList<MusicShelfRenderer.Content> =
                    mutableListOf()
                val musicCarouselShelfContents: MutableList<MusicCarouselShelfRenderer.Content> =
                    mutableListOf()
                if (content.musicShelfRenderer != null) {
                    title = content.musicShelfRenderer
                        .title?.text ?: ""
                    if (content.musicShelfRenderer.contents != null) {
                        musicShelfRendererContents.clear()
                        musicShelfRendererContents.addAll(content.musicShelfRenderer.contents)
                    }
                    val browseEndpoint = content.musicShelfRenderer.title
                        ?.runs
                        ?.firstOrNull()
                        ?.navigationEndpoint
                        ?.browseEndpoint

                    browseId = browseEndpoint?.browseId ?: ""
                    params = browseEndpoint?.params ?: ""
                }
                if (content.musicCarouselShelfRenderer != null) {
                    title = content.musicCarouselShelfRenderer.header
                        ?.musicCarouselShelfBasicHeaderRenderer
                        ?.title
                        ?.text ?: ""

                    if (content.musicCarouselShelfRenderer.contents != null) {
                        musicCarouselShelfContents.clear()
                        musicCarouselShelfContents.addAll(content.musicCarouselShelfRenderer.contents)
                    }
                    val browseEndpoint = content.musicCarouselShelfRenderer.header
                        ?.musicCarouselShelfBasicHeaderRenderer
                        ?.title
                        ?.runs
                        ?.firstOrNull()
                        ?.navigationEndpoint
                        ?.browseEndpoint

                    browseId = browseEndpoint?.browseId ?: ""
                    params = browseEndpoint?.params ?: ""
                    pageType = browseEndpoint?.type ?: ""
                }

                val singerDetailsContent = Innertube.SingerDetailsListPage.SingerDetailsContent(
                    musicShelfRendererContents,
                    musicCarouselShelfContents
                )

                val singerDetails =
                    Innertube.SingerDetailsListPage(
                        title = title,
                        contents = singerDetailsContent,
                        browseId = browseId,
                        params = params,
                        pageType = pageType,
                    )
                if (title.isNotEmpty()) {
                    list.add(singerDetails)
                }
            }
        }

        Innertube.SingerDetailsPage(
            title = title,
            thumbnail = thumbnail,
            description = description,
            list
        )
    }


suspend fun Innertube.moSingerDetailsMorePage(body: BrowseBody): Result<Innertube.BaseSingleColumnBrowseSongResults>? =
    runCatchingNonCancellable {
        val response = client.post(browse) {
            setBody(body)
        }.body<BrowseResponse>()

        val gridRenderer = response.contents
            ?.singleColumnBrowseResultsRenderer
            ?.tabs?.firstOrNull()
            ?.tabRenderer
            ?.content
            ?.sectionListRenderer
            ?.contents
            ?.firstOrNull()
            ?.gridRenderer


        val musicPlaylistShelfRenderer = response.contents
            ?.singleColumnBrowseResultsRenderer
            ?.tabs
            ?.firstOrNull()
            ?.tabRenderer
            ?.content
            ?.sectionListRenderer
            ?.contents
            ?.firstOrNull()
            ?.musicShelfRenderer

        val title = response.header?.musicHeaderRenderer?.title?.text
        val continuation = musicPlaylistShelfRenderer
            ?.continuations
            ?.firstOrNull()
            ?.nextContinuationData
            ?.continuation

        val songList: MutableList<Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults> =
            mutableListOf()

        val contentList = musicPlaylistShelfRenderer?.contents
        val contentGridItems = gridRenderer?.items
        if (contentList != null) {
            for (content: MusicShelfRenderer.Content in contentList) {
                val contentTitle = content.musicResponsiveListItemRenderer
                    ?.flexColumns
                    ?.firstOrNull()
                    ?.musicResponsiveListItemFlexColumnRenderer
                    ?.text?.text

                val name = content.musicResponsiveListItemRenderer
                    ?.flexColumns
                    ?.get(1)
                    ?.musicResponsiveListItemFlexColumnRenderer
                    ?.text?.text

                val thumbnail = content.musicResponsiveListItemRenderer
                    ?.thumbnail
                    ?.musicThumbnailRenderer
                    ?.thumbnail
                    ?.thumbnails?.let {
                        it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
                    }?.url

                val navigationEndpoint = content.musicResponsiveListItemRenderer
                    ?.flexColumns
                    ?.firstOrNull()
                    ?.musicResponsiveListItemFlexColumnRenderer
                    ?.text
                    ?.runs
                    ?.firstOrNull()
                    ?.navigationEndpoint

                val videoId = navigationEndpoint?.watchEndpoint?.videoId
                val playlistId = navigationEndpoint?.watchEndpoint?.playlistId


                songList.add(
                    Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults(
                        title = contentTitle,
                        name = name,
                        thumbnail = thumbnail,
                        videoId = videoId,
                        playlistId = playlistId
                    )
                )
            }
        } else {
            if (contentGridItems != null) {
                for (content: GridRenderer.Item in contentGridItems) {
                    songList.add(
                        Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults(
                            title = content.musicTwoRowItemRenderer?.title?.runs?.firstOrNull()?.text,
                            name = content.musicTwoRowItemRenderer?.subtitle?.text,
                            thumbnail = content.musicTwoRowItemRenderer
                                ?.thumbnailRenderer
                                ?.musicThumbnailRenderer
                                ?.thumbnail
                                ?.thumbnails?.let {
                                    it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
                                }?.url,
                            browseId = content.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.browseId,
                            params = content.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.params,
                            pageType = content.musicTwoRowItemRenderer?.navigationEndpoint?.browseEndpoint?.type
                        )
                    )
                }
            }
        }
        Innertube.BaseSingleColumnBrowseSongResults(
            title = title,
            songList = songList,
            continuation = continuation
        )
    }

suspend fun Innertube.moSingerDetailsMoreLoadMorePage(body: ContinuationBody): Result<Innertube.BaseSingleColumnBrowseSongResults>? =
    runCatchingNonCancellable {
        val response = client.post(browse) {
            setBody(body)
        }.body<ContinuationResponse>()

        val continuation = response.continuationContents
            ?.musicShelfContinuation
            ?.continuations
            ?.firstOrNull()
            ?.nextContinuationData
            ?.continuation

        val songList: MutableList<Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults> =
            mutableListOf()

        val contentList = response.continuationContents?.musicShelfContinuation?.contents
        if (contentList != null) {
            for (content: MusicShelfRenderer.Content in contentList) {
                val title = content.musicResponsiveListItemRenderer
                    ?.flexColumns
                    ?.firstOrNull()
                    ?.musicResponsiveListItemFlexColumnRenderer
                    ?.text?.text

                val name = content.musicResponsiveListItemRenderer
                    ?.flexColumns
                    ?.get(1)
                    ?.musicResponsiveListItemFlexColumnRenderer
                    ?.text?.text

                val thumbnail = content.musicResponsiveListItemRenderer
                    ?.thumbnail
                    ?.musicThumbnailRenderer
                    ?.thumbnail
                    ?.thumbnails?.let {
                        it.getOrNull(2) ?: it.getOrNull(1) ?: it.getOrNull(0)
                    }?.url

                val navigationEndpoint = content.musicResponsiveListItemRenderer
                    ?.flexColumns
                    ?.firstOrNull()
                    ?.musicResponsiveListItemFlexColumnRenderer
                    ?.text
                    ?.runs
                    ?.firstOrNull()
                    ?.navigationEndpoint

                val videoId = navigationEndpoint?.watchEndpoint?.videoId
                val playlistId = navigationEndpoint?.watchEndpoint?.playlistId


                songList.add(
                    Innertube.BaseSingleColumnBrowseSongResults.SingleColumnBrowseSongResults(
                        title, name, thumbnail, videoId, playlistId
                    )
                )
            }
        }
        Innertube.BaseSingleColumnBrowseSongResults(
            continuation = continuation,
            songList = songList
        )
    }