package dev.photosync.platform;

import dev.photosync.client.PhotoSyncClient;
import dev.photosync.platform.impl.OpenKey;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;

import java.util.Optional;

/**
 * Fabric's way in, and the mixins' way back.
 *
 * <p>Three lines of wiring: build the client against this bucket's bridge, tick
 * it, and close it when the game is shutting down. Everything else the mod does
 * is reached from those.
 *
 * <p>The static field is the same concession {@code ScreenshotBus} and
 * {@code QuitGuard} make, for the same reason -- a mixin is woven into a class
 * nobody constructs, so it cannot be handed a collaborator. Those two cover the
 * capture and quit hooks between them; this covers the third, the HUD, which
 * needs the client itself because it draws through it. Keeping the field here
 * rather than in each bucket's mixin package means there is exactly one of them.
 */
@Slf4j
public final class PhotoSyncMod implements ClientModInitializer {

    private static volatile PhotoSyncClient client;

    @Override
    public void onInitializeClient() {
        OpenKey openKey = OpenKey.register();
        PhotoSyncClient started = new PhotoSyncClient(new MinecraftBridge()).start();
        client = started;

        ClientTickEvents.END_CLIENT_TICK.register(game -> {
            started.tick();
            // Drained in a loop: holding the key over a lag spike queues several
            // presses, and opening the screen three times is not what was meant.
            boolean pressed = false;
            while (openKey.wasPressed()) {
                pressed = true;
            }
            if (pressed) {
                started.openScreen();
            }
        });

        ClientLifecycleEvents.CLIENT_STOPPING.register(game -> {
            client = null;
            started.close();
        });
    }

    /**
     * The running client, for the HUD mixin.
     *
     * <p>Empty before {@code onInitializeClient} finishes and again once the
     * game is stopping, both of which are frames the HUD can still be drawn in.
     */
    public static Optional<PhotoSyncClient> client() {
        return Optional.ofNullable(client);
    }
}
