package SGN::View::Mason::Commands;
use strict;
use vars qw($m $c);
HTML::Mason::Component::FileBased->new(
'code' => sub {
use utf8; local $SGN::View::Mason::Commands::m = $HTML::Mason::Commands::m;
HTML::Mason::Exception::Params->throw
    ( error =>
      "Odd number of parameters passed to component expecting name/value pairs"
    ) if @_ % 2;
my ( %services );
{
    my %pos;
    for ( my $x = 0; $x < @_; $x += 2 )
    {
        $pos{ $_[$x] } = $x + 1;
    }

    foreach my $arg ( qw( services ) )
    {
        HTML::Mason::Exception::Params->throw
            ( error => "no value sent for required parameter '$arg'" )
                unless exists $pos{$arg};
    }
#line 3 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
    %services = HTML::Mason::Tools::coerce_to_hash( $_[ $pos{'services'} ], '%services');
}
$m->debug_hook( $m->current_comp->path ) if ( HTML::Mason::Compiler::IN_PERL_DB() );

#line 1 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '
' );
#line 5 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '
<script src="/js/source/legacy/CXGN/BreedersToolbox/UploadImages.js"></script>

' );
#line 8 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
 use JSON::Any;
$m->print( '
' );
#line 10 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp(   '/util/import_javascript.mas',
  classes => ['jquery.dataTables-buttons-min',
      'jquery.iframe-post-form',
      'jszip-min', 'pdfmake.pdfmake-min',
      'pdfmake.vfs_fonts',
      'buttons.bootstrap-min',
      'buttons.html5-min',
      'jquery',
      'jquery.cookie',
      'thickbox',
      'CXGN.BreedersToolbox.HTMLSelect',
      'd3.d3v4Min'
  ]
  
); #line 23 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '

<style>
td.details-control {
    text-align:center;
    color:forestgreen;
    cursor: pointer;
}
tr.shown td.details-control {
    text-align:center;
    color:red;
}

.bar {
  fill: steelblue;
  shape-rendering: crispEdges;
}
</style>

<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />

' );
#line 44 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp(   '/page/page_title.mas', title=>"Image Analysis"   
); #line 44 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '
<hr>

<div class="well well-sm">
    <center>
    <button class="btn btn-primary" id="upload_images_link">Upload New Images</button>
    </center>
</div>
' );
#line 52 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp(   '/breeders_toolbox/upload_images.mas'  
); #line 52 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '
' );
#line 53 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp(   '/breeders_toolbox/trial/create_spreadsheet_dialog.mas'  
); #line 53 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '

' );
#line 55 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp( { content => sub {
#line 55 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '

    <div id="image_search_form" class="well well-sm">
        <div class="form-horizontal" >
            <div class="form-group">
                <label class="col-sm-3 control-label">Select a Field Trial: </label>
                <div class="col-sm-9" >
                    <div id ="image_analysis_trial_select">
                    </div>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-6 control-label">Image descriptors (name, description, or filename): </label>
                <div class="col-sm-6" >
                    <input class="form-control" type="text" id="image_description_filename_composite" name="image_description_filename_composite" placeholder="e.g. MyImageName" />
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-6 control-label">Submitter: </label>
                <div class="col-sm-6" >
                    <input class="form-control" type="text" id="image_submitter" name="image_submitter" placeholder="e.g. JaneDoe" />
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-6 control-label">Image tag: </label>
                <div class="col-sm-6" >
                    <input class="form-control" type="text" id="image_tag" name="image_tag" placeholder="e.g. ImageTagName" />
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-6 control-label">Associated stock: </label>
                <div class="col-sm-6" >
                    <input class="form-control" type="text" id="image_stock_uniquename" name="image_stock_uniquename" placeholder="e.g. FieldPlot100" />
                </div>
            </div>
        </div>

        <center>
        <button class="btn btn-primary" id="image_search_submit" >Search</button>
        </center>
    </div>
' );
#line 96 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
} }, '/page/info_section.mas', title=>"Image Search Criteria",  collapsible => 1, collapsed=>0, subtitle => "All images may not have names, descriptions, or tags associated with them."
 );
#line 96 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '

' );
#line 98 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp( { content => sub {
#line 98 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '
    <div class="well well-sm">
        <div class="panel panel-default">
            <div class="panel-body">
                <table id="image_analysis_image_search_results" class="table table-hover table-striped">
                <thead>
                  <tr>
                    <th>Select</th>
                    <th>Image Thumbnail</th>
                    <th>Filename</th>
                    <th>Description</th>
                    <th>Submitter</th>
                    <th>Associations</th>
                    <th>Observations</th>
                    <th>Tags</th>
                </tr>
                </thead>
                </table>
            </div>
        </div>
    </div>
' );
#line 119 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
} }, '/page/info_section.mas', title=>"Image Search Results",  collapsible => 1, collapsed=>0
 );
#line 119 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '

' );
#line 121 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->comp( { content => sub {
#line 121 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '
    <div class="well well-sm">
        <div class="panel panel-default">
            <div class="panel-body">
                <div class="form-group">
                    <label class="col-sm-6 control-label">Image Analysis Service: </label>
                    <div class="col-sm-6" >
                        <select class="form-control" id="image_analysis_service_select" name="image_analysis_service_select">
                            <option value="">Select An Analysis Service:</option>

' );
#line 131 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
 foreach my $s (keys %services) {
$m->print( ' 		            <option value="' );
#line 132 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print(  $s  );
#line 132 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '">' );
#line 132 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print(  $services{$s}->{description}  );
#line 132 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '</option>
' );
#line 133 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
 }
$m->print( '
                            <!-- option value="necrosis">Necrosis(Makerere AIR Lab)</option>
                            <option value="largest_contour_percent">Necrosis Largest Contour Mask Percent</option>
                            <option value="count_contours">Count Contours</option>
                            <option value="count_sift">SIFT Feature Count</option>
                            <option value="whitefly_count">Whitefly Count (Makerere AIR Lab)</option  -->
                        </select>
                    </div>
                </div>
                <br/>
                <div class="form-group" id="image_analysis_trait_group" style="display: none;">
                    <label class="col-sm-6 control-label">Trait to be Analyzed: </label>
                    <div class="col-sm-6" >
                        <select class="form-control" id="image_analysis_trait_select" name="image_analysis_service_select"></select>
                    </div>
                </div>
                <br/><br/><br/>

                <hr>
                <center>
                <button class="btn btn-primary" id="image_analysis_submit" disabled>Submit for Analysis</button>
                </center>
                <hr>
                <div id="image_analysis_result" style="display: none;">
                    <table class="display" style="width:100%" id="image_analysis_result_table">
                        <thead>
                           <tr>
                               <th></th>
                               <th>Stock</th>
                               <th>Trait</th>
                               <th># Analyzed Images</th>
                               <th>Mean Value</th>
                           </tr>
                       </thead>
                       <caption class="well well-sm" style="caption-side: bottom;margin-top: 10px;">
                        <center> Analysis Service Details: <a id="model_metrics_link"  style="cursor: pointer;">Model Metrics</a> </center>
                       </caption>
                    </table>
                    <hr>
                    <center><button class="btn btn-primary" id="image_analysis_save_results">Save Results</button></center>
                </div>
            </div>
        </div>
    </div>

    <br/><br/>
    <div class="well well-sm">
        <div class="panel panel-default">
            <div class="panel-body">
                <div class="form-group">
                    <div class="col-sm-9">
                    <label class="col-sm-6 control-label">Image Analysis Usage </label>
                    </div>
                    <div class="col-sm-3" >
                        <label class="control-label">Date Range: </label>
                        <select class="form-control" id="usage_range_select" name="usage_range_select">
                            <option value="all">All Dates</option>
                            <option value="year">Latest Year</option>
                            <option value="month">Latest Month</option>
                            <option value="week">Latest Week</option>
                        </select>
                    </div>
                </div>
                <br/>
                <div class="form-group" id="image_analysis_usage">
                </div>
            </div>
        </div>
    </div>

    <div class="modal fade" id="modelMetricsDialog" tabindex="-1" role="dialog" aria-labelledby="modelMetricsDialog" aria-hidden="true">
      <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="modelMetricsDialogTitle">Model Metrics</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body" id="modelMetricsDialogBody">
              <table class="display" style="width:100%" id="metrics_table">
              </table>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
          </div>
        </div>
      </div>
    </div>

    <div class="modal fade" id="saveResultModal" tabindex="-1" role="dialog" aria-labelledby="saveResultModal" aria-hidden="true">
      <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="saveResultModalTitle">Image Analysis Save Status</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body" id="saveResultModalBody">
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
          </div>
        </div>
      </div>
    </div>
' );
#line 241 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
} }, '/page/info_section.mas', title=>"Image Analysis", collapsible => 1, collapsed=>0
 );
#line 241 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '

<script>

var service_traits = {
    \'necrosis\': {
        "CBSDpct|CO_334:0002078" : "Cassava",
    },
    \'largest_contour_percent\': {},
    \'count_contours\': {},
    \'count_sift\': {},
    \'whitefly_count\': {},
}

jQuery(document).ready(function(){

    jQuery(\'#model_metrics_link\').click( function() {
        jQuery(\'#modelMetricsDialog\').modal("show");
    });

    get_select_box(\'trials\', \'image_analysis_trial_select\', { \'name\' : \'html_image_analysis_trial_select\', \'id\' : \'html_image_analysis_trial_select\', \'multiple\':0, \'size\':10, \'trial_name_values\':1 });

    _load_image_search_results();

    var date_range = jQuery(\'#usage_range_select\').val();
    _load_analysis_activity_graph(date_range);

    jQuery(\'#image_search_submit\').click(function(){
        if (jQuery(\'#html_image_analysis_trial_select\').val() == \'\') {
            alert("Please select a Field Trial first!");
            return false;
        }
        _load_image_search_results();
    });

    jQuery("#image_submitter").autocomplete({
        source: \'/ajax/people/autocomplete\'
    });

    jQuery(\'#image_search_form\').keypress( function( e ) {
        var code = e.keyCode || e.which;
        if( code == 13 ) {
            jQuery(\'#image_search_submit\').click();
        }
    });

    jQuery(\'#image_analysis_image_search_results\').on( \'draw.dt\', function () {
        jQuery(\'a.image_search_group\').colorbox();
    });$

    jQuery(\'#image_analysis_service_select\').change(function() {
        var service = jQuery(\'#image_analysis_service_select\').val();
	var service_defs = JSON.parse(\'' );
#line 293 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print(  JSON::encode_json(\%services)  );
#line 293 "/home/production/cxgn/sgn/mason/tools/image_analysis.mas"
$m->print( '\');
        jQuery(\'#image_analysis_trait_select\').html(\'<option value="">Select A Trait</option>\');
        if (service) {
            jQuery(\'#working_modal\').modal(\'show\');
            // add crop and service specific trait options
            var all_traits = service_defs[service].service_traits;
            var trait_names = Object.keys(all_traits);
            // console.log("trait names", trait_names);
            var options =  [];

            jQuery.ajax({
                url: \'/brapi/v2/commoncropnames/\',
                method: \'GET\',
                success: function(response) {
                    // console.log("Retrieved crop names and they are: "+response.result.data);
//                    var supportedcrops = response.result.data;
//                    supportedcrops.forEach(function(crop) {
//		        alert("CROP = "+crop);
                        trait_names.forEach(function(name) {
//                            if (all_traits[name] == crop) {
                                // console.log("Id is "+id);
                                options.push(\'<option value="\'+ name +\'">\'+ name +\'</option>\');
//                              console.log("options: ", options);
//                            }
//                        });
			});
                    jQuery(\'#image_analysis_trait_select\').append(options);
                    jQuery(\'#image_analysis_trait_group\').show();
                    jQuery(\'#working_modal\').modal(\'hide\');
                },
                error: function(response) {
                    console.log("error retrieving crop names: "+response);
                    // just add all traits regardless of crop
                    trait_names.forEach(function(name) {
                        // console.log("Id is "+id);
                        options.push(\'<option value="\'+ name +\'">\'+ name +\'</option>\');

                    });
                    jQuery(\'#image_analysis_trait_select\').append(options);
                    jQuery(\'#image_analysis_trait_group\').show();
                    jQuery(\'#working_modal\').modal(\'hide\');
                }
            });
      }
      else {
          // hide trait select
          jQuery(\'#image_analysis_trait_group\').hide();
      }
    });

    jQuery(\'#image_analysis_trait_select\').change(function() {
        if (jQuery(\'#image_analysis_trait_select\').val()) {
            jQuery(\'#image_analysis_submit\').prop(\'disabled\', false);
        }
        else {
            jQuery(\'#image_analysis_submit\').prop(\'disabled\', true);
        }
    });

    const selected_image_ids = [];
    let submit_results;

    jQuery(\'#image_analysis_submit\').click(function(){
        jQuery(\'input[name="image_analysis_select"]\').each(function() {
            if (this.checked){
                selected_image_ids.push(this.value);
            }
        });

        if (selected_image_ids.length < 1) {
            alert(\'Please select at least one image first!\');
            return false;
        }

        var results = [];
        var progress_modal = jQuery(\'#progress_modal\');
        var progress_bar = jQuery(\'#progress_bar\');
        var image_total = selected_image_ids.length;
        var images_finished = 0;
        var current_progress = 0;
        progress_modal.modal(\'show\');
        jQuery(\'#progress_msg\').text(\'Submitting images for analysis\');

        var deferred_calls = selected_image_ids.map(function(image_id, index) {
            jQuery(\'#progress_msg\').text(\'Submitting image \'+index+\' out of \'+image_total+\' images\');
            current_progress += (1 / image_total) * 10;
            progress_bar.css("width", current_progress + "%")
            .attr("aria-valuenow", current_progress)
            .text(Math.round(current_progress) + "%");

            var call = jQuery.ajax({
                url: \'/ajax/image_analysis/submit\',
                method: \'POST\',
                data: {
                    \'selected_image_ids\': image_id,
                    \'service\': jQuery(\'#image_analysis_service_select\').val(),
                    \'trait\': jQuery(\'#image_analysis_trait_select\').val(),
                },
                dataType:\'json\',
                success: function(response) {
                    images_finished++;
                    // console.log(response);
                    jQuery(\'#progress_msg\').text(\'Responses received for \'+images_finished+\' out of \'+image_total+\' images\');
                    current_progress += (1 / image_total) * 90;
                    progress_bar.css("width", current_progress + "%")
                    .attr("aria-valuenow", current_progress)
                    .text(Math.round(current_progress) + "%");
                    response.results.map(function(item) {
                        if (item.result.error) {
                            progress_modal.find(\'.modal-footer\').append(
                                \'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error analyzing image number \'+index+\': \'+item.result.error+\'</li></ul>\'
                            );
                        }
                        else {
                        }
                        results.push(item);
                    });
                },
                error: function(response) {
                    images_finished++;
                    // console.log(response);
                    jQuery(\'#progress_msg\').text(\'Finished analyzing \'+images_finished+\' out of \'+image_total+\' images\');
                    current_progress += (1 / image_total) * 90
                    progress_modal.find(\'.modal-footer\').append(
                        \'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error analyzing image number \'+index+\': \'+response+\'</li></ul>\'
                    );
                }
            });
            return call;
        });

        jQuery(\'#progress_msg\').text(\'All \'+image_total+\' images submitted, waiting for responses.\');

        jQuery.when.apply(jQuery, deferred_calls).then(function() {
            // console.log("Results are:");
            // console.log(results);
            var first = results[0];
            submit_results = first;
            // console.log("stock type:", first.stock_type_name);

            if (first.stock_type_name === "plot") {
                alert("The image you submitted for analysis is associated with a plot. If you save these results a new plant will be created for this plot.")
            }

            let metricsData = Object.entries(first.result.analysis_info)
                .filter(([key, value]) => key != null && value != null)
                .map(([key, value]) => ({
                    metric: key,
                    value: typeof value === \'object\' ? JSON.stringify(value) : String(value)
                }));

            if (metricsData.length > 0) {
                jQuery(\'#metrics_table\').DataTable({
                    "data": metricsData,
                    "columns": [
                        { "data": "metric" },
                        { "data": "value" },
                    ]
                });
            }

            if (results.length > 0) {
                jQuery.ajax({
                    url: \'/ajax/image_analysis/group\',
                    method: \'POST\',
                    data: { \'result\': JSON.stringify(results) },
                    success: function(response) {
                        // console.log("Grouped Results are:");
                        // console.log(response);
                        current_progress = 100;
                        progress_bar.css("width", current_progress + "%")
                        .attr("aria-valuenow", current_progress)
                        .text(Math.round(current_progress) + "%");
                        jQuery(\'#progress_msg\').text(\'Building results table.\');
                        jQuery(\'#image_analysis_result\').show();

                        var table = jQuery(\'#image_analysis_result_table\').DataTable( {
                            "destroy" : true,
                            "data": response.results,
                            "dom": \'Bfrtip\',
                            "buttons":  [
                                \'copy\', \'excel\', \'csv\', \'pdf\'
                            ],
                            "columns": [
                                {
                                    "className":      \'details-control\',
                                    "orderable":      false,
                                    "data":           null,
                                    "defaultContent": \'\',
                                    "render": function () {
                                         return \'<i class="fa fa-plus-square" aria-hidden="true"></i>\';
                                     },
                                     width:"15px"
                                },
                                { "data": "observationUnitName" },
                                { "data": "observationVariableName" },
                                { "data": "numberAnalyzed" },
                                { "data": "value" }
                            ],
                            "order": [[1, \'asc\']]
                        } );

                        // Add event listener for opening and closing details
                        jQuery(\'#image_analysis_result_table tbody\').on(\'click\', \'td.details-control\', function () {
                            var tr = jQuery(this).closest(\'tr\');
                            var tdi = tr.find("i.fa");
                            var row = table.row( tr );

                            if ( row.child.isShown() ) {
                                // This row is already open - close it
                                row.child.hide();
                                tr.removeClass(\'shown\');
                                tdi.first().removeClass(\'fa-minus-square\');
                                tdi.first().addClass(\'fa-plus-square\');
                            }
                            else {
                                // Open this row
                                row.child( format(row.data()) ).show();
                                tr.addClass(\'shown\');
                                tdi.first().removeClass(\'fa-plus-square\');
                                tdi.first().addClass(\'fa-minus-square\');
                            }
                        } );

                        setTimeout(function(){
                            progress_modal.find(\'.modal-footer\').html(\'\');
                            progress_modal.modal(\'hide\');
                        }, 1000);

                    },
                    error: function(response) {
                        // jQuery(\'#working_modal\').modal(\'hide\');
                        progress_modal.modal(\'hide\');
                        console.log(\'Error: \'+response);
                        // jQuery(\'#\'+image_id).text(\'Error analyzing image number \'+index+\'. \'+response);
                        alert("An error occurred while displaying image analysis results.");
                    }
                });
            }
            else {
                progress_modal.find(\'.modal-footer\').html(\'\');
                progress_modal.modal(\'hide\');
                alert("No usable results returned from the service, aborting analysis.");                 // alert("No usable results returned from the service, aborting analysis.");
            }
        });
    });

    jQuery(\'#image_analysis_save_results\').click(function(){

        var table_data = jQuery(\'#image_analysis_result_table\').DataTable().rows().data().toArray();
        let dt = new DataTransfer();

        jQuery(\'#working_modal\').modal(\'show\');
        let plantData = [
            {
                additionalInfo: {
                    observationUnitParent: table_data[0].observationUnitDbId
                },
                observationUnitName: table_data[0].observationUnitName + "_" + selected_image_ids[0] +  "_plant",
                studyDbId: table_data[0].studyDbId, // trial ID
                germplasmDbId: table_data[0].germplasmDbId,
                observationUnitPosition: {
                    observationLevel: {
                        levelName: "plant",
                        levelCode: table_data[0].observationUnitDbId,
                        levelOrder: 4
                    },
                    positionCoordinateX: null,
                    positionCoordinateY: null,
                    observationLevelRelationships: [],
                    geoCoordinates: null
                }
            }
        ];

        let tissueSamplesData = [];
        let tissueSampleMap = {};
        let existingCreatedSamples = [];

        let plantId = table_data[0].observationUnitDbId;
        
        if (jQuery(\'#image_analysis_service_select option:selected\').text() === "Citrus Image Multi Analysis") {
            if (submit_results.stock_type_name === "plot") {
                jQuery.ajax({
                    type: \'GET\',
                    contentType: \'application/json\',
                    url: `/brapi/v2/observationunits?observationUnitName=${encodeURIComponent(plantData[0].observationUnitName)}`,
                    headers: { "Authorization": "Bearer "+jQuery.cookie("sgn_session_id") },
                    success: function(response) {
                        if (response.result.data.length > 0) {
                            plantId = response.result.data[0].observationUnitDbId;
                        } else {
                            jQuery.ajax({
                                type: \'POST\',
                                contentType: \'application/json\',
                                url: \'/brapi/v2/observationunits\',
                                headers: { "Authorization": "Bearer "+jQuery.cookie("sgn_session_id") },
                                data: JSON.stringify(plantData),
                                beforeSend: function() {
                                    jQuery(\'#working_modal\').modal(\'show\');
                                },
                                success: function(response) {
                                    if (response.result.data.length > 0) {
                                        plantId = response.result.data[0].observationUnitDbId;
                                    }                                
                                },
                                error: function(response) {
                                    jQuery(\'#working_modal\').modal(\'hide\');
                                    jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error while creating a new plant. Deets: \'+response.responseText+\'</li></ul>\');
                                    jQuery(\'#saveResultModal\').modal(\'show\');
                                }
                            });
                        }                        
                    },
                    error: function(response) {
                        jQuery(\'#working_modal\').modal(\'hide\');
                        jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error while trying to save the analysis results. Deets: \'+response.responseText+\'</li></ul>\');
                        jQuery(\'#saveResultModal\').modal(\'show\');
                    }
                })
            } 

            const fileData = {};
            let imageFiles;
            let imageData;

            table_data.forEach(function(row) {
                let plotId = row.observationUnitDbId;
                let studyDbId = row.studyDbId;
                let germplasmName = plantData[0].observationUnitName;
                let accessionId = table_data[0].germplasmDbId;
                //const imageId = selected_image_ids[0].toString();

                row.details.forEach(function(detail, i) {
                    let sampleNumber = parseInt(detail.sample_num) + 1 + i;
                    let sampleName = submit_results.result.trait_id + \'_\' + germplasmName + \'_\' + \'sample\' + sampleNumber;
                    let proxyUrl = "/get_image_file?url=" + encodeURIComponent(detail.analyzed_link);
                    

                    fetch(proxyUrl)
                        .then(response => {
                            if (!response.ok) throw new Error("Failed to fetch " + proxyUrl);
                            return response.blob();
                        })
                        .then(blob => {
                            let filename = sampleName + ".png";
                            let file = new File([blob], filename, {type: blob.type || "image/png" });
                            dt.items.add(file);

                            document.getElementById(\'upload_images_file_input\').files = dt.files;
                            imageFiles = document.getElementById(\'upload_images_file_input\').files;

                            fileData[file.name] = {
                                "imageFileName": file.name,
                                "imageFileSize": file.size,
                                "mimeType": file.type
                            };
                        })
                        .catch(err => console.error(err));

                    tissueSamplesData.push(
                        {
                            additionalInfo: {
                                observationUnitParent: plantId
                            },
                            observationUnitName: sampleName,
                            studyDbId: studyDbId,
                            germplasmDbId: accessionId,
                            observationUnitPosition: {
                                observationLevel: {
                                    levelName: "tissue_sample",
                                    levelCode: "tissue_sameple" + sampleNumber,
                                    levelOrder: 4
                                },
                                observationLevelRelationships: [
                                    {
                                        levelName: "plant",
                                        observationUnitDbId: plantId,
                                        levelOrder: 4
                                    }
                                ],
                                positionCoordinateX: null,
                                positionCoordinateY: null,
                                geoCoordinates: null
                            }
                        }
                    )

                    tissueSampleMap[sampleName] = detail.value;
                })
            })

            // Add observations to existing samples if analysis has been run on current image before
            if (table_data[0].image_analyzed == 1) {
                getOrCreateSamples(tissueSamplesData).then(sampleData => {
                    //console.log("samples data", sampleData);

                    const observationData = [];
                    for (const sampleId of Object.keys(sampleData)) {
                        observationData.push({
                            //additionalInfo: { observationUnitParent: plantId },
                            collector: table_data[0].collector,
                            observationUnitDbId: sampleId,
                            observationVariableDbId: table_data[0].observationVariableDbId,
                            observationVariableName: table_data[0].observationVariableName,
                            observationTimeStamp: table_data[0].observationTimeStamp,
                            value: tissueSampleMap[sampleData[sampleId]]
                        });
                    }

                    // console.log("observation json", JSON.stringify(observationData));

                    jQuery.ajax({
                        type: \'POST\',
                        contentType: \'application/json\',
                        url: \'/brapi/v2/observations\',
                        headers: { "Authorization": "Bearer " + jQuery.cookie("sgn_session_id") },
                        data: JSON.stringify(observationData),
                        success: function (obsResponse) {
                            jQuery(\'#working_modal\').modal(\'hide\');
                            jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-success"><span class="badge"><span class="glyphicon glyphicon-ok"></span></span>Analysis results saved successfully in the database.</li></ul>\');
                            jQuery(\'#saveResultModal\').modal(\'show\');
                        },
                        error: function (err) {
                            console.error("Error saving observations", err.responseText);
                        }
                    });
                });
            } else {
                jQuery.ajax({
                    type: \'POST\',
                    contentType: \'application/json\',
                    url: \'/brapi/v2/observationunits\',
                    headers: { "Authorization": "Bearer "+jQuery.cookie("sgn_session_id") },
                    data: JSON.stringify(tissueSamplesData),
                    success: function(response) {
                        const observationUnitDbIdsMap = {};
                        response.result.data.forEach(unit => {
                            observationUnitDbIdsMap[unit.observationUnitName] = unit.observationUnitDbId;
                        });

                        imageData = Object.values(fileData).map(file => {
                            const sampleName = file.imageFileName.replace(/\\.[^/.]+$/, "");
                            file.observationUnitDbId = observationUnitDbIdsMap[sampleName];
                            return file;
                        });

                        const observationData = [];

                        response.result.data.forEach(unit => {
                            observationData.push(
                                {
                                    collector: table_data[0].collector,
                                    observationUnitDbId: unit.observationUnitDbId,
                                    observationVariableDbId: table_data[0].observationVariableDbId,
                                    observationVariableName: table_data[0].observationVariableName,
                                    observationTimeStamp: table_data[0].observationTimeStamp,
                                    value: tissueSampleMap[unit.observationUnitName]
                                }
                            )
                        })

                        jQuery.ajax({
                            type: \'POST\',
                            contentType: \'application/json\',
                            url: \'/brapi/v2/observations\',
                            headers: { "Authorization": "Bearer "+jQuery.cookie("sgn_session_id") },
                            data: JSON.stringify(observationData),
                            success: function(obsResponse) {    
                                loadAllImages(imageFiles, imageData).then(function(uploadStatus) {
                                    console.log("Upload completed!");
                                    jQuery(\'#working_modal\').modal(\'hide\');
                                    jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-success"><span class="badge"><span class="glyphicon glyphicon-ok"></span></span>Analysis results saved successfully in the database.</li></ul>\');
                                    jQuery(\'#saveResultModal\').modal(\'show\');
                                });
                                
                            },
                            error: function(response) {
                                jQuery(\'#working_modal\').modal(\'hide\');
                                jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error while trying to save the analysis results. Deets: \'+response.responseText+\'</li></ul>\');
                                jQuery(\'#saveResultModal\').modal(\'show\');
                            }
                        })
                    },
                    error: function(response) {
                        jQuery(\'#working_modal\').modal(\'hide\');
                        jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error while trying to save the analysis results. Deets: \'+response.responseText+\'</li></ul>\');
                        jQuery(\'#saveResultModal\').modal(\'show\');
                    }
                });
            }
        } else if (jQuery(\'#image_analysis_service_select option:selected\').text() === "Citrus Image Analysis") {
            table_data[0].observationUnitDbId = plantId;
            jQuery.ajax({
            url: \'/brapi/v2/observations/\',
            method: \'POST\',
            headers: { "Authorization": "Bearer "+jQuery.cookie("sgn_session_id") },
            data: JSON.stringify(table_data),
            contentType: "application/json; charset=utf-8",
            beforeSend: function() {
                jQuery(\'#working_modal\').modal(\'show\');
            },
            success: function(response) {
                // console.log(response);
                jQuery(\'#working_modal\').modal(\'hide\');
                jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-success"><span class="badge"><span class="glyphicon glyphicon-ok"></span></span>Analysis results saved successfully in the database.</li></ul>\');
                jQuery(\'#saveResultModal\').modal(\'show\');
            },
            error: function(response) {
                // console.log(response);
                jQuery(\'#working_modal\').modal(\'hide\');
                jQuery(\'#saveResultModalBody\').html(\'<ul class="list-group"><li class="list-group-item list-group-item-danger"><span class="badge"><span class="glyphicon glyphicon-remove"></span></span>Error while trying to save the analysis results. Deets: \'+response.responseText+\'</li></ul>\');
                jQuery(\'#saveResultModal\').modal(\'show\');
            }
        });
        }
        
    });

});

function getOrCreateSamples(sampleData) {
    const existingSamples = {};
    const requests = sampleData.map(sample => {
        return new Promise((resolve, reject) => {
            jQuery.ajax({
                url: `/brapi/v2/observationunits?observationUnitName=${encodeURIComponent(sample.observationUnitName)}`,
                method: \'GET\',
                headers: { "Authorization": "Bearer " + jQuery.cookie("sgn_session_id") },
                success: function (response) {
                    if (response.result.data.length > 0) {
                        existingSamples[response.result.data[0].observationUnitDbId] = response.result.data[0].observationUnitName;
                        resolve();
                    } else {
                        jQuery.ajax({
                            type: \'POST\',
                            url: \'/brapi/v2/observationunits\',
                            headers: { "Authorization": "Bearer " + jQuery.cookie("sgn_session_id") },
                            contentType: \'application/json\',
                            data: JSON.stringify([sample]),
                            success: function (sampleResp) {
                                existingSamples[sampleResp.result.data[0].observationUnitDbId] =
                                    sampleResp.result.data[0].observationUnitName;
                                resolve();
                            },
                            error: reject
                        });
                    }
                },
                error: reject
            });
        });
    });

    return Promise.all(requests).then(() => existingSamples);
}

function _load_image_search_results() {
    images_table = jQuery(\'#image_analysis_image_search_results\').DataTable({
        \'destroy\' : true,
        \'searching\' : false,
        \'ordering\'  : false,
        \'processing\': true,
        \'serverSide\': true,
        \'scrollX\': true,
        \'lengthMenu\': [10,20,50,100,1000,5000],
        \'ajax\': { \'url\':  \'/ajax/search/images\',
            \'method\': \'POST\',
            \'data\': function(d) {
              d.html_select_box = "image_analysis_select";
              d.image_description_filename_composite = jQuery(\'#image_description_filename_composite\').val();
              d.image_person = jQuery(\'#image_submitter\').val();
              d.image_tag = jQuery(\'#image_tag\').val();
              d.image_stock_uniquename = jQuery(\'#image_stock_uniquename\').val();
              d.image_project_name = jQuery(\'#html_image_analysis_trial_select\').val();
            }
        }
    });
}

function _load_analysis_activity_graph(date_range) {

    d3.json(\'/ajax/image_analysis/activity\', function(error, response) {

        if (response.activity) {
            var activity = JSON.parse(response.activity);
            // console.log("Activity array is: ");
            // console.log(activity);

            // Iterate through each data point and parse date strings into dates
            var parseTime = d3.timeParse("%Y-%m-%d");
            var data = [];

            jQuery.each(activity, function (index, element) {
                data.push({
                    \'date\': parseTime(element.date)
                })
            });

            // Set canvas margins
            var margin = {top: 20, right: 50, bottom: 30, left: 50};
            var width = 800 - margin.left - margin.right;
            var height = 500 - margin.top - margin.bottom;

            // Create svg object
            var svg = d3.select(\'#image_analysis_usage\').append(\'svg\')
                .attr(\'width\', width + margin.left + margin.right)
                .attr(\'height\', height + margin.top + margin.bottom)
                .append(\'g\')
                .attr(\'transform\', `translate(${margin.left}, ${margin.top})`);

            // Set x (timeseries) and y (linear) scales
            var xScale = d3.scaleTime().range([0, width]);
            var yScale = d3.scaleLinear().range([height, 0]);

           var dayExtent = d3.extent(data, function (d) { return d.date; });

           console.log("day extent is "+dayExtent);

           // Create one bin per day, use an offset to include the first and last days
           var dayBins = d3.timeDays(d3.timeDay.offset(dayExtent[0],-1),
                                     d3.timeDay.offset(dayExtent[1], 1));

           var x = d3.scaleTime()
               .domain(dayExtent)
               .rangeRound([0, width]);

           // Scale the range of the data in the y domain
           var y = d3.scaleLinear()
                      .range([height, 0]);

           var xAxis = d3.axisBottom(x)
                          .tickArguments([d3.timeDay.every(1)])
                          .tickFormat(d3.timeFormat(\'%d-%b\'))
                          .ticks(10);

           // Set the parameters for the histogram
           var histogram = d3.histogram()
                              .value(function(d) { return d.date; })
                              .domain(x.domain())
                              .thresholds(x.ticks(dayBins.length));


           // Group the data for the bars
           var bins = histogram(data);

           y.domain([0, d3.max(bins, function(d) { return d.length; })]);

           var hist = svg.selectAll("rect")
                .data(bins)
                .enter().append("rect")
                .attr("class", "bar")
                .attr("x", 1)
                .attr("transform", function(d) {
                   return "translate(" + x(d.x0) + "," + y(d.length) + ")";
                })
                .attr("width", function(d) {
                   return x(d.x1) - x(d.x0) -1 ;
                })
                .attr("height", function(d) {
                   return height - y(d.length);
                });

           // Add the x axis
           svg.append("g")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis)

           // Add the y axis
           svg.append("g")
                // .call(d3.axisLeft(y).ticks(d3.max(bins, function(d) { return d.length; })))
                .call(d3.axisLeft(y).ticks(15))
                .append("text")
                .attr("fill", "#000")
                .attr("transform", "rotate(-90)")
                .attr("y", 0 - margin.left)
                .attr("x",0 - (height / 2))
                .attr("dy", "1em")
                .style("text-anchor", "middle")
                .text("Number of Images Analyzed");
        } else {
            document.getElementById(\'image_analysis_usage\').innerHTML += \'<center>No image analysis usage data found.</center>\';
        }

    });
}

function format ( d ) {
    var detail_rows = \'\';
    d.details.forEach(function (image, index) {
        var result = image.analyzed_link;
        var text;
        if (result.startsWith("Error: ")) {
            text = result;
        } else {
            text = \'<img src="\'+result+\'" width="100">\';
        }
        detail_rows +=
        `<tr>
          <td>`+image.image_name+`</td>
          <td>`+text+`</td>
          <td>`+image.value+`</td>
        </tr>`
    });

return `<table class="table">
            <thead>
                <tr>
                  <th scope="col">Image Name</th>
                  <th scope="col">Analyzed Image</th>
                  <th scope="col">Value</th>
                </tr>
             </thead>
             <tbody>` + detail_rows + `</tbody>
        </table>`;

}

</script>
' );
;return;
},
'declared_args' => {
  '%services' => { default => undef }
},
'load_time' => 1763180757,

)
;