//funkce a promenne specificke pro archiveTable
//usually work with archiveRecords

//ARCHIVE TABLES
let editor_diff_arch1
let editor_diff_arch2
var archData = null
var batchHeaders = []
var editorLog = null

function refresh_arch_and_callback(row, callback) {
    //console.log("entering refresh")
    var request = $.ajax({
        url: "/archived_runners/"+row.id,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
            API_KEY); },
        method:"GET",
        contentType: "application/json",
        dataType: "json",
        success:function(data){   
            //console.log("fetched data ok")                      
            //console.log(JSON.stringify(data,null,2));
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
            console.log(JSON.stringify(xhr));
        }
    });

    // Handling the responses of both requests
    $.when(request).then(function(response) {
        // Both requests have completed successfully
        //console.log("Result from  request:", response);
        //console.log("Response received. calling callback")
        //call callback function
        callback(response)

    }, function(error) {
        // Handle errors from either request here
        // Example:
        console.error("Error from first request:", error);
        console.log("requesting id error")
    });
}

//triggers charting
function get_detail_and_chart(row) {
    $.ajax({
        url:"/archived_runners_detail/"+row.id,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
            API_KEY); },
        method:"GET",
        contentType: "application/json",
        dataType: "json",
        success:function(data){							
            $('#button_show_arch').attr('disabled',false);
            $('#chartContainerInner').addClass("show");
            //$("#lines").html("<pre>"+JSON.stringify(row.stratvars,null,2)+"</pre>")
            
            //$('#chartArchive').append(JSON.stringify(data,null,2));
            //console.log(JSON.stringify(data,null,2));
            //if lower res is required call prepare_data otherwise call chart_archived_run()
            //get other base resolutions

            // console.log("received detail", data)
            // data = JSON.parse(data)
            // console.log("parsed detail", data)
            prepare_data(row, 1, "Min", data)
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
            //console.log(JSON.stringify(xhr));
            $('#button_show_arch').attr('disabled',false);
        }
    })
}

//rerun stratin (use to rerun strategy and also to rerun live/paper as bt on same period)
function run_day_again(turnintobt=false) {
    row = archiveRecords.row('.selected').data();
    var button_name = turnintobt ? '#button_runbt_arch' : '#button_runagain_arch'
    $(button_name).attr('disabled',true)

    var record1 = new Object()
    //console.log(JSON.stringify(rows))

    //record1 = JSON.parse(rows[0].strat_json)
    //record1.json = rows[0].json

    //TBD mozna zkopirovat jen urcite?

    //getting required data (detail of the archived runner + stratin to be run)
    var request1 = $.ajax({
        url: "/archived_runners/"+row.id,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
            API_KEY); },
        method:"GET",
        contentType: "application/json",
        dataType: "json",
        success:function(data){   
            //console.log("fetched data ok")                      
            //console.log(JSON.stringify(data,null,2));
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
            console.log(JSON.stringify(xhr));
        }
      });

      //nalaodovat data pro strategii
      var request2 = $.ajax({
        url: "/stratins/"+row.strat_id,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
            API_KEY); },
        method:"GET",
        contentType: "application/json",
        dataType: "json",
        success:function(data){   
            //console.log("fetched data ok")                      
            //console.log(JSON.stringify(data,null,2));
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
            console.log(JSON.stringify(xhr));
        }
      });


    // Handling the responses of both requests
    $.when(request1, request2).then(function(response1, response2) {
        // Both requests have completed successfully
        var result1 = response1[0];
        var result2 = response2[0];

        //console.log("Result from first request:", result1);
        //console.log("Result from second request:", result2);

        //console.log("calling compare")
        rerun_strategy(result1, result2, turnintobt)
        // Perform your action with the results from both requests
        // Example:

    }, function(error1, error2) {
        // Handle errors from either request here
        // Example:
        console.error("Error from first request:", error1);
        console.error("Error from second request:", error2);
    });


    function rerun_strategy(archRunner, stratData, turnintobt) {
        record1 = archRunner
        //console.log(record1)

        var note_prefix = "RERUN "
        if ((turnintobt) && ((record1.mode == 'live') || (record1.mode == 'paper'))) {
            record1.mode = 'backtest'
            record1.bt_from = record1.started
            record1.bt_to = record1.stopped
            note_prefix = "BT SAME PERIOD "
        }

        record1.note = note_prefix + record1.note
        //nebudeme muset odstanovat pri kazdem pridani noveho atributu v budoucnu
        //smazeneme nepotrebne a pridame potrebne
        //do budoucna predelat na vytvoreni noveho objektu
        delete record1["end_positions"];
        delete record1["end_positions_avgp"];
        delete record1["profit"];
        delete record1["trade_count"];
        delete record1["stratvars_toml"];
        delete record1["started"];
        delete record1["stopped"];
        delete record1["metrics"];
        delete record1["settings"];
        delete record1["stratvars"];

        if (record1.bt_from == "") {delete record1["bt_from"];}
        if (record1.bt_to == "") {delete record1["bt_to"];}
    
        //mazeme, pouze rerunujeme single
        delete record1["test_batch_id"];
        delete record1["batch_id"];

        const rec = new Object()
        rec.id2 = parseInt(stratData.id2);
        rec.name = stratData.name;
        rec.symbol = stratData.symbol;
        rec.class_name = stratData.class_name;
        rec.script = stratData.script;
        rec.open_rush = stratData.open_rush;
        rec.close_rush = stratData.close_rush;
        rec.stratvars_conf = stratData.stratvars_conf;
        rec.add_data_conf = stratData.add_data_conf;
        rec.note = stratData.note;
        rec.history = "";
        strat_json = JSON.stringify(rec, null, 2);
        record1.strat_json = strat_json
        
        //zkopirujeme strat_id do id a smazeme strat_id
        record1.id = record1.strat_id
        delete record1["strat_id"];

        //console.log("record1 pred odeslanim", record1)
        jsonString = JSON.stringify(record1);

        $.ajax({
            url:"/stratins/"+record1.id+"/run",
            beforeSend: function (xhr) {
                xhr.setRequestHeader('X-API-Key',
                    API_KEY); },
            method:"PUT",
            contentType: "application/json",
            data: jsonString,
            success:function(data){							
                $(button_name).attr('disabled',false);
                setTimeout(function () {
                    runnerRecords.ajax.reload();
                    stratinRecords.ajax.reload();
                }, 1500);
            },
            error: function(xhr, status, error) {
                var err = eval("(" + xhr.responseText + ")");
                window.alert(JSON.stringify(xhr));
                //console.log(JSON.stringify(xhr));
                $(button_name).attr('disabled',false);
            }
        })
    }

}


function expand_collapse_rows(event) {
    event.stopPropagation()
    var headerRow = $(this);
    var name = headerRow.data('name');
    var collapsed = headerRow.hasClass('collapsed');

    // Toggle the expand icon name
    var expandIcon = headerRow.find('.expand-icon');
    if (collapsed) {
        expandIcon.text('expand_less');
    } else {
        expandIcon.text('expand_more');
    }

    headerRow.toggleClass('collapsed');

    archiveRecords.rows().every(function () {
        var row = $(this.node());
        var rowGroup = row.attr('data-group-name');
        if (rowGroup == name) {
            row.toggle();
        }
    });

    // Save the state
    if (collapsed) {
        localStorage.setItem('dt-group-state-' + name, 'expanded');
    } else {
        localStorage.setItem('dt-group-state-' + name, 'collapsed');
    }
    }

function delete_batch(event){
    event.preventDefault();
    batch_id = $('#batch_id_del').val();
    $('#deletebatch').attr('disabled', 'disabled');
    $.ajax({
        url:"/archived_runners/batch/"+batch_id,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
                API_KEY); },
        method:"DELETE",
        contentType: "application/json",
        dataType: "json",
        data: JSON.stringify(batch_id),
        success:function(data){				
            $('#delFormBatch')[0].reset();
            window.$('#delModalBatch').modal('hide');
            $('#deletebatch').attr('disabled', false);				
            $('#button_delete_batch').attr('disabled', false);
            //console.log(data)
            archiveRecords.ajax.reload();
            disable_arch_buttons();
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
            console.log(JSON.stringify(xhr));
            $('#deletebatch').attr('disabled', false);
            $('#button_delete_batch').attr('disabled', false);
            archiveRecords.ajax.reload();
            disable_arch_buttons();
        }
    })
}


function analyze_optimal_cutoff(batch_id = null) {
    //definice parametru
    param_obj = { rem_outliers:false, steps:50}
    obj = {function: "analyze_optimal_cutoff", runner_ids:[], batch_id:null, params:param_obj}
    //bereme bud selected runners
    if (!batch_id) {
        rows = archiveRecords.rows('.selected').data();
        if (rows == undefined) {
            return
        }
        $('#button_analyze').attr('disabled','disabled');
        // Extract IDs from each row's data and store them in an array
        obj.runner_ids = [];
        for (var i = 0; i < rows.length; i++) {
            obj.runner_ids.push(rows[i].id); // Assuming 'id' is the property that contains the row ID
        }
    }
    //nebo batch
    else {
        obj.batch_id = batch_id

    }
    console.log("analyze cutoff objekt", obj)
    // batch_id: Optional[str] = None
    // runner_ids: Optional[List[UUID]] = None
    // #additional parameter
    // params: Optional[dict] = None    

    $.ajax({
        url:"/batches/optimizecutoff/",
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
                API_KEY); },
        method:"POST",
        xhrFields: {
            responseType: 'blob'
        },
        xhr: function() {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState === 2) { // Headers have been received
                    if (xhr.status === 200) {
                        xhr.responseType = "blob"; // Set responseType to 'blob' for successful image responses
                    } else {
                        xhr.responseType = "text"; // Set responseType to 'text' for error messages
                    }
                }
            };
            return xhr;
        },
        contentType: "application/json",
        processData: false,
        data: JSON.stringify(obj),
        success:function(blob){		
            var url = window.URL || window.webkitURL;
            console.log("vraceny obraz", blob)
            console.log("url",url.createObjectURL(blob))
            display_image(url.createObjectURL(blob))
            if (!batch_id) {
                $('#button_analyze').attr('disabled',false);
            }
        },
        error: function(xhr, status, error) {
            console.log("proc to skace do erroru?")
            window.alert(JSON.stringify(xhr));
            console.log(JSON.stringify(xhr));
            $('#button_analyze').attr('disabled',false);
            if (!batch_id) {
                $('#button_analyze').attr('disabled',false);
            }             
        }
    })
}

//pomocna funkce, ktera vraci filtrovane radky tabulky (bud oznacene nebo batchove)
function get_selected_or_batch(batch_id = null) {
    if (!batch_id) {
        rows = archiveRecords.rows('.selected');
    } else {
        rows = archiveRecords.rows( function ( idx, data, node ) {
            return data.batch_id == batch_id;
        });
        //console.log("batch rows",batch_id, rows)
    }
    return rows
}

//prepares export data, either for selected rows or based on batch_id
function prepare_export(batch_id = null) {
    rows = get_selected_or_batch(batch_id)
    var trdList = []
    if(rows.data().length > 0 ) {
        //console.log(rows.data())
        // Loop through the selected rows and display an alert with each row's ID
        rows.every(function (rowIdx, tableLoop, rowLoop ) {
            var data = this.data()
            data.metrics.prescr_trades.forEach((trade) => {
                new_obj = {}
                new_obj["entry_time"] = (trade.entry_time) ? new Date(trade.entry_time * 1000) : null
                new_obj["entry_time"] = (new_obj["entry_time"]) ? new_obj["entry_time"].toLocaleString('cs-CZ', {
                    timeZone: 'America/New_York',
                  }) : null
                new_obj["exit_time"] = (trade.exit_time) ? new Date(trade.exit_time * 1000):null
                new_obj["exit_time"] = (new_obj["exit_time"]) ? new_obj["exit_time"].toLocaleString('cs-CZ', {
                    timeZone: 'America/New_York',
                  }) : null
                new_obj["direction"] = trade.direction
                new_obj["profit"] = trade.profit
                new_obj["rel_profit"] = trade.rel_profit
                trdList.push(new_obj)
            })
        });
    }
    return trdList
}

function download_exported_data(type, batch_id = null) {
    filename = batch_id ? "batch"+batch_id+"-trades" : "trades"
    if (type == "xml") {
        response_type = "application/xml"
        output = convertToXml(prepare_export(batch_id))
        }
    else {
        response_type = "text/csv"
        output = convertToCsv(prepare_export(batch_id))
    }
    console.log(output)
    downloadFile(response_type,type, filename, output)
}

function display_image(imageUrl) {
    // Attempt to load the image
    var img = new Image();
    img.src = imageUrl;
    img.onload = function() {
        // If the image loads successfully, display it
        $('#previewImg').attr('src', imageUrl);
        //$('#imagePreview').show();
        window.$('#imageModal').modal('show');        
    };
    img.onerror = function(e) {
        console.log("Image load error", e);
        console.log("Image object:", img);
        console.log("no image available")
        // If the image fails to load, do nothing
    };
}

function display_batch_report(batch_id) {
    //var imageUrl = '/media/report_'+data.id+".png"; // Replace with your logic to get image URL
    var imageUrl = '/media/basic/'+batch_id+'.png'; // Replace with your logic to get image URL
    //console.log(imageUrl)
    display_image(imageUrl)
}

function refresh_logfile() {
    logfile = $("#logFileSelect").val()
    lines = 1200
    $.ajax({
        url:"/log?lines="+lines+"&logfile="+logfile,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
            API_KEY); },
        method:"GET",
        contentType: "application/json",
        dataType: "json",
        success:function(response){
            if (editorLog) {
                editorLog.dispose();
            }
            if (response.lines.length == 0) {
                value = "no records";
                // $('#log-content').html("no records");
            }
            else {
                //console.log(response.lines)
                //var escapedLines = response.lines.map(line => escapeHtml(line));
                value = response.lines.join('\n')
                // $('#log-content').html(escapedLines.join('\n'));  
            }
            require(["vs/editor/editor.main"], () => {
                editorLog = monaco.editor.create(document.getElementById('log-container'), {
                    value: value,
                    language: 'mylogs',
                    theme: 'tomlTheme-dark',
                    automaticLayout: true,
                    readOnly: true
                });
                });
                // Focus at the end of the file:
                const model = editorLog.getModel();
                const lastLineNumber = model.getLineCount();
                const lastLineColumn = model.getLineMaxColumn(lastLineNumber);
                editorLog.setPosition({ lineNumber: lastLineNumber, column: lastLineColumn });
                editorLog.revealPosition({ lineNumber: lastLineNumber, column: lastLineColumn });
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
        }
    })        
}

function escapeHtml(text) {
    return text
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}
function delete_arch_rows(ids) {
    $.ajax({
        url:"/archived_runners/",
        beforeSend: function (xhr) {
            xhr.setRequestHeader('X-API-Key',
                API_KEY); },
        method:"DELETE",
        contentType: "application/json",
        dataType: "json",
        data: JSON.stringify(ids),
        success:function(data){				
            $('#delFormArchive')[0].reset();
            window.$('#delModalArchive').modal('hide');				
            $('#deletearchive').attr('disabled', false);
            //console.log(data)
            archiveRecords.ajax.reload();
            disable_arch_buttons()
        },
        error: function(xhr, status, error) {
            var err = eval("(" + xhr.responseText + ")");
            window.alert(JSON.stringify(xhr));
            console.log(JSON.stringify(xhr));
            $('#deletearchive').attr('disabled', false);
            //archiveRecords.ajax.reload();
        }
    })
}

function extractNumbersFromString(str) {
    // Regular expression to match the pattern #number1/number2
    const pattern = /#(\d+)\/(\d+)/;
    const match = str.match(pattern);

    if (match) {
        // Extract number1 and number2 from the match
        const number1 = parseInt(match[1], 10);
        const number2 = parseInt(match[2], 10);

        //return { number1, number2 };
        return number2;
    } else {
        return null;
    }
}

// Function to generate a unique key for localStorage based on batch_id
function generateStorageKey(batchId) {
    return 'dt-group-state-' + batchId;
}


function disable_arch_buttons() {
    //disable buttons (enable on row selection)
    $('#button_runagain_arch').attr('disabled','disabled');
    $('#button_runbt_arch').attr('disabled','disabled');
    $('#button_show_arch').attr('disabled','disabled');
    $('#button_delete_arch').attr('disabled','disabled');
    $('#button_delete_batch').attr('disabled','disabled');
    $('#button_analyze').attr('disabled','disabled');
    $('#button_edit_arch').attr('disabled','disabled');
    $('#button_compare_arch').attr('disabled','disabled');
    $('#button_report').attr('disabled','disabled');
    $('#button_export_xml').attr('disabled','disabled');   
    $('#button_export_csv').attr('disabled','disabled');   
}

function enable_arch_buttons() {
    $('#button_analyze').attr('disabled',false);
    $('#button_show_arch').attr('disabled',false);
    $('#button_runagain_arch').attr('disabled',false);
    $('#button_delete_arch').attr('disabled',false);
    $('#button_delete_batch').attr('disabled',false);
    $('#button_edit_arch').attr('disabled',false);
    $('#button_compare_arch').attr('disabled',false);
    $('#button_report').attr('disabled',false);
    $('#button_export_xml').attr('disabled',false);
    $('#button_export_csv').attr('disabled',false);

    //Backtest same period button is displayed only when row with mode paper/live is selected
    row = archiveRecords.row('.selected').data();
    if ((row.mode == 'paper') || (row.mode == 'live')) {
        $('#button_runbt_arch').attr('disabled',false);
    }
}