<?php


error_reporting(E_ALL);
require('../config.php');
require('../EpiApi.php');

use chillerlan\QRCode\{
    QRCode,
    QROptions
};

require('../vendor/autoload.php');

$options = new QROptions([
    'imageBase64' => false,
    'qrCodeHeight' => 75,
    'qrCodeWidth' => 75,
    'version' => -1,
    'quietzoneSize' => 1
        ]);

$Epi = new Epirent();

const APP_TZ = 'Europe/Berlin';

/** Hilfsfunktionen für die Row-Marking-Logik (ohne weitere Änderungen am Rest) */
function dt(?string $s): ?DateTimeImmutable {
    if (!$s)
        return null;
    try {
        return new DateTimeImmutable($s, new DateTimeZone(APP_TZ));
    } catch (Throwable $e) {
        return null;
    }
}

function dayStart(DateTimeImmutable $d): DateTimeImmutable {
    return $d->setTime(0, 0, 0);
}

function resolveRowMarkDate($packingjob, $VorbereitungsTimeDetail, $PackingNoteDetail, $DispoTimeDetail, int $source): ?DateTimeImmutable {
    $candidate = null;
    switch ($source) {
        case 1: $candidate = dt($packingjob->date_start ?? null);
            break;
        case 2: $candidate = dt($VorbereitungsTimeDetail->date_start ?? null);
            break;
        case 3: $candidate = dt($PackingNoteDetail->date_packing ?? null);
            break;
        case 4: $candidate = dt($PackingNoteDetail->date_delivery ?? null);
            break;
        case 5: $candidate = dt($DispoTimeDetail->date_start ?? null);
            break;
        default: $candidate = null;
            break;
    }
    if (!$candidate) {
        $candidate = dt($packingjob->date_start ?? null);
    }
    return $candidate ? dayStart($candidate) : null;
}

function rowClassForDate(?DateTimeImmutable $markDate, ?DateTimeImmutable $today): string {
    if (!$markDate || !$today)
        return '';
    if ($markDate == $today)
        return 'text-dark bg-warning';
    if ($markDate < $today)
        return 'bg-danger';
    return '';
}

if (UseDeliveredForCheckOutCompleted) {
    $result = $Epi->requestEpiApi('/v1/packingnote/open?isci=true&cl=' . Epirent_Mandant);
    
} else {
    $result = $Epi->requestEpiApi('/v1/packingnote/open?isci=False&cl=' . Epirent_Mandant);
}
$data_output = json_decode($result)->payload;

if (SortCheckOut == 2) {

    // Prüfen, ob $data_output ein Array ist
    if (is_array($data_output)) {
        usort($data_output, function ($a, $b) {
            // Konvertiere time_start von Millisekunden in Sekunden
            $timeStartA = $a->time_start / 1000; // Zeit in Sekunden
            $timeStartB = $b->time_start / 1000;

            // Kombiniere date_start mit time_start
            $datetimeA = strtotime($a->date_start) + $timeStartA;
            $datetimeB = strtotime($b->date_start) + $timeStartB;

            // Vergleich für die Sortierung
            return $datetimeA <=> $datetimeB;
        });

        // Sortierte Daten ausgeben oder weiterverarbeiten
        // print_r($data_output);
    } else {
        echo "Daten konnten nicht verarbeitet werden.";
    }
}

foreach ($data_output as $packingjob) {

    $PackingNoteDetail = null;

    if ($packingjob->is_archived != true && UseDeliveredForCheckOutCompleted) {
        $PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant);
        $PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0];
       
        
    }

if (
    ($packingjob->is_archived ?? false) != true
    && (
        ((int)($PackingNoteDetail->is_all_out ?? 0)) !== 0
        || (($PackingNoteDetail->date_delivered ?? "0000-00-00") === "0000-00-00"
            || (int)($PackingNoteDetail->time_delivered ?? 0) === 0)
    )
) {
        //get OrderDetails
        $result = $Epi->requestEpiApi('/v1/order/' . $packingjob->order_pk . '?cl=' . Epirent_Mandant);
        $orderdetail_output = json_decode($result)->payload[0];

        // get PackingNote Details, aber nur wenn nicht schon vor der schleife geholt.
        if (!UseDeliveredForCheckOutCompleted) {
            $PackingNoteDetailResult = $Epi->requestEpiApi('/v1/packingnote/' . $packingjob->primary_key . '?cl=' . Epirent_Mandant);
            $PackingNoteDetail = json_decode($PackingNoteDetailResult)->payload[0];
        }

        $VorbereitungsTimeDetail = null;
        $DispoTimeDetail = null;

        foreach ($orderdetail_output->order_schedule as $scheduledetail) {
            if ($scheduledetail->name == Vorbereitungs_Zeitvariable) {
                $VorbereitungsTimeDetail = $scheduledetail;
            }
            if($scheduledetail->name == "Dispo"){
                $DispoTimeDetail = $scheduledetail;
            }
        }

        // --- Row-Marking Datum bestimmen (konfigurierbar) ---
        $today = dayStart(new DateTimeImmutable('today', new DateTimeZone(APP_TZ)));
        $todayFilter = $today; // für die Window-Berechnung
        $limit = null;
        if (CheckOut_FutureDays != -1) {
            $limit = $todayFilter->modify('+' . (int) CheckOut_FutureDays . ' day');
        }

        $markDate = resolveRowMarkDate($packingjob, $VorbereitungsTimeDetail, $PackingNoteDetail, $DispoTimeDetail, (int) CheckOutRowMarkSource);

        if (CheckOut_FutureDays == -1 || ($markDate && $markDate <= $limit)) {
            $trClass = rowClassForDate($markDate, $today);

            if ($trClass) {
                echo "<tr class='{$trClass}'>";
            } else {
                echo "<tr>";
            }

            if (Enable_QR_Code_CheckOut) {
                echo "<td>" . '<div style="width: 5vb;">' . (new QRCode($options))->render($packingjob->packingnote_no) . "</div></td>";
            } else {
                echo "<td>" . $packingjob->packingnote_no . "</td>";
            }
            echo "<td>" . $packingjob->contact->name . "</td>";
            echo "<td>" . $packingjob->event . "</td>";

            if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout || ShowDispoStartOnCheckout) { echo "<td>";}
                                                
            
            if (ShowCheckoutTimeOnCheckout && $packingjob->date_start != null) {
                echoMarkedTimeLine($packingjob->date_start, (int) $packingjob->time_start, $today, ShowTimesOnCheckout);
            }
            if (ShowVorbereitungTimeOnCheckout && $VorbereitungsTimeDetail && $VorbereitungsTimeDetail->date_start != null) {
                if (ShowCheckoutTimeOnCheckout) {
                    echo "<br>";
                }
                
                if($packingjob->is_all_out != 0){
               echoMarkedTimeLine($VorbereitungsTimeDetail->date_start, (int) $VorbereitungsTimeDetail->time_start, $today, ShowTimesOnCheckout);
                }else{
                    echo "<span class='bg-success text-light'>";
                    echo date_format(new \DateTime($VorbereitungsTimeDetail->date_start), 'd.m.Y');
                    if($VorbereitungsTimeDetail->time_start){echo " ".getTimeFromSeconds((string) $VorbereitungsTimeDetail->time_start);}
                    echo "</span>";
                }
                
                
            }
            if (ShowPackagingTimeOnCheckout && $PackingNoteDetail && $PackingNoteDetail->date_packing != null) {
                if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout) {
                    echo "<br>";
                }
                if($packingjob->is_all_out != 0){
                echoMarkedTimeLine($PackingNoteDetail->date_packing, (int) $PackingNoteDetail->time_packing, $today, ShowTimesOnCheckout);
                }else{
                    echo "<span class='bg-success text-light'>";
                    echo date_format(new \DateTime($PackingNoteDetail->date_packing), 'd.m.Y');
                    if($PackingNoteDetail->time_packing){echo " ".getTimeFromSeconds((string) $PackingNoteDetail->time_packing);}
                    echo "</span>";
                }
            }
            if (ShowDeliveryTimeOnCheckout && $PackingNoteDetail && $PackingNoteDetail->date_delivery != null) {
                if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout) {
                    echo "<br>";
                }
                echoMarkedTimeLine($PackingNoteDetail->date_delivery, (int) $PackingNoteDetail->time_delivery, $today, ShowTimesOnCheckout);
            }
            if (ShowDispoStartOnCheckout && $DispoTimeDetail->date_start && $DispoTimeDetail->time_start != null) {
                if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout) {
                    echo "<br>";
                }
                echoMarkedTimeLine($DispoTimeDetail->date_start, (int) $DispoTimeDetail->time_start, $today, ShowTimesOnCheckout);
            }

          if (ShowCheckoutTimeOnCheckout || ShowVorbereitungTimeOnCheckout || ShowPackagingTimeOnCheckout || ShowDeliveryTimeOnCheckout || ShowDispoStartOnCheckout) {
                echo "</td>";
            }

            echo "<td>";

            if ($packingjob->is_all_out == 0) {
                echo "<span class='badge badge-success'>";
            } else {

                echo '<div class="progress"><div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: ' . (($packingjob->pieces_sum_total - abs($packingjob->is_all_out)) / $packingjob->pieces_sum_total) * 100 . '%" aria-valuenow="' . ($packingjob->pieces_sum_total - abs($packingjob->is_all_out)) . '" aria-valuemin="0" aria-valuemax="' . $packingjob->pieces_sum_total . '"></div></div>';

                echo "<span class='badge badge-info'>";
            }

            echo ($packingjob->pieces_sum_total - abs($packingjob->is_all_out)) . "/" . $packingjob->pieces_sum_total;
            echo "</span></td>";

            if (ShowShippingIcons) {

                if (UseShippingStatus) {
                    if (($PackingNoteDetail->status == ShippingOutOrganizedStatus) || ($PackingNoteDetail->status == ShippingOrganizedStatus)) {
                        echo "<td style='color:#66FF00; text-align:center;'>";
                    } else {
                        echo "<td style='text-align:center;'>";
                    }

                    if ($PackingNoteDetail->is_self_pickup) {
                        echo '<i class="'.SelbstabholerIcon.'"></i>';
                    } else {
                        if (preg_match('/' . KurierContainsText . '/i', $PackingNoteDetail->shipping_out)) {
                            echo '<i class="'.KurierIcon.'"></i>';
                        }
                        if (preg_match('/' . SpeditionContainsText . '/i', $PackingNoteDetail->shipping_out)) {
                            echo '<i class="'.SpeditionIcon.'"></i>';
                        }
                        if (preg_match('/' . DHLContainsText . '/i', $PackingNoteDetail->shipping_out)) {
                            echo '<i class="'.DHLIcon.'"></i>';
                        }
                        if (preg_match('/' . LKWContainsText . '/i', $PackingNoteDetail->shipping_out)) {
                            echo '<i class="fa-solid fa-industry fa-lg"></i><i class="'.LKWIcon.'"></i>';
                        }
                        if (preg_match('/' . TransporterContainsText . '/i', $PackingNoteDetail->shipping_out)) {
                            echo '<i class="fa-solid fa-industry fa-lg"></i><i class="'.TransporterIcon.'"></i>';
                        }
                        if (preg_match('/' . PKWContainsText . '/i', $PackingNoteDetail->shipping_out)) {
                            echo '<i class="fa-solid fa-industry fa-lg"></i><i class="'.PKWIcon.'"></i>';
                        }
                    }
                    echo "</td>";
                }

                echo "</tr>";
            }

            echo "</tr>";
        }
    }
}

function echoMarkedTimeLine(?string $dateStr, ?int $timeSeconds, DateTimeImmutable $today, $ReturnTime): void {
    if (!$dateStr)
        return;
    $d = dt($dateStr);
    if (!$d)
        return;

    $mark = dayStart($d);
    $cls = rowClassForDate($mark, $today);

    echo $cls ? "<span class=\"{$cls}\">" : "";
    echo date_format(new \DateTime($dateStr), 'd.m.Y');
    if($ReturnTime){echo " ".getTimeFromSeconds((string) $timeSeconds);}
    echo $cls ? "</span>" : "";
}

/*
function getTimeFromSeconds(string $timestring) {

    $hours = floor($timestring / 3600);
    $mins = floor(round($timestring / 60 % 60));
    $secs = floor(round($timestring % 60));

    $timeFormat = sprintf('%02d:%02d', $hours, $mins);

    return $timeFormat;
}*/
function getTimeFromSeconds($seconds): string {
    if ($seconds === null || $seconds === '') {
        return '';
    }

    // robust normalisieren: String/Float -> Float -> gerundet -> Int
    $seconds = (int) round((float) $seconds);

    if ($seconds < 0) {
        $seconds = 0; // oder: return ''; je nach gewünschtem Verhalten
    }

    // reine Integer-Arithmetik, keine impliziten float->int Casts
    $hours = intdiv($seconds, 3600);
    $mins  = intdiv($seconds % 3600, 60);

    return sprintf('%02d:%02d', $hours, $mins);
}


?>
