/** --- Phi Technologies --- */
#include "../libphitech/helpers.h"
#include "sierrachart.h"

#include <vector>

SCDLLName("PhitechBacktest");

using namespace phitech::helpers;

// In the study we use lowercase var names (with _) to distinguish them from Sierra's symbols.
SCSFExport scsf_TriggerBacktest(SCStudyInterfaceRef sc)
{
    // Example -> 2024-09-09 13:00:00/2024-09-09 13:30:00|2024-09-09 14:00:00/2024-09-09 14:30:00
    SCInputRef i_date_ranges = sc.Input[0];

    if (sc.SetDefaults)
    {
        sc.GraphName = "Trigger Backtest";
        sc.StudyDescription = "Phi Technologies study for Sierra.";
        sc.AutoLoop = 0;
        sc.GraphRegion = 0;
        sc.ReceivePointerEvents = ACS_RECEIVE_POINTER_EVENTS_ALWAYS;

        i_date_ranges.Name = "Date Ranges";
        i_date_ranges.SetString("");
        return;
    }

    int& is_running = sc.GetPersistentInt(0);
    int& is_init = sc.GetPersistentInt(0);
    int& current_range_index = sc.GetPersistentInt(1);
    auto* date_ranges = reinterpret_cast<std::vector<SCDateTime>*>(sc.GetPersistentPointer(3));

    if (sc.MenuEventID != 0)
    {
        is_running = sc.GetCustomStudyControlBarButtonEnableState(2);
        if (!is_running)
        {
            print(sc, "backtest stopped");
            sc.StopChartReplay(sc.ChartNumber);
            return;
        }
    }

    if (is_running)
    {
        if (!is_init)
        {
            print(sc, "init date ranges");
            std::vector<int> ranges = string_to_datetime_vector(i_date_ranges.GetString());
            std::vector<SCDateTime> sc_ranges;

            for (int i = 0; i < ranges.size(); i += 6)
            {
                if (i + 6 > ranges.size())
                    break;

                SCDateTime sc_current;
                sc_current.SetDateTimeYMDHMS(ranges[i], ranges[i + 1], ranges[i + 2], ranges[i + 3],
                                             ranges[i + 4], ranges[i + 5]);
                sc_ranges.push_back(sc_current);
            }

            sc.SetPersistentPointer(3, &sc_ranges);
            is_init = 1;
            return;
        }

        if (current_range_index + 1 >= date_ranges->size())
        {
            print(sc, "current_range_index out of bounds -> stop replay");
            print(sc, "current_range_index -> %d", current_range_index);
            print(sc, "date ranges size -> %d", date_ranges->size());
            sc.StopChartReplay(sc.ChartNumber);
            is_running = 0;
            return;
        }

        SCDateTime start = (*date_ranges)[current_range_index];
        SCDateTime end = (*date_ranges)[current_range_index + 1];

        SCDateTime current_datetime = sc.GetCurrentDateTime();
        if (current_datetime >= end)
            return;

        print(sc, "start backtest from first date for current range");
        sc.StartChartReplay(sc.ChartNumber, 30.0, start);
        current_range_index += 2;
    }
}
