package dev.photosync.core.config;

import dev.photosync.core.provider.AlbumRef;
import dev.photosync.core.provider.ProviderConnection;
import dev.photosync.core.provider.ProviderId;
import lombok.Builder;

/**
 * The whole of PhotoSync's settings, as one immutable value.
 *
 * <p>Screens never mutate this. They build a new one -- {@code
 * config.toBuilder().albumId(id).build()} -- and hand it to {@link
 * ConfigService}, which persists it and tells everyone who cares. That makes
 * "cancel" free and "what changed?" answerable.
 */
@Builder(toBuilder = true)
public record PhotoSyncConfig(
        ProviderId provider,
        ProviderConnection connection,
        String albumId,
        UploadSettings upload,
        AutoCaptureSettings autoCapture,
        NotificationSettings notifications,
        BrowserSettings browser,
        ConfigLocation location) {

    public static PhotoSyncConfig defaults(ProviderId provider) {
        return PhotoSyncConfig.builder()
                .provider(provider)
                .connection(ProviderConnection.empty())
                .albumId("")
                .upload(UploadSettings.defaults())
                .autoCapture(AutoCaptureSettings.defaults())
                .notifications(NotificationSettings.defaults())
                .browser(BrowserSettings.defaults())
                .location(ConfigLocation.INSTANCE)
                .build();
    }

    /**
     * Repairs a config that came off disk: fills in anything a hand edit removed
     * and clamps anything a hand edit made absurd. Called on every load, so the
     * rest of the mod may assume its values are sane.
     */
    public PhotoSyncConfig normalized(ProviderId fallbackProvider) {
        return PhotoSyncConfig.builder()
                .provider(provider == null ? fallbackProvider : provider)
                .connection(connection == null ? ProviderConnection.empty() : connection)
                .albumId(albumId == null ? "" : albumId.trim())
                .upload((upload == null ? UploadSettings.defaults() : upload).normalized())
                .autoCapture((autoCapture == null ? AutoCaptureSettings.defaults() : autoCapture).normalized())
                .notifications((notifications == null ? NotificationSettings.defaults() : notifications).normalized())
                .browser((browser == null ? BrowserSettings.defaults() : browser).normalized())
                .location(location == null ? ConfigLocation.INSTANCE : location)
                .build();
    }

    /** Where uploads go and what the browser shows. Empty album id means the whole library. */
    public AlbumRef album() {
        return AlbumRef.of(albumId);
    }

    /** True once there is enough here to actually talk to a server. */
    public boolean isReady() {
        return connection.isConfigured();
    }
}
