package CalReserv;
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
#
#Bike calendar-reservation
#
use strict;
use warnings;
use POSIX;
use CGI ':standard';
use Scalar::Util qw(looks_like_number);
use JSON;
use DateTime;
use DateTime::Format::Strptime;
use DateTime::Format::Pg;
use LWP::UserAgent;
use Mod::Basework;
use Mod::DBtank;
use Mod::Buttons;
use Tpl::AccountSubmenu;
use Data::Dumper;

my $bw = new Basework;
my $dbt = new DBtank;

sub new {
 my $class = shift;
 my $self = {};
 bless($self,$class);
 return $self;
}


#api workaround reserving bike by post request
sub bike_reservreq {
 my $self = shift;
 my $uri_server = shift;
 my $booking_request = shift;

 my $booking_json = $self->fetchserver_json($uri_server,$booking_request);
 my $response_booking = {};
 eval {
   $response_booking = decode_json($booking_json);
   $bw->log("CalendarReserv booking_json response",$response_booking,"");
 };
 if ($@){
   $bw->log("Failure, CalendarReserv booking_json not valid","","");
   warn $@;
 }

 return $response_booking;
}

sub tpl {
 my $self = shift;
 my $q = shift;
 my $node_meta = shift;
 my $users_dms = shift || "";
 my $varenv = shift;
 my $users_sharee = shift || "";
 my $feedb = shift || "";

 my $but = new Buttons;
 my $submenu = new AccountSubmenu;
 my $path = $q->path_info();
 my $dbh = "";
 my $red = "#c83434";

 my $coo = $q->cookie(-name=>'domcookie') || $R::sessionid;
 my $session="";
 my $session_and="";
 if($R::sessionid && length($R::sessionid) > 20 && !$q->cookie(-name=>'domcookie')){
        $session = "?sessionid=$R::sessionid";
        $session_and = "&sessionid=$R::sessionid";
 }
 my $select_station = $q->escapeHTML($R::select_station) || "LatLng(47.976634, 7.82549)";#defaults to Villaban
 my $bike = $q->escapeHTML($R::bike_reserv) || "";
 my $bgcolor1 = "009899";#sharee
 $bgcolor1 = $dbt->{website}->{$varenv->{syshost}}->{bgcolor1} if($dbt->{website}->{$varenv->{syshost}}->{bgcolor1});
 $bgcolor1 = $dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1} if($dbt->{merchant_ids}->{$varenv->{merchant_id}}->{bgcolor1});
 my $initMap = "47.976634, 7.825490";#Freiburg
 my $map_zoom = 10;
 my $project = "all";
 my $uri_server = $dbt->{primary}->{sharee_primary}->{primaryApp};

 my $timestamp = DateTime->now( time_zone => "Europe/Berlin" );
 my $dt0 = DateTime->now( time_zone => "Europe/Berlin" );
 my $dt1 = DateTime->now( time_zone => "Europe/Berlin" );
 my $strp = DateTime::Format::Strptime->new(    
    pattern   => '%Y-%m-%dT%H:%M',
    locale    => 'de_DE',
    time_zone => 'Europe/Berlin',
    on_error  => 'croak',
 );

 my $reserv_starttime = $R::reserv_starttime || "";
 my $reserv_endtime = $R::reserv_endtime || "";

 if($reserv_starttime && $reserv_starttime =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/){
   $dt0 = $strp->parse_datetime($reserv_starttime);
   $reserv_starttime = $dt0->datetime;
 }
 if($reserv_endtime && $reserv_endtime =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/){
   $dt1 = $strp->parse_datetime($reserv_endtime);
   $reserv_endtime = $dt1->datetime;
 }

 if($dt0 < $timestamp){
   $dt0 = $strp->parse_datetime($timestamp);
   $reserv_starttime = $dt0->datetime;
   $reserv_starttime =~ s/:00$//;
   $dt1 = $strp->parse_datetime($timestamp);
   $dt1->add( hours => 4);
   $reserv_endtime = $dt1->datetime;
   $reserv_endtime =~ s/:00$//;
 }

 if(!$reserv_starttime || $reserv_starttime !~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/){
   $dt0 = $strp->parse_datetime($timestamp);
   $reserv_starttime = $dt0->datetime;
   $reserv_starttime =~ s/:00$//;
 }

 if(!$reserv_endtime || $reserv_endtime !~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/){
   $dt1 = $strp->parse_datetime($timestamp);
   $dt1->add( hours => 3);
   $reserv_endtime = $dt1->datetime;
   $reserv_endtime =~ s/:00$//;
 }

 print "<div id='Contentapp'>\n";

 #subMenue--------
  $submenu->tpl($node_meta,$users_dms,$varenv,$users_sharee,$feedb);
 #-----------------

 print $q->start_form(-name=>'calreservscreen', -action=>""),"\n";
 print $q->hidden(-name=>"sessionid",-override=>1,-value=>"$R::sessionid") if($R::sessionid);
 print $q->hidden(-name=>"calreserv",-override=>1,-value=>"1");#to get uri_operator by GBFSout


 #Station select by map
  my $icon_green = "Open_Green.png";
  my $icon_red = "Open_Red.png";
  my $icon_blue = "Open_Blue.png";
  $initMap =~ s/\s//g;
  my ($lat,$lng) = split(/,/,$initMap);
  if($select_station && $select_station =~ /LatLng\((\d+\.\d+),\s(\d+\.\d+)\)/){
    $lat = $1;
    $lng = $2;
  }else{
    
  }

print<<EOF
<link rel="stylesheet" href="https://unpkg.com/leaflet\@1.8.0/dist/leaflet.css"
   integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ=="
   crossorigin=""/>

<script src="https://unpkg.com/leaflet\@1.8.0/dist/leaflet.js"
   integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
   crossorigin=""></script>

<style>
  #map { 
   height: 250px; 
   width: 100%;
  }
</style>

EOF
;

print $q->div({-class=>'content_title3',-style=>''}, "$varenv->{cms}->{'iframe-calendar-reserv-intro'}->{txt}"),"\n";
#print $q->div({-style=>'padding:10px 0;'},"<b>Mietrad Reservierung</b>. Radstation in Karte auswählen, Fahrtbeginn und Fahrtende einstellen und verfügbares Mietrad buchen."),"\n";
print $q->div({-id=>"geolocatestate"},""),"\n";

print "<div style='margin:5px 0 15px; 0' id='map'></div>\n";

 #print $q->div({-style=>'padding:15px 0;'},$q->b("Mietradstation: "),$q->span({-id=>"station_selected"},"")),"\n";
 #with Station select $stations_json 
 my $list_options = "";
 my %gbfs_station = ();
 my %selected_station = ();
 if(1==1){
   my $rest_stations = "request=stations_available&calreserv=1&authcookie=$coo";
   my $stations_json = $self->fetchserver_json($uri_server,$rest_stations);
   eval {
     my $response_stations = {};
     $response_stations = decode_json($stations_json);

     foreach my $station (sort {$response_stations->{shareejson}->{stations}->{$a}->{station}  cmp $response_stations->{shareejson}->{stations}->{$b}->{station} } keys (%{ $response_stations->{shareejson}->{stations} })) {
        #print Dumper($response_stations->{shareejson}->{stations}->{$station});
	$response_stations->{shareejson}->{stations}->{$station}->{gps}->{latitude} =~ s/0$//g;
	$response_stations->{shareejson}->{stations}->{$station}->{gps}->{longitude} =~ s/0$//g;
	$gbfs_station{$station}{LatLng} = "LatLng($response_stations->{shareejson}->{stations}->{$station}->{gps}->{latitude}, $response_stations->{shareejson}->{stations}->{$station}->{gps}->{longitude})";
        $gbfs_station{$station}{name} = Encode::encode('utf-8', Encode::decode('iso-8859-1',$response_stations->{shareejson}->{stations}->{$station}->{description}));
        $gbfs_station{$station}{station_id} = $response_stations->{shareejson}->{stations}->{$station}->{station};
	if($select_station && $select_station eq $gbfs_station{$station}{LatLng}){
          $selected_station{uri_operator} = $response_stations->{shareejson}->{stations}->{$station}->{uri_operator};
          $selected_station{name} = $gbfs_station{$station}{name};
          $selected_station{station_id} = $gbfs_station{$station}{station_id};
          $list_options .= "<option value='$gbfs_station{$station}{LatLng}' selected>$gbfs_station{$station}{name} | $gbfs_station{$station}{station_id}</option>\n";
	}else{
          $list_options .= "<option value='$gbfs_station{$station}{LatLng}'>$gbfs_station{$station}{name} | $gbfs_station{$station}{station_id}</option>\n";
	}
     }
   };
   if ($@){
     $bw->log("Failure, CalendarReserv station_information not valid","","");
     warn $@;
   }

   print $q->label({-for=>'select_station', -class=>'form-label'},"<b>Mietradstation</b>"),"\n";
   print "<div class='input-group mb-3'>\n";
   #print $q->span({-class=>"input-group-text bi bi-record-circle", -style=>"font-size: 1.5rem;width:3rem;"},""),"\n";
   #print $q->input({-id=>'select_station', -name=>'select_station', -type=>'text', -list=>'list-stations', -class=>'form-control', -style=>'max-width:500px;font-weight:bold;', -placeholder=>'Ort oder Stationname', -override=>1},""),"\n";
   print "<select id='select_station' name='select_station' class='form-control' style='max-width:500px;' placeholder='Station Auswahl' override>";
   print "<datalist id='list-stations'>\n";
   print "$list_options\n";
   print "</datalist>\n";
   print "</select >";
   #print $q->input({-type=>'reset',-value=>'Reset'},""),"\n";
   print "</div>\n";
 }
 #end with Station select $stations_json 
 
print "<script src='$varenv->{metahost}/js/rentalator.js' type='text/JAVASCRIPT'></script>"; 

print<<EOF
 <script>
 //document.getElementById('select_station').value = 'LatLng(47.976634, 7.825490)';

 var map = L.map('map', { scrollWheelZoom: false }).setView([$lat, $lng], $map_zoom);

  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

var icon_green = L.icon({
    iconUrl: '$varenv->{metahost}/img/$icon_green',
    iconSize: [37, 37],
    iconAnchor: [20, 37],
    popupAnchor: [-2, -36]
    //shadowUrl: 'marker-shadow.png',
    //shadowSize: [68, 95],
    //shadowAnchor: [22, 94]
});
var icon_red = L.icon({
    iconUrl: '$varenv->{metahost}/img/$icon_red',
    iconSize: [37, 37],
    iconAnchor: [20, 37],
    popupAnchor: [-2, -36]
});

//Only stations with bike_count
Promise.all([
  fetch(
    "$uri_server/GBFSout?request=stations_available&calreserv=1&authcookie=$coo"
  )]).then(async ([response1]) => {
  const responseData1 = await response1.json();

  const data1 = responseData1.data.stations;

 const layerGroup = L.featureGroup().addTo(map);
  data1.forEach(({ lat, lon, name, bike_count, uri_operator, station_id: stationId }) => {
    console.log('Station: ' + stationId , name, bike_count);

     layerGroup.addLayer(
      //L.marker([lat, lon], { icon:icon_green }).bindPopup(`<b>Station: \${name} \${stationId} </b><br />\${lat},\${lon}`).on('click', clickedGPS)
      L.marker([lat, lon], { icon:icon_green }).bindPopup(`<b>Station</b> \${name} \${stationId}`).on('click', clickedGPS)
     );

  });

  //disabled to setView on current location
  //map.fitBounds(layerGroup.getBounds());
});

function clickedGPS(e) {
    const select_station = document.querySelector('#select_station');
    select_station.value = e.latlng
    //station_selected.textContent = 'FR101'
    console.log('clickedGPS:' + select_station.value);
}

function onLocationFound(e) {
    console.log('onLocationFound:' + e.latlng);
    const geolocatestate = document.querySelector('#geolocatestate');
    var radius = e.accuracy;

    //L.marker(e.latlng).addTo(map).bindPopup("You are within " + radius + " meters from this point").openPopup();
    L.circle(e.latlng, radius).addTo(map);
    geolocatestate.textContent = 'Stationen in Umgebung';
}


function onLocationError(e) {
    //alert(e.message);
}

function lastLocation() {
    var latlng = L.latLng($lat, $lng);
    console.log('lastLocation:' + latlng);
    const geolocatestate = document.querySelector('#geolocatestate');
    var radius = 5000;

    L.marker(latlng, { icon:icon_green }).addTo(map).bindPopup(`<b>Station</b> $selected_station{name} | $selected_station{station_id}`).openPopup();
    L.circle(latlng, radius).addTo(map);
    geolocatestate.textContent = 'Station nach Auswahl';
}


if("$select_station"){
  map.on('locationfound', lastLocation);
  map.locate({setView: false, maxZoom: 16});
  map.setView(L.latLng($lat, $lng), 11);
}else{
  map.on('locationfound', onLocationFound);
  map.on('locationerror', onLocationError);
  map.locate({setView: true, maxZoom: 16});
}

    </script>
EOF
;

 #end Station select by map

 #if(!$bike){
   print "<div class='mb-3'>\n";
   print $q->label({-for=>'reserv_starttime', -class=>'form-label'},"Fahrtbeginn"),"\n";
   print $q->input({-id=>'reserv_starttime', -name=>'reserv_starttime',-type=>'datetime-local', -class=>'form-control', -style=>'max-width:230px;', -value=>"$reserv_starttime", -override=>1},""),"\n";
   print $q->label({-for=>'reserv_endtime', -class=>'form-label', -style=>'padding-top:1em;'},"Fahrtende"),"\n";
   print $q->input({-id=>'reserv_endtime', -name=>'reserv_endtime',-type=>'datetime-local', -class=>'form-control', -style=>'max-width:230px;', -value=>"$reserv_endtime", override=>1},""),"\n";
   print "</div>\n";
  #}

  if(1==2){
   print $q->div({-class=>"accordion bi bi-caret-down"}, "mehr Filter anzeigen"),"\n";
   print "<div class='panel'>\n";

   print "<div class='form-check' style='float:left;padding-right:15px;'>\n";
   my $ecargo_checked = "checked";
   $ecargo_checked = "" if($R::sharee_edit && !$R::ecargo);
   print "<input class='form-check-input' type='checkbox' name='ecargo' value='1' id='ecargo' $ecargo_checked>\n";
   print $q->label({-class=>"form-check-label", -for=>"ecargo",-style=>'padding-top:5px;'},"E-Lastenrad"),"\n";
   print "</div>\n";
   print "<div class='form-check' style='float:left;padding-right:15px;'>\n";
   my $cargo_checked = "checked";
   $cargo_checked = "" if($R::sharee_edit && !$R::cargo);
   print "<input class='form-check-input' type='checkbox' name='cargo' value='1' id='cargo' $cargo_checked>\n";
   print $q->label({-class=>"form-check-label", -for=>"cargo",-style=>'padding-top:5px;'},"Lastenrad"),"\n";
   print "</div>\n";
   print "<div class='form-check' style='float:left;padding-right:15px;'>\n";
   my $city_checked = "checked";
   $city_checked = "" if($R::sharee_edit && !$R::city);
   print "<input class='form-check-input' type='checkbox' name='city' value='1' id='city' $city_checked>\n";
   print $q->label({-class=>"form-check-label", -for=>"city",-style=>'padding-top:5px;'},"Stadtrad"),"\n";
   print "</div>\n";

  print "</div>\n";
 }

 #if($R::sharee_edit =~ /calendar_bikes_available/ && $bike){
 #  print $q->div({-style=>'margin:1em 0;text-align:center;clear:both;'},"<button type='submit' name='sharee_edit' value='calendar_bikes_available' class='btn btn-primary btn-block' style='border:1px solid #$bgcolor1;'>Fahrtzeit übernehmen</button>"),"\n";
 #  print $q->hidden(-name=>"bike",-override=>1,-value=>"$bike");
 #}
 my $but_search = "Mieträder anzeigen";
 #$but_search = "Erneut suchen" if(($R::sharee_edit && $R::sharee_edit =~ /calendar_bikes_available/) || $R::bike_reserv);
 print $q->div({-style=>'margin:1em 0;text-align:center;clear:both;'},"<button type='submit' name='sharee_edit' value='calendar_bikes_available_all' class='btn btn-primary btn-block' style='border:1px solid #$bgcolor1;'>$but_search</button>"),"\n";

 print $q->div({-id=>'reserved_bikes'},""),"\n";#not used

 #$bikes_json
  if(($R::sharee_edit && $R::sharee_edit =~ /calendar_bikes_available/) || $R::bike_reserv){

   my $rest_bikes = "request=bikes_available&calreserv=1&reserv_starttime=$R::reserv_starttime&reserv_endtime=$R::reserv_endtime&authcookie=$coo&lang=de";
   $rest_bikes .= "&station=$selected_station{station_id}" if($selected_station{station_id});

   if($select_station && $select_station =~/LatLng\((\d+\.\d+), (\d+\.\d+)\)/){
     my $Lat = $1;
     my $Lng = $2;
     $rest_bikes .= "&Lat=$Lat&Lng=$Lng";
     $uri_server = $selected_station{uri_operator} if($selected_station{uri_operator});
   }
   my $list_title = "Mieträder an Station:";
   if($R::sharee_edit ne "calendar_bikes_available_all" && $bike){
     $list_title = "Mietrad an Station:";
     $rest_bikes .= "&bike=$bike";
   }

   #api workaround reserving bike by post v3
   my $response_booking = {};
   if($R::bike_reserv){
     my $booking_request = "request=booking_request&bike=$bike&calreserv=1&reserv_starttime=$reserv_starttime&reserv_endtime=$reserv_endtime&authcookie=$coo";
     $response_booking = $self->bike_reservreq($uri_server,$booking_request);
   }

   my $bikes_json = $self->fetchserver_json($uri_server,$rest_bikes);
   eval {
     my $response_bikes = {};
     $response_bikes = decode_json($bikes_json);

     #bikes available
     print $q->div({-style=>'font-weight:bold;'},"$selected_station{name} | $selected_station{station_id}"),"\n" if(1 == 1);
     foreach my $bike (sort {$response_bikes->{shareejson}->{bikes}->{$a}->{bike}  cmp $response_bikes->{shareejson}->{bikes}->{$b}->{bike} } keys (%{ $response_bikes->{shareejson}->{bikes} })) {

	#print "<div style='border:1px solid #$bgcolor1;margin:1em 0;max-width:550px;'>\n";
	print $q->div({-style=>'padding:0.1em 0;margin:0.5em 0;background-color:#b6b6b6;'},""),"\n";
	my $bike_image = "bike_Cargo_SoleHumanPowered_Two.png";
	$bike_image = "bike_Cargo_SoleHumanPowered_Trike.png" if($response_bikes->{shareejson}->{bikes}->{$bike}->{bike_type}->{category} eq "cargo" && $response_bikes->{shareejson}->{bikes}->{$bike}->{bike_type}->{wheels} eq "3");
	$bike_image = "bike_Cargo_Pedelec_Two.png" if($response_bikes->{shareejson}->{bikes}->{$bike}->{bike_type}->{category} eq "cargo" && $response_bikes->{shareejson}->{bikes}->{$bike}->{bike_type}->{engine});
	$bike_image = "bike_City_SoleHumanPowered_Two.png" if($response_bikes->{shareejson}->{bikes}->{$bike}->{bike_type}->{category} eq "city");

        print $q->div({-style=>'padding:0.5em;float:left;'},$q->img({-style=>'width:100px;', -src=>"$varenv->{metahost}/img/$bike_image"})),"\n";
	print $q->div({-style=>'padding:0.5em;'},$q->span({-style=>'font-weight:bold;'},"$response_bikes->{shareejson}->{bikes}->{$bike}->{description} "),"$response_bikes->{shareejson}->{bikes}->{$bike}->{bike}"),"\n";
 
     	  if($response_booking->{shareejson}->{response_text}){
	    my $dts = $strp->parse_datetime($reserv_starttime);
	    my $start_loc = $dts->strftime("%d.%m.%Y %H:%M");
	    my $dte = $strp->parse_datetime($reserv_endtime);
	    my $end_loc = $dte->strftime("%d.%m.%Y %H:%M");
	    print $q->div({-style=>''},"Beginn: $start_loc"),"\n";
	    print $q->div({-style=>''},"Ende:&nbsp;&nbsp;&nbsp; $end_loc"),"\n";
	    #print $q->div({-id=>"return_state_$bike",-style=>'color:green;'},""),"\n";
	  
      	    my $reserve_style = "color:green;";
       	    $reserve_style = "color:red;" if($response_booking->{shareejson}->{response_state} =~ /Failure/);
       	    print $q->div({-style=>"$reserve_style"},"$response_booking->{shareejson}->{response_text}"),"\n";
     	  }

	  #collect timerange
	  my $set_starttime = "";
	  my $set_endtime = "";
	  my $j = 0;
	  my $dt2 = DateTime->now(time_zone => "Europe/Berlin");
	  my $dt3 = DateTime->now(time_zone => "Europe/Berlin");
   	  my $dtnow = $strp->parse_datetime($timestamp);
	  $dtnow->add( minutes => 1);
          $set_starttime = $dtnow->datetime;

	  my %blockedhash = ();
	  my %reservedhash = ();
	  my $sb = 100;#start blockedhash index . 1
	  my $eb = 100;#end blockedhash index . 2
	  my $sr = 100;#start reservedhash index . 1
	  my $er = 100;#end reservedhash index . 2
	  $blockedhash{$sb . '1'} = $set_starttime;
     	  foreach my $rid (sort {$response_bikes->{shareejson}->{bikes}->{$bike}->{blocked}->{$a}->{start_time} cmp $response_bikes->{shareejson}->{bikes}->{$bike}->{blocked}->{$b}->{start_time} } keys (%{ $response_bikes->{shareejson}->{bikes}->{$bike}->{blocked} })) {
	      $j++;
	      $dt2 = DateTime::Format::Pg->parse_datetime($response_bikes->{shareejson}->{bikes}->{$bike}->{blocked}->{$rid}->{start_time});
	      $sr++;
	      $er++;

	      if($j==1){
	       $dt3 = DateTime::Format::Pg->parse_datetime($response_bikes->{shareejson}->{bikes}->{$bike}->{blocked}->{$rid}->{end_time});
	      }

	      if($j==1 && $dtnow < $dt3){
                $set_endtime = $dt2->datetime;
	  	$reservedhash{$sr . '1'} = $set_endtime;#reserv start_time
	  	$reservedhash{$er . '2'} = $set_starttime;#reserv end_time
		$dt3->add( minutes => 15);
                $set_starttime = $dt3->datetime;
	  	$blockedhash{$sb . '1'} = $set_starttime;
	      }else{
            	my $dt0 = DateTime::Format::Pg->parse_datetime($response_bikes->{shareejson}->{bikes}->{$bike}->{blocked}->{$rid}->{start_time});
		my $dtend = $strp->parse_datetime($dt0);
                $set_endtime = $dtend->datetime;
	  	$reservedhash{$sr . '1'} = $set_endtime;#reserv start_time
	  	$blockedhash{$eb . '2'} = $set_endtime;#blocked end_time

            	my $dt1 = DateTime::Format::Pg->parse_datetime($response_bikes->{shareejson}->{bikes}->{$bike}->{blocked}->{$rid}->{end_time});
		my $dtstart = $strp->parse_datetime($dt1);
                $set_starttime = $dtstart->datetime;
	  	$reservedhash{$er . '2'} = $set_starttime;#reserv end_time

		$sb++;
		$eb++;
		$dt1->add( minutes => 15);
		$dtstart = $strp->parse_datetime($dt1);
                $set_starttime = $dtstart->datetime;
	  	$blockedhash{$sb . '1'} = $set_starttime;#blocked start_time
	      }
	  }
          $dtnow->add( weeks => 4);
          $set_endtime = $dtnow->datetime;
	  $blockedhash{$eb . '2'} = $set_endtime;
	  #print Dumper(\%reservedhash) . "<br />\n";
	  #print Dumper(\%blockedhash) . "<br />\n";
	  #end collect timerange

	  #view red flag if bike not available on selected rental timerange 
	  my $reservindex = 0;
	  my $se = 0;
	  my $reservbut = 0;
	  foreach my $ri (sort keys %reservedhash){
	     if($ri =~ /(\d{3})(\d{1})/){
	       $reservindex = $1;
	       $se = $2;
	     }
	     if($ri =~ /^$reservindex/ && $se == 1){
		my $dtx = $strp->parse_datetime($reservedhash{$ri});
		my $end_ri = $ri + 1;
		my $dty = $strp->parse_datetime($reservedhash{$end_ri});
		if($dty >= $dt0 && $dty <= $dt1 && $dtx <= $dt1){
		  $reservbut = 1;
		  #print $q->div({-style=>'color:red;'},"Im gewähltem Zeitfenster nicht verfügbar"),"\n";
		  #print "$ri Von: $reservedhash{$ri}<br />\n";
		  #print "$end_ri Bis: $reservedhash{$end_ri}<br />\n";
		}
	     }
     	  }

	  #delete blockedhash with too small ranges 
	  my $rangeindex = 0;
	  my $se = 0;
	  foreach my $ri (sort keys %blockedhash){
	     if($ri =~ /(\d{3})(\d{1})/){
	       $rangeindex = $1;
	       $se = $2;
	     }
	     if($ri =~ /^$rangeindex/ && $se == 1){
		my $dtx = $strp->parse_datetime($blockedhash{$ri});
		my $end_ri = $ri + 1;
		my $dty = $strp->parse_datetime($blockedhash{$end_ri});
		if($dty <= $dtx){
		  delete $blockedhash{$ri};
		  delete $blockedhash{$end_ri};
		}
	     }
     	  }

	  my $availability = "";
	  my $href = "";
	  #build availability links
	  foreach my $ri (sort keys %blockedhash){
	     if($ri =~ /(\d{3})(\d{1})/){
	       $rangeindex = $1;
	       $se = $2;
	     }
	     if($ri =~ /^$rangeindex/ && $se == 1){
	        $href = "/app/Account/CalendarReserv?sharee_edit=calendar_bikes_available&select_station=$select_station&bike=$bike&calreserv=1&authcookie=$coo&lang=de";
		#print "$ri Von: $blockedhash{$ri}<br />\n";
		my $dtx = $strp->parse_datetime($blockedhash{$ri});
            	my $start_loc = $dtx->strftime("%d.%m.%Y %H:%M");
	     	$href .= "&reserv_starttime=$blockedhash{$ri}";
		$availability .= "<div style='padding:20px 0;'>Von: $start_loc</div>\n";
	     }
	     if($ri =~ /^$rangeindex/ && $se == 2){
		#print "$ri Bis: $blockedhash{$ri}<br />---<br />\n";
		my $dty = $strp->parse_datetime($blockedhash{$ri});
	    	my $end_loc = $dty->strftime("%d.%m.%Y %H:%M");
	     	$href .= "&reserv_endtime=$blockedhash{$ri}";
		$availability .= "<div style='padding:20px 0;'><a href='$href'>Zeitfenster übernehmen</a></div>\n
		<div style='padding:20px 0;'>Bis: $end_loc</div>\n
		<div style='padding:20px 0;border-bottom:1px solid silver;'></div>\n";
	     }
	  }


print <<EOF
<!-- Modal -->
<div class="modal fade" id="$bike" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Verfügbarkeit: $response_bikes->{shareejson}->{bikes}->{$bike}->{description} $response_bikes->{shareejson}->{bikes}->{$bike}->{bike}</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div class="text-default">$availability</div>
      </div>
    </div>
  </div>
</div>
EOF
;

	if(!$R::bike_reserv && $reservbut){
	  print $q->div({-style=>'color:red;'},"Im gewählten Zeitraum nicht verfügbar."),"\n";
	}else{
	#if(1==1){
	  #Mietrad buchen
	  #print $q->div({-id=>"button_reserv_$bike",-style=>'clear:both;text-align:center;display:block;'},"<span class='btn btn-primary' style='margin:0.5em;width:300px;' onclick='rental_request(\"$response_bikes->{shareejson}->{bikes}->{$bike}->{uri_operator}/APIjsonserver?request=booking_request&bike=$response_bikes->{shareejson}->{bikes}->{$bike}->{bike}&calreserv=1&reserv_starttime=$reserv_starttime&reserv_endtime=$reserv_endtime&authcookie=$coo\",\"$bike\",\"\")'>Mietrad buchen</span>"),"\n";
          print $q->div({-id=>"button_reserv_$bike",-style=>'clear:both;text-align:center;display:block;'},"<button type='submit' name='bike_reserv' value='$bike' class='btn btn-primary btn-block' style='border:1px solid #$bgcolor1;margin:0.5em;width:300px;'>Mietrad buchen</button>"),"\n";
	
	  #Buchung stornieren
	  #print $q->div({-id=>"button_cancel_$bike",-style=>'clear:both;text-align:center;display:none;'},"<span class='btn btn-outline-primary' style='border:1px solid #$bgcolor1;color:#$bgcolor1;background-color:#fff;margin:0.5em;width:300px;' onclick='rental_request(\"$response_bikes->{shareejson}->{bikes}->{$bike}->{uri_operator}/APIjsonserver?request=booking_update&bike=$response_bikes->{shareejson}->{bikes}->{$bike}->{bike}&state=canceled&reserv_starttime=$reserv_starttime&reserv_endtime=$reserv_endtime&authcookie=$coo\",\"$bike\",\"\")'>Buchung stornieren</span>"),"\n";
  	}

	  #Verfügbarkeitsanzeige
	  print $q->div({-id=>"button_availablbility_$bike",-style=>'clear:both;text-align:center;display:block;'},"<span class='btn btn-outline-primary' style='border:1px solid #$bgcolor1;color:#$bgcolor1;background-color:#fff;margin:0.5em;width:300px;' data-bs-toggle='modal' data-bs-target='#$bike'>Verfügbarkeitsanzeige</span>"),"\n";
	

	#print Dumper($response_bikes->{shareejson}->{bikes}->{$bike}->{rental_description}->{tarif_elements});
	foreach my $ele (%{ $response_bikes->{shareejson}->{bikes}->{$bike}->{rental_description}->{tarif_elements} }){
	  if($response_bikes->{shareejson}->{bikes}->{$bike}->{rental_description}->{tarif_elements}->{$ele}[0] && $response_bikes->{shareejson}->{bikes}->{$bike}->{rental_description}->{tarif_elements}->{$ele}[1]){
	    print $q->div({-style=>'padding:0.2em 0.5em;'},"$response_bikes->{shareejson}->{bikes}->{$bike}->{rental_description}->{tarif_elements}->{$ele}[0] : $response_bikes->{shareejson}->{bikes}->{$bike}->{rental_description}->{tarif_elements}->{$ele}[1]"),"\n";
  	  }
	}
      
	#print "</div>\n";
     }

     #bikes_occupied
     print $q->div({-style=>'padding:0.1em 0;margin:0.5em 0;background-color:#b6b6b6;'},""),"\n";
     my $i = 0;
     foreach my $rid (sort {$response_bikes->{shareejson}->{bikes_occupied}->{$a}->{start_time} cmp $response_bikes->{shareejson}->{bikes_occupied}->{$b}->{start_time} } keys (%{ $response_bikes->{shareejson}->{bikes_occupied} })) {
	my $reserv_starttime = DateTime::Format::Pg->parse_datetime($response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{start_time});
     	my $reserv_endtime = DateTime::Format::Pg->parse_datetime($response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{end_time});
	my $start_loc = $reserv_starttime->strftime("%d.%m.%Y %H:%M");
	my $end_loc = $reserv_endtime->strftime("%d.%m.%Y %H:%M");
	$i++;
	my $oprefix = "";
	$oprefix = $1 if($response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{station} =~ /([A-Z]+)/i);
	my $bike = $response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{bike};
	print $q->div({-style=>'padding:1em 0.5em;font-weight:bold;'},"Deine $oprefix Buchungen:"),"\n" if($i == 1);
	#selector by $rid pos_id
	print $q->div({-id=>"return_state_$rid"},""),"\n";
	print $q->div({-id=>"button_cancel_$rid", -style=>'padding:0.2em 0.5em;color:green;display:block;'},"<span class='btn btn-outline-primary btn-sm' style='border:1px solid #$bgcolor1;color:#$bgcolor1;background-color:#fff;' onclick='rental_request(\"$response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{uri_operator}/APIjsonserver?request=booking_update&bike=$bike&pos_id=$rid&state=canceled&authcookie=$coo\",\"\",\"$rid\")'>Buchung stornieren</span> $start_loc - $end_loc: $response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{description} $bike an Station $response_bikes->{shareejson}->{bikes_occupied}->{$rid}->{station}"),"\n";
	print $q->div({-id=>"button_reserv_$rid",-style=>'color:red;'},""),"\n";#dummy
     }

   };
   if ($@){
     $bw->log("Failure, CalendarReserv bike_json not valid","","");
     warn $@;
   }
  }#end $bikes_json
 


 print $q->end_form,"\n";
 print $q->div({-id=>'scroll-top-wrapper'},"nach oben"),"\n" if($R::sharee_edit =~ /calendar_bikes_available/);

 #print $q->div({-style=>'position:fixed;bottom:2%;right:2%;z-index:10;font-size:13px;'},"--> $varenv->{syshost} | $varenv->{merchant_id} | $bgcolor1 | template -> $node_meta->{tpl_name},$node_meta->{tpl_id}"),"\n" if($users_sharee->{c_id} eq $dbt->{copri_conf}->{superu_id} || $dbt->{copri_conf}->{stage} eq "test");

  print "</div>\n";
}

#requestor
sub fetchserver_json {
 my $self = shift;
 my $uri_server = shift || "";
 my $rest = shift || "";
 my $server_request = "$uri_server/APIjsonserver?$rest";

 my $ua = LWP::UserAgent->new;
 $ua->agent("sharee CalReserv");

 my $req = HTTP::Request->new(GET => "$server_request");
 $req->content_type('application/x-www-form-urlencoded');
 $req->content($rest);

 #Pass request to the user agent and get a response back
 my $res = $ua->request($req);
 #SSL certificate must be valid
 #print Dumper($res);
 # Check the outcome of the response
 if ($res->is_success) {
  #print $res->content;
  return $res->content;
  #print $res->status_line, "\n";
 }else {
  return "";
  #print $res->status_line, "\n";
 }
}

1;
