package com.abdownloadmanager.desktop.utils

import ir.amirab.downloader.connection.DownloaderClient
import ir.amirab.downloader.connection.response.ResponseInfo
import ir.amirab.downloader.downloaditem.DownloadCredentials
import com.abdownloadmanager.utils.isValidUrl
import ir.amirab.util.UrlUtils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

class LinkChecker(
    initialCredentials: DownloadCredentials = DownloadCredentials.empty(),
    private val client: DownloaderClient,
) {
    //input
    val credentials = MutableStateFlow(initialCredentials)

    private val _suggestedName = MutableStateFlow(null as String?)
    val suggestedName = _suggestedName.asStateFlow()

    private val _length = MutableStateFlow(null as Long?)
    val length = _length.asStateFlow()

    private val _isLoading = MutableStateFlow(false)
    val isLoading = _isLoading.asStateFlow()
    private val _responseInfo = MutableStateFlow(null as ResponseInfo?)
    val responseInfo = _responseInfo.asStateFlow()

    private val _isValid = MutableStateFlow(false)
    private val isValid = _isValid.asStateFlow()

    private fun setInfo(responseInfo: ResponseInfo?) {
        _responseInfo.update { responseInfo }
        updateNameAndLength(responseInfo)
        validate()
    }

    private fun validate() {
        val isValid = when {
            !isValidUrl(this.credentials.value.link) -> false
            else -> true
        }
        _isValid.update { isValid }
    }

    suspend fun check() {
        val downloadCredentials = credentials.value
        val link = downloadCredentials.link
        val isValidUrl = isValidUrl(link)
        setInfo(null)
        if (link.isBlank() || !isValidUrl) {
            return
        }
        _isLoading.update { true }
        val info = runCatching {
            client.head(downloadCredentials)
        }.getOrNull()
        _isLoading.update { false }
        setInfo(info)
    }


    private fun updateNameAndLength(responseInfo: ResponseInfo?) {
        val suggestedName = responseInfo?.fileName ?: kotlin.run {
            UrlUtils.extractNameFromLink(this.credentials.value.link)
        }
        _suggestedName.update { suggestedName }

        _length.update {
            responseInfo?.run {
                totalLength.takeIf { isSuccessFul }
            }
        }
    }
}