<?php
session_start();
require_once('./../admin/tcpdf/tcpdf.php');
require_once("inc/config.inc.php");
require_once("inc/functions.inc.php");

if (!isset($_SESSION['userid'])) {
    die("Kein Benutzer angemeldet.");
}

$currentUser = check_user();
if (!is_admin_user()) {
    die("Keine Berechtigung.");
}

$selectedMonth = $_GET['month'] ?? date('m');
$selectedYear = $_GET['year'] ?? date('Y');
$firmaName = "Praxis Creutzburg";

try {
    $usersStmt = $pdo->prepare("
        SELECT DISTINCT u.id, u.vorname, u.nachname
        FROM users u
        INNER JOIN timestamps t ON t.employee_id = u.id
        WHERE u.zeiterfassung = '1'
          AND MONTH(t.timestamp_datetime) = :month
          AND YEAR(t.timestamp_datetime) = :year
        ORDER BY u.nachname ASC, u.vorname ASC
    ");
    $usersStmt->bindValue(':month', (int)$selectedMonth, PDO::PARAM_INT);
    $usersStmt->bindValue(':year', (int)$selectedYear, PDO::PARAM_INT);
    $usersStmt->execute();
    $employees = $usersStmt->fetchAll(PDO::FETCH_ASSOC);

    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetAuthor($currentUser['vorname'] . ' ' . $currentUser['nachname']);
    $pdf->SetTitle('Arbeitszeiten aller Mitarbeiter');
    $pdf->SetSubject('Arbeitszeiten aller Mitarbeiter fuer ' . $selectedMonth . '/' . $selectedYear);

    $stempdate = $selectedYear . "-" . $selectedMonth . "-1";
    $date = new DateTime($stempdate);
    $formatter = new IntlDateFormatter(
        "de-DE",
        IntlDateFormatter::LONG,
        IntlDateFormatter::NONE,
        "Europe/Berlin",
        IntlDateFormatter::GREGORIAN,
        "MMMM"
    );
    $monthName = $formatter->format($date);

    $sequenceStmt = $pdo->prepare("
        SELECT
            DATE(timestamp_datetime) AS datum,
            GROUP_CONCAT(timestamp_type ORDER BY timestamp_datetime) AS day_sequence
        FROM timestamps
        WHERE employee_id = :employee_id
          AND MONTH(timestamp_datetime) = :selectedMonth
          AND YEAR(timestamp_datetime) = :selectedYear
        GROUP BY DATE(timestamp_datetime)
    ");

    $timesStmt = $pdo->prepare("
        SELECT
            DATE(timestamp_datetime) AS day,
            MIN(CASE WHEN timestamp_type = 'KOMMEN' THEN timestamp_datetime END) AS first_come,
            MAX(CASE WHEN timestamp_type = 'GEHEN' THEN timestamp_datetime END) AS last_go,
            SEC_TO_TIME(SUM(
                CASE
                    WHEN timestamp_type = 'GEHEN' THEN UNIX_TIMESTAMP(timestamp_datetime)
                    WHEN timestamp_type = 'KOMMEN' THEN -UNIX_TIMESTAMP(timestamp_datetime)
                    ELSE 0
                END
            )) AS total_time,
            SEC_TO_TIME(
                TIME_TO_SEC(
                    SEC_TO_TIME(
                        UNIX_TIMESTAMP(MAX(CASE WHEN timestamp_type = 'GEHEN' THEN timestamp_datetime END)) -
                        UNIX_TIMESTAMP(MIN(CASE WHEN timestamp_type = 'KOMMEN' THEN timestamp_datetime END))
                    )
                ) - TIME_TO_SEC(SEC_TO_TIME(SUM(
                    CASE
                        WHEN timestamp_type = 'GEHEN' THEN UNIX_TIMESTAMP(timestamp_datetime)
                        WHEN timestamp_type = 'KOMMEN' THEN -UNIX_TIMESTAMP(timestamp_datetime)
                        ELSE 0
                    END
                )))
            ) AS difference_between_total_time_and_pause_time
        FROM timestamps
        WHERE employee_id = :employee_id
          AND MONTH(timestamp_datetime) = :month
          AND YEAR(timestamp_datetime) = :year
        GROUP BY DATE(timestamp_datetime)
    ");

    foreach ($employees as $employee) {
        $employeeId = (int)$employee['id'];
        $employeeName = trim($employee['vorname'] . ' ' . $employee['nachname']);

        $sequenceStmt->bindValue(':employee_id', $employeeId, PDO::PARAM_INT);
        $sequenceStmt->bindValue(':selectedMonth', (int)$selectedMonth, PDO::PARAM_INT);
        $sequenceStmt->bindValue(':selectedYear', (int)$selectedYear, PDO::PARAM_INT);
        $sequenceStmt->execute();
        $sequenceRows = $sequenceStmt->fetchAll(PDO::FETCH_ASSOC);

        $fehlerhafteTage = [];
        foreach ($sequenceRows as $row) {
            if (!isValidSequence((string)$row['day_sequence'])) {
                $fehlerhafteTage[] = (string)$row['datum'];
            }
        }

        $pdf->AddPage();
        $html = '<h1>Arbeitszeiten - ' . $firmaName . '</h1>';
        $html .= '<h2>Mitarbeiter: ' . htmlspecialchars($employeeName, ENT_QUOTES, 'UTF-8') . '</h2>';
        $html .= '<h3>Monat: ' . htmlspecialchars((string)$monthName, ENT_QUOTES, 'UTF-8') . ' ' . htmlspecialchars((string)$selectedYear, ENT_QUOTES, 'UTF-8') . '</h3>';

        if (!empty($fehlerhafteTage)) {
            $html .= '<p><strong>Fehlzeiten erkannt.</strong> Bitte erst beheben.</p>';
            $html .= '<p>Betroffene Tage: ' . htmlspecialchars(implode(', ', array_map(static function (string $day): string {
                return date('d.m.Y', strtotime($day));
            }, $fehlerhafteTage)), ENT_QUOTES, 'UTF-8') . '</p>';
            $pdf->writeHTML($html, true, false, true, false, '');
            continue;
        }

        $timesStmt->bindValue(':employee_id', $employeeId, PDO::PARAM_INT);
        $timesStmt->bindValue(':month', (int)$selectedMonth, PDO::PARAM_INT);
        $timesStmt->bindValue(':year', (int)$selectedYear, PDO::PARAM_INT);
        $timesStmt->execute();

        $timesData = [];
        while ($row = $timesStmt->fetch(PDO::FETCH_ASSOC)) {
            $day = date('d', strtotime($row['day']));
            $timesData[$day] = $row;
        }

        $html .= '<table border="1" style="font-size:14px;" width="100%">';
        $html .= '<tr><th style="width: 7%;">Tag</th><th style="width: 12%;">Start</th><th style="width: 12%;">Pause</th><th style="width: 12%;">Ende</th><th>Gesamtzeit</th><th style="width: 20%;font-size:12px;">aufgezeichnet am:</th><th style="width: 23%;">Bemerkung</th></tr>';

        $totalSeconds = 0;
        for ($day = 1; $day <= 31; $day++) {
            $daytwo = str_pad((string)$day, 2, '0', STR_PAD_LEFT);
            if (isset($timesData[$daytwo])) {
                $row = $timesData[$daytwo];
                $html .= '<tr><td>' . $day . '</td><td>' . date('H:i:s', strtotime($row['first_come'])) . '</td><td>' . $row['difference_between_total_time_and_pause_time'] . '</td><td>' . date('H:i:s', strtotime($row['last_go'])) . '</td><td>' . $row['total_time'] . '</td><td>' . date('d.m.Y', strtotime($row['day'])) . '</td><td></td></tr>';

                if (!empty($row['total_time'])) {
                    [$hours, $minutes, $seconds] = explode(':', $row['total_time']);
                    $totalSeconds += ((int)$hours * 3600) + ((int)$minutes * 60) + (int)$seconds;
                }
            } else {
                $html .= '<tr><td>' . $day . '</td><td></td><td></td><td></td><td></td><td></td><td></td></tr>';
            }
        }

        $hours = floor($totalSeconds / 3600);
        $mins = floor(($totalSeconds / 60) % 60);
        $secs = floor($totalSeconds % 60);
        $totalTime = sprintf('%02d:%02d:%02d', $hours, $mins, $secs);

        $html .= '<tr><td></td><td></td><td></td><td><b>Gesamt</b></td><td><b>' . $totalTime . '</b></td><td></td><td></td></tr>';
        $html .= '</table>';

        $pdf->writeHTML($html, true, false, true, false, '');
    }

    $pdf->Output('Arbeitszeiten_alle_' . $selectedYear . '_' . str_pad((string)$selectedMonth, 2, '0', STR_PAD_LEFT) . '.pdf', 'I');
} catch (PDOException $e) {
    echo "Datenbankfehler: " . $e->getMessage();
}
?>
