#pragma once

#include "bakkesmod/plugin/bakkesmodplugin.h"
#include "bakkesmod/plugin/pluginwindow.h"
#include "bakkesmod/plugin/PluginSettingsWindow.h"
#include "imgui/imgui.h"
#include "imgui/imgui_searchablecombo.h"
#include "imgui/imgui_internal.h"
#include "shot.h"
#include <vector>
#include <filesystem>
#include <string>
#include "version.h"
#include <chrono>
#include "bakkesmod/wrappers/includes.h"
#include "bakkesmod/wrappers/canvaswrapper.h"

namespace fs = std::filesystem;
constexpr auto plugin_version = stringify(VERSION_MAJOR) "." stringify(VERSION_MINOR) "." stringify(VERSION_PATCH) "." stringify(VERSION_BUILD);


class HSTraining : public BakkesMod::Plugin::BakkesModPlugin, public BakkesMod::Plugin::PluginWindow
{
    public:
        //note: sorry for the shit code I made most of this years ago when i was just learning to code. I didnt really want to take the time to refactor it all and chatgpt 5 fucks everything up if I have it try.
        
        //calls on loading the program
        void onLoad();
        void onUnload();
        ~HSTraining();
        //interactng with the world
        void ballMove();
        void ballVelocity();
        void carMove();
        void ballSpeed();
        bool delayRepeat();
        //void HitAtYou();
        //interacts with the shot class
        void overideShot();
        void setUpShot();
        /*void HitHigh();
        void HitTowardsOrange();
        void ScoreGoal();*/
        //variables needed for each shot
        float height = 0.0;
        float length = 0.0;
        float width = 0.0;
        float speedX = 0.0;
        float speedY = 0.0;
        float speedZ = 0.0;
        float carX = 0.0;
        float carY = 0.0;
        float carZ = 0.0;
        int carYaw = 0;
        int carPitch = 0;
        int carRoll = 0;
        int SSpeed = 2985;
        std::string shotName = "";
        
        bool setMaxScore = true;
        int maxScore = 0;
        float repshot = 500.0;
        bool repeatShot = false;
        bool rtimer = false;
        float carHitDelay = 100.0;
        void Rep();
        //randomizer
        bool randomizer = false;
        bool mirBall = false;
        bool mirCar = false;
        bool splitBall = false;
        bool splitCar = false;
        bool ranActive[13];
        bool selectRan = false;
        bool makeCeiling = false;
        bool makeWall = false;
        bool isRan = false;
        //garbage
        int linesOfFile = 0;
        bool lineStart = false;
        
        //Training pack stuff
        std::string normalizePathSeparators(const std::string& path);
        void oldToNewOrganization();
        void loadTrainingPack(int packNum);
        void getTrainingPacks();
        void createTrainingPack(std::string packName);
        void renameTrainingPack(int packNum, std::string newName);
        void deleteTrainingPack(int packNum);
        void copyTrainingPack(int packNum, std::string newName);
        bool transferShot(int senderPackNum, int receiverPackNum, int shotnum, std::string newName);
        bool createNewShot(int TrainingPackNum, float height1, float length1, float width1, float speedX1, float speedY1, float speedZ1, float carX1, float carY1, float carZ1, int carYaw1, std::string nameShot1, int carPitch1, int carRoll1);
        
        //gets a list of all shots for the specific training pack
        std::vector<std::string> getAllShotNames(int TrainingPackNum);
        std::vector<std::string> trainingPacks;

        //time variables
        std::chrono::time_point<std::chrono::system_clock> t1 = std::chrono::system_clock::now();

        std::chrono::time_point<std::chrono::system_clock> t2 = t1;

        //time variables
        std::chrono::time_point<std::chrono::system_clock> d1 = std::chrono::system_clock::now();

        std::chrono::time_point<std::chrono::system_clock> d2 = d1;
        
        

        int controllerKeybind = 11;
        int KeyBoardKeybind = 42;
        const std::vector<std::string> controllerKeys = {
            "XboxTypeS_LeftThumbStick", "XboxTypeS_RightThumbStick", "XboxTypeS_Start", "XboxTypeS_Y", "XboxTypeS_X", "XboxTypeS_B", "XboxTypeS_A", "XboxTypeS_LeftShoulder", "XboxTypeS_RightShoulder",
            "XboxTypeS_LeftTrigger", "XboxTypeS_RightTrigger", "XboxTypeS_Back", "XboxTypeS_DPad_Up",
            "XboxTypeS_DPad_Down", "XboxTypeS_DPad_Left", "XboxTypeS_DPad_Right"
        };
      
        const std::vector<std::string> KeyBoardKeys = {
            "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
            "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "Escape", "Tab",  "Pause",
            "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Underscore",
            "Equals", "Backslash", "BackSpace", "LeftBracket", "RightBracket", "Enter", "CapsLock",
            "Semicolon", "Quote", "LeftShift", "Comma", "Period", "Slash", "RightShift", "LeftControl",
            "LeftAlt", "SpaceBar", "RightAlt", "RightControl", "Left", "Up", "Down", "Right", "Home",
            "End", "Insert", "PageUp", "Delete", "PageDown", "NumLock" "NumPadOne", "NumPadTwo", "NumPadThree", "NumPadFour", "NumPadFive", "NumPadSix",
            "NumPadSeven", "NumPadEight", "NumPadNine", "NumPadZero", "Decimal", "LeftMouseButton",
            "RightMouseButton", "ThumbMouseButton", "ThumbMouseButton2", "MouseScrollUp", "MouseScrollDown",
        };

        std::vector<std::string>::const_iterator keysIt;
        
        
        //variables for training mode
        bool trainingActive = false;
        int shotCount = 100;
        //int shotCount1 = 100;
        

        //bool array for storing values for whether the shot is activated or not true == activated and false == not activated
        std::vector<bool> isShotActive;

        //changes binding
        //void newBind(std::string str1, std::string str2);
        void read();
        void write();

        //stuff for inputs
        void controlInput();
    //telling the program to load the shot
        void loadShot();

        
        //tells the program to access a random shot
        void shotRandom();
    private:
        //stuff to enable things
        bool HeatEnabled = false;//allows the program to be turned off
        bool carEnabled = false;//allows the teleportation of the car to be turned off
        bool noShot;
        std::vector<Shot> ShotData;
        //int shotNumber = 0;
        int numberHits = 0;
        int IUse = 0;
        bool selectAll = false;
        int isZero1 = -1;
    


    std::string GetPluginName();

    //Gui tests
    private:
        bool showSecondWindow = false;
        bool isWindowOpen_ = false;
        bool shouldBlockInput = true;
        std::string menuTitle_ = "Heatseaker Training";
        int TPackNum = 0;
        char newShotName[128];
        bool openEditPopup = false;
        int editIndex = -1;
        bool sliderOrTextBox = false;
    public:
        
        void Render();
        std::string GetMenuName();
        std::string GetMenuTitle();
        void SetImGuiContext(uintptr_t ctx);
        bool ShouldBlockInput();
        bool IsActiveOverlay();
        void OnOpen();
        void OnClose();
        
    //DittoBot Stuff
    public:
    
        //void onLoad1();
        //void onUnload1();
        //void unloadARR();
private:

    //void getInput();
    //void stopInput();
    //void Replay();
    //void SetupGame();
    //void Repeat();
    //void RecordTrain();
    //std::string getRecordName(int l);
    //void Setup();
    //void recordRandom();
    //void Overide();
    //void LoadRecord();
    //bool dittoOn = false;
    //bool noRecord;
    //bool trainingActive1 = false;
    //bool selectAll1 = false;
    
    //int FirstUse = 0;
    //int oneUse = 0;
    //bool replay = false;
    //bool recording = false;
    //bool isShotActive1[100];
    //std::vector<std::vector<float>> RInput;
    //std::vector<float> lop;
    //int incr = 0;
    //int cincr = 0;
    //int RecordCount = 20;
    ////for if i want to have a setting that alows you to increase the shotcount unimplemented
    //int RecordCount1 = 20;
    //std::vector<Recorder> RecordData;
    ////shotname saved in the default shot.
    //std::string camname = "Recording";
    ////contains the shotname to save
    //std::string RecordName = "Record ";
    //int currentShot = 20;
    //int curr = 0;
    //int defaultSubsteps = 0;
    //bool SetSubsteps = false;
    //int defaultframes = 0.0;
    //bool SetFrames = false;

    
public:

    //void Render1();
    //std::string GetMenuName1();
    //std::string GetMenuTitle1();
    //void SetImGuiContext(uintptr_t ctx);
    //bool ShouldBlockInput1();
    //bool IsActiveOverlay1();
    //void OnOpen1();
    //void OnClose1();
};

