package org.firstinspires.ftc.teamcode;

import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
import com.qualcomm.robotcore.util.ReadWriteFile;

import org.firstinspires.ftc.robotcore.internal.system.AppUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.util.HashMap;

@TeleOp(name="Gamepad Recorder v1.0.1")
public class GamepadRecord extends Gamepad {
    private final String outputFileName = "recording1.json";
    private File outputFile;
    private JSONObject outputJSON;
    private boolean prevGuide = false;
    private int currentIndex = 0;
    private HashMap<GameMotor, API.Motor> motors = new HashMap<>();

    @Override
    public void init() {
        super.init();

        outputFile = AppUtil.getInstance().getSettingsFile(outputFileName);
        try {
            outputJSON = new JSONObject();
            outputJSON.put("recordedData", new JSONArray());
        } catch (JSONException e) {
            api.print("Why are we here? Just to suffer?");
        }

        for (GameMotor m : GameMotor.values()) {
            motors.put(m, api.new Motor(m.name));
        }

        api.clear();
        api.print("Press play to start");
    }

    @Override
    public void start() {
        this.resetStartTime();
    }

    @Override
    public void loop() {
        long ms = System.currentTimeMillis()+15;

        super.loop();

        api.print("Time", this.time + "");

        try {
            JSONObject motorData = new JSONObject();

            for (GameMotor m : GameMotor.values()) {
                //noinspection ConstantConditions
                double power = motors.get(m).getRawPower();
                motorData.put(m.name().toLowerCase(), power);
            }

            JSONObject currentData = new JSONObject()
                    .put("time", this.getRuntime() * 1000) // Time
                    .put("data", motorData); // Data

            if (
                    currentIndex == 0 ||
                    !currentData.get("data").toString()
                    .equals(
                    outputJSON.getJSONArray("recordedData").getJSONObject(currentIndex - 1).get("data").toString())
            )
                outputJSON.getJSONArray("recordedData").put(currentIndex++, currentData);
        } catch (JSONException e) {
            api.print("Why are we here? Just to suffer?" + System.lineSeparator() + e.getMessage());
        }

        ms -= System.currentTimeMillis();
        if (ms > 5) try {
            Thread.sleep(ms);
        } catch (InterruptedException ie) {
            api.print("Why are we here? Just to suffer? (Thread.sleep error)");
        }

        if (gamepad1.guide && !prevGuide) {
            ReadWriteFile.writeFile(outputFile, outputJSON.toString());
            api.print("Wrote file to '" + outputFile.getName() + "'!");
        }

        prevGuide = gamepad1.guide;
    }
}
