package id.iiyh.inatrading.feature.profile.presentation

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import id.iiyh.inatrading.feature.auth.domain.repository.AuthRepository
import id.iiyh.inatrading.feature.profile.data.model.CityItem
import id.iiyh.inatrading.feature.profile.data.model.CreateShippingAddressRequest
import id.iiyh.inatrading.feature.profile.data.model.ProvinceItem
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

const val ADDRESS_COUNTRY_INDONESIA = "indonesia"
const val ADDRESS_COUNTRY_OTHER = "other"

data class AddShippingAddressUiState(
    val label: String = "rumah",
    val customLabel: String = "",
    val recipient: String = "",
    val phone: String = "",
    val countryKey: String = ADDRESS_COUNTRY_INDONESIA,
    val customCountry: String = "",
    val provinces: List<ProvinceItem> = emptyList(),
    val cities: List<CityItem> = emptyList(),
    val selectedProvinceId: String? = null,
    val selectedCityId: String? = null,
    val isLoadingProvinces: Boolean = false,
    val isLoadingCities: Boolean = false,
    val province: String = "",
    val city: String = "",
    val postalCode: String = "",
    val address: String = "",
    val isPrimary: Boolean = true,
    val latitude: Double? = null,
    val longitude: Double? = null,
    val isResolvingLocation: Boolean = false,
    val isSaving: Boolean = false,
    val infoMessage: String? = null,
    val saveSuccess: Boolean = false,
)

@HiltViewModel
class AddShippingAddressViewModel @Inject constructor(
    private val authRepository: AuthRepository,
) : ViewModel() {

    private val _uiState = MutableStateFlow(AddShippingAddressUiState())
    val uiState: StateFlow<AddShippingAddressUiState> = _uiState.asStateFlow()

    init {
        loadProvinces()
    }

    fun onLabelSelected(value: String) {
        _uiState.update { it.copy(label = value, customLabel = "") }
    }

    fun onCustomLabelSelected() {
        _uiState.update {
            it.copy(
                label = CUSTOM_LABEL_KEY,
                customLabel = it.customLabel,
            )
        }
    }

    fun onCustomLabelChange(value: String) {
        _uiState.update {
            it.copy(
                label = CUSTOM_LABEL_KEY,
                customLabel = value,
            )
        }
    }

    fun onRecipientChange(value: String) {
        _uiState.update { it.copy(recipient = value) }
    }

    fun onPhoneChange(value: String) {
        _uiState.update { it.copy(phone = value.filter(Char::isDigit)) }
    }

    fun onCountrySelected(value: String) {
        _uiState.update {
            it.copy(
                countryKey = value,
                customCountry = if (value == ADDRESS_COUNTRY_OTHER) it.customCountry else "",
                province = "",
                city = "",
                selectedProvinceId = null,
                selectedCityId = null,
                cities = emptyList(),
            )
        }
        if (value == ADDRESS_COUNTRY_INDONESIA) {
            loadProvinces()
        }
    }

    fun onCustomCountryChange(value: String) {
        _uiState.update { it.copy(customCountry = value) }
    }

    fun onProvinceSelected(id: String) {
        val province = _uiState.value.provinces.firstOrNull { it.id == id } ?: return
        _uiState.update {
            it.copy(
                selectedProvinceId = province.id,
                province = province.name.orEmpty(),
                selectedCityId = null,
                city = "",
                cities = emptyList(),
            )
        }
        province.id?.let(::loadCities)
    }

    fun onProvinceChange(value: String) {
        _uiState.update { it.copy(province = value) }
    }

    fun onCitySelected(id: String) {
        val city = _uiState.value.cities.firstOrNull { it.id == id } ?: return
        _uiState.update {
            it.copy(
                selectedCityId = city.id,
                city = city.name.orEmpty(),
            )
        }
    }

    fun onCityChange(value: String) {
        _uiState.update { it.copy(city = value) }
    }

    fun onPostalCodeChange(value: String) {
        _uiState.update { it.copy(postalCode = value.filter(Char::isDigit)) }
    }

    fun onAddressChange(value: String) {
        _uiState.update { it.copy(address = value) }
    }

    fun onPrimaryChange(value: Boolean) {
        _uiState.update { it.copy(isPrimary = value) }
    }

    fun onLocationCaptured(latitude: Double, longitude: Double) {
        _uiState.update {
            it.copy(
                latitude = latitude,
                longitude = longitude,
                isResolvingLocation = false,
                infoMessage = "Lokasi saat ini berhasil digunakan.",
            )
        }
    }

    fun onLocationError(message: String) {
        _uiState.update { it.copy(isResolvingLocation = false, infoMessage = message) }
    }

    fun onLocationRequestStarted() {
        _uiState.update {
            it.copy(
                isResolvingLocation = true,
                infoMessage = "Mengambil koordinat lokasi saat ini...",
            )
        }
    }

    fun onPinPointClick() {
        _uiState.update {
            it.copy(infoMessage = "Pemilihan pin point map akan segera tersedia.")
        }
    }

    fun saveAddress() {
        val state = _uiState.value
        if (state.recipient.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Nama penerima wajib diisi.") }
            return
        }
        if (state.phone.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Nomor telepon wajib diisi.") }
            return
        }
        if (state.province.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Provinsi wajib diisi.") }
            return
        }
        if (state.city.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Kota wajib diisi.") }
            return
        }
        if (state.postalCode.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Kode pos wajib diisi.") }
            return
        }
        if (state.address.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Detail alamat wajib diisi.") }
            return
        }
        if (state.label == CUSTOM_LABEL_KEY && state.customLabel.isBlank()) {
            _uiState.update { it.copy(infoMessage = "Label alamat wajib diisi.") }
            return
        }
        if (state.resolvedCountry().isBlank()) {
            _uiState.update { it.copy(infoMessage = "Negara wajib dipilih.") }
            return
        }
        if (state.countryKey == ADDRESS_COUNTRY_INDONESIA && state.selectedProvinceId == null) {
            _uiState.update { it.copy(infoMessage = "Provinsi wajib dipilih.") }
            return
        }
        if (state.countryKey == ADDRESS_COUNTRY_INDONESIA && state.selectedCityId == null) {
            _uiState.update { it.copy(infoMessage = "Kota/Kabupaten wajib dipilih.") }
            return
        }
        if (state.isResolvingLocation) {
            _uiState.update { it.copy(infoMessage = "Tunggu sampai koordinat lokasi selesai diambil.") }
            return
        }

        viewModelScope.launch {
            _uiState.update { it.copy(isSaving = true, infoMessage = null) }
            authRepository.createAddress(
                CreateShippingAddressRequest(
                    label = state.submittedLabel(),
                    recipient = state.recipient.trim(),
                    mobile = normalizePhone(state.phone),
                    address = state.address.trim(),
                    country = state.resolvedCountry(),
                    province = state.province.trim(),
                    city = state.city.trim(),
                    postalCode = state.postalCode.trim(),
                    isPrimary = state.isPrimary,
                    latitude = state.latitude,
                    longitude = state.longitude,
                )
            ).onSuccess {
                _uiState.update {
                    it.copy(
                        isSaving = false,
                        saveSuccess = true,
                        infoMessage = "Alamat berhasil disimpan.",
                    )
                }
            }.onFailure { error ->
                _uiState.update {
                    it.copy(
                        isSaving = false,
                        infoMessage = error.message ?: "Gagal menyimpan alamat",
                    )
                }
            }
        }
    }

    fun consumeInfoMessage() {
        _uiState.update { it.copy(infoMessage = null) }
    }

    fun consumeSaveSuccess() {
        _uiState.update { it.copy(saveSuccess = false) }
    }

    private fun loadProvinces() {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoadingProvinces = true) }
            authRepository.getProvinces()
                .onSuccess { provinces ->
                    _uiState.update {
                        it.copy(
                            isLoadingProvinces = false,
                            provinces = provinces.sortedBy { item -> item.name.orEmpty() },
                        )
                    }
                }
                .onFailure { error ->
                    _uiState.update {
                        it.copy(
                            isLoadingProvinces = false,
                            infoMessage = error.message ?: "Gagal memuat provinsi",
                        )
                    }
                }
        }
    }

    private fun loadCities(provinceId: String) {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoadingCities = true) }
            authRepository.getCities(provinceId)
                .onSuccess { cities ->
                    _uiState.update {
                        it.copy(
                            isLoadingCities = false,
                            cities = cities.sortedBy { item -> item.name.orEmpty() },
                        )
                    }
                }
                .onFailure { error ->
                    _uiState.update {
                        it.copy(
                            isLoadingCities = false,
                            infoMessage = error.message ?: "Gagal memuat kota",
                        )
                    }
                }
        }
    }

    private fun normalizePhone(raw: String): String {
        val digits = raw.filter(Char::isDigit)
        if (digits.startsWith("0")) return digits
        if (digits.startsWith("62")) return "0${digits.removePrefix("62")}"
        return "0$digits"
    }

    private fun AddShippingAddressUiState.submittedLabel(): String {
        return if (label == CUSTOM_LABEL_KEY) customLabel.trim() else label
    }

    private fun AddShippingAddressUiState.resolvedCountry(): String {
        return if (countryKey == ADDRESS_COUNTRY_OTHER) customCountry.trim() else "Indonesia"
    }

    companion object {
        const val CUSTOM_LABEL_KEY = "__custom__"
    }
}
