package com.margelo.nitro.lunardatepicker.services import com.margelo.nitro.lunardatepicker.* import com.margelo.nitro.lunardatepicker.models.* import com.margelo.nitro.lunardatepicker.utils.* import com.margelo.nitro.lunardatepicker.constants.DataConstants import android.util.Log import java.util.* /** * Service for building picker configurations with caching optimization */ class ConfigurationBuilder { companion object { private const val TAG = DataConstants.LogTags.CONFIG_BUILDER } // Cache service for optimized configuration building private val cacheService: ConfigurationCacheService by lazy { ConfigurationCacheService() } /** * Builds a PickerConfig from presentation parameters and global configuration * Uses caching for O(1) configuration building * @param params Presentation parameters * @param globalConfig Global configuration (nullable) * @return Configured PickerConfig */ fun buildPickerConfig(params: LDP_PresentParams, globalConfig: LDP_ConfigParams?): PickerConfig { return try { // Use cache service for O(1) configuration building val config = cacheService.getOrBuildConfiguration(params, globalConfig) Log.d(TAG, "Configuration built successfully using cache service") config } catch (e: Exception) { Log.e(TAG, "Failed to build configuration using cache service, falling back to manual build", e) // Fallback to manual configuration building buildConfigurationManually(params, globalConfig) } } /** * Fallback method for manual configuration building * Used when cache service fails */ private fun buildConfigurationManually(params: LDP_PresentParams, globalConfig: LDP_ConfigParams?): PickerConfig { var pickerConfig = PickerConfig.default.copy() // Apply basic configuration pickerConfig = pickerConfig.copy( controller = pickerConfig.controller.copy( title = params.title, cancelButtonTitle = params.textCancel ) ) // Apply theme if available globalConfig?.let { config -> config.themes[params.theme]?.let { theme -> pickerConfig = applyTheme(theme, pickerConfig) } } // Apply language if available globalConfig?.let { config -> config.languages[params.language]?.let { language -> pickerConfig = applyLanguage(language, pickerConfig) } } // Apply timezone if available globalConfig?.let { config -> pickerConfig = applyTimeZone(config.timeZoneOffset, pickerConfig) } // Apply year range if available globalConfig?.let { config -> pickerConfig = applyYearRange(config.yearRangeOffset, pickerConfig) } // Apply month visible debounce delay if available globalConfig?.let { config -> config.monthVisibleDebounceDelaySeconds?.let { delay -> pickerConfig = applyMonthVisibleDebounceDelay(delay, pickerConfig) } } return pickerConfig } /** * Gets configuration cache statistics * @return Cache statistics string */ fun getCacheStats(): String { return cacheService.getCacheStats().toString() } /** * Clears configuration cache */ fun clearCache() { cacheService.clearAllCaches() Log.d(TAG, "Configuration cache cleared") } /** * Applies a theme to the picker configuration * @param theme Custom style theme * @param config Current picker configuration * @return Updated picker configuration */ private fun applyTheme(theme: LDP_CustomStyle, config: PickerConfig): PickerConfig { return config.copy( controller = config.controller.copy( backgroundColor = ColorUtils.colorFromHex(theme.backgroundColor), cancelColor = ColorUtils.colorFromHex(theme.cancelColor), titleColor = ColorUtils.colorFromHex(theme.titleColor) ), dayCell = config.dayCell.copy( dateLabelColor = ColorUtils.colorFromHex(theme.dateLabelColor), weekendLabelColor = ColorUtils.colorFromHex(theme.weekendLabelColor), lunarDateLabelColor = ColorUtils.colorFromHex(theme.lunarDateLabelColor), specialDateLabelColor = ColorUtils.colorFromHex(theme.specialDayLabelColor), priceLabelColor = ColorUtils.colorFromHex(theme.priceLabelColor), cheapestPriceLabelColor = ColorUtils.colorFromHex(theme.cheapestPriceLabelColor), rangeBackgroundColor = ColorUtils.colorFromHex(theme.rangeBackgroundColor), selectedBackgroundColor = ColorUtils.colorFromHex(theme.selectedBackgroundColor), selectedTextColor = ColorUtils.colorFromHex(theme.selectedTextColor) ), monthHeader = config.monthHeader.copy( labelColor = ColorUtils.colorFromHex(theme.monthLabelColor) ), weekView = config.weekView.copy( backgroundColor = ColorUtils.colorFromHex(theme.weekViewBackgroundColor), weekendLabelColor = ColorUtils.colorFromHex(theme.weekendLabelColor), weekLabelColor = ColorUtils.colorFromHex(theme.dateLabelColor) ) ) } /** * Applies a language configuration to the picker * @param language Custom language configuration * @param config Current picker configuration * @return Updated picker configuration */ private fun applyLanguage(language: LDP_CustomLanguage, config: PickerConfig): PickerConfig { return config.copy( monthHeader = config.monthHeader.copy( monthNames = language.monthNames ), weekView = config.weekView.copy( weekdayNames = language.weekdayNames ) ) } /** * Applies timezone configuration * @param offset Timezone offset in hours * @param config Current picker configuration * @return Updated picker configuration */ private fun applyTimeZone(offset: Double, config: PickerConfig): PickerConfig { val timeZone = TimeZone.getTimeZone("GMT${if (offset >= 0) "+" else ""}${offset.toInt()}") return config.copy( calendar = config.calendar.copy( timeZone = timeZone ) ) } /** * Applies year range configuration * @param offset Year range offset * @param config Current picker configuration * @return Updated picker configuration */ private fun applyYearRange(offset: Double, config: PickerConfig): PickerConfig { return config.copy( yearRangeOffset = offset.toInt() ) } /** * Applies month visible debounce delay configuration * @param delay Debounce delay in seconds * @param config Current picker configuration * @return Updated picker configuration */ private fun applyMonthVisibleDebounceDelay(delay: Double, config: PickerConfig): PickerConfig { return config.copy( monthVisibleDebounceDelaySeconds = delay ) } }