<?php

// D1 daily-images — use D1 for all cameras, fallback to files.txt on failure
@include_once('/home/subdomains/livetimelapse/public_html/php/api/daily-images-helper.php');

if (!function_exists('_getFileListForDay')) {
    function _getFileListForDay($cam, $year, $month, $day, $fallbackPath) {
        if (function_exists('dailyImagesGetFileList')) {
            $d1Name = str_replace('_', '-', $cam);
            $d1Date = "$year-$month-$day";
            $d1Result = dailyImagesGetFileList($d1Name, $d1Date, 'web');
            if ($d1Result !== false) {
                $ftResult = @file("$fallbackPath", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
                if ($ftResult !== false && count($ftResult) > count($d1Result) + 5) {
                    return $ftResult;
                }
                return $d1Result;
            }
        }
        return @file("$fallbackPath");
    }
}
/////////////////////////////////////////////////////////////////////////
//////////////   B2 IMAGE URL JSON API    ///////////////////////////////
/////////////////////////////////////////////////////////////////////////
//
// Standalone JSON API endpoint that returns Backblaze B2 image URLs
// for a given camera and time period. Reuses the same image-list
// building logic as tlc.include.b2native.php.
//
// Required parameters:
//   cam  - Camera identifier (underscore format)
//   mode - Time period: last2hours, today, yesterday, project, custom
//
// Optional parameters (custom mode):
//   s1y, s1m, s1d, s1t - Start year, month (jan-dec), day, time (HHMM)
//   s2y, s2m, s2d, s2t - Stop year, month (jan-dec), day, time (HHMM)
//
// Optional project overrides:
//   project_start_date, project_start_hour, project_start_ampm
//   project_stop_hour, project_stop_ampm
//   max_project_images, image_size
//   project_limit_start_hour, project_limit_start_ampm
//   project_limit_stop_hour, project_limit_stop_ampm
//
/////////////////////////////////////////////////////////////////////////

ini_set('display_errors', '0');
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');

/////////////////////////////////////////////////////////////////////////
//////////////   HELPER FUNCTIONS         ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

function isLeapYear($year) {
    return (($year % 4 == 0 && $year % 100 != 0) || $year % 400 == 0);
}

function check_month_days($month, $day) {
    if ($month == 'jan' && $day > 31) { return 31; }
    if ($month == 'feb' && $day > 28) {
        if (isLeapYear(date('Y'))) { return 29; }
        else { return 28; }
    }
    if ($month == 'mar' && $day > 31) { return 31; }
    if ($month == 'apr' && $day > 30) { return 30; }
    if ($month == 'may' && $day > 31) { return 31; }
    if ($month == 'jun' && $day > 30) { return 30; }
    if ($month == 'jul' && $day > 31) { return 31; }
    if ($month == 'aug' && $day > 31) { return 31; }
    if ($month == 'sep' && $day > 30) { return 30; }
    if ($month == 'oct' && $day > 31) { return 31; }
    if ($month == 'nov' && $day > 30) { return 30; }
    if ($month == 'dec' && $day > 31) { return 31; }
    else { return $day; }
}

function round_time($time, $mode, $nearest) {
    if ($mode == 'up') {
        if ($nearest == 10) {
            $time_values = '|00|,|10|,|20|,|30|,|40|,|50|';
            $a = 0;
            $current_minutes = date("i", $time);
            while (strstr($time_values, "|$current_minutes|") == FALSE) {
                $current_minutes = date("i", $time);
                $time = $time + 30;
                $a++;
                if ($a == 20) { break; }
            }
        }
    }
    if ($mode == 'down') {
        if ($nearest == 10) {
            $time_values = '|00|,|10|,|20|,|30|,|40|,|50|';
            $a = 0;
            $current_minutes = date("i", $time);
            while (strstr($time_values, "|$current_minutes|") == FALSE) {
                $current_minutes = date("i", $time);
                $time = $time - 30;
                $a++;
                if ($a == 20) { break; }
            }
        }
    }
    return $time;
}

function get_images($cam, $date, $start_time_unix, $stop_time_unix) {
    global $basedir_archive;

    global $project_start_hour;
    global $project_start_min;
    global $project_start_ampm;

    global $project_stop_hour;
    global $project_stop_min;
    global $project_stop_ampm;

    global $last2hours;
    global $today;
    global $yesterday;
    global $project;

    global $timeLapseImageSize;

    $start_date = date('Ymd', $start_time_unix);
    $stop_date = date('Ymd', $stop_time_unix);

    $directories = Array();
    $dates = Array();
    $a = 0;
    $working_date = $start_date;

    while ($working_date <= $stop_date) {
        $directories[$a] = "{$basedir_archive}/{$cam}/" . substr($working_date, 0, 4) . "/" . substr($working_date, 4, 2) . "/" . substr($working_date, 6, 2);
        $dates[$a] = $working_date;
        $working_date = date('Ymd', (strtotime($working_date) + 86400));
        $a++;
        if ($a == 1000) { break; }
    }

    $archived_images = array();

    for ($b = 0; $b < sizeof($directories); $b++) {
        if ($last2hours == 'on') {
            $current_time = time();
            $current_date = date('Ymd');
            $relative_project_start = strtotime("$current_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
            $relative_project_stop = strtotime("$current_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");

            if (($current_time > $relative_project_stop || $current_time < $relative_project_start)) {
                if ($current_time > $relative_project_stop) {
                    $start_hour = $relative_project_stop - 7200;
                    $stop_hour = $relative_project_stop;
                } else {
                    $start_hour = $relative_project_stop - 93600;
                    $stop_hour = $relative_project_stop - 86400;
                }
            } else {
                $start_hour = $start_time_unix;
                $stop_hour = $stop_time_unix;
            }
        } elseif ($today == 'on' || $yesterday == 'on' || $project == 'on') {
            $start_hour = strtotime("{$dates[$b]}, {$project_start_hour}:{$project_start_min}$project_start_ampm");
            $stop_hour = strtotime("{$dates[$b]}, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
        } else {
            $days = sizeof($directories);
            $current_time = time();
            $current_date = date('Ymd');
            $relative_project_start = strtotime("$current_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
            $relative_project_stop = strtotime("$current_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");

            if ($days == 1) {
                $start_hour = $start_time_unix;
                $stop_hour = $stop_time_unix;
            } else {
                if ($b == 0) {
                    $start_hour = $start_time_unix;
                    $stop_hour = strtotime("{$dates[$b]}, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
                } elseif ($b == ($days - 1)) {
                    $start_hour = strtotime("{$dates[$b]}, {$project_start_hour}:{$project_start_min}$project_start_ampm");
                    $stop_hour = $stop_time_unix;
                } else {
                    $start_hour = strtotime("{$dates[$b]}, {$project_start_hour}:{$project_start_min}$project_start_ampm");
                    $stop_hour = strtotime("{$dates[$b]}, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
                }
            }
        }

        $current_year = substr($dates[$b], 0, 4);
        $current_month = substr($dates[$b], 4, 2);
        $current_day = substr($dates[$b], 6, 2);

        $current_file_list = _getFileListForDay($cam, $current_year, $current_month, $current_day, "{$basedir_archive}/$cam/$current_year/$current_month/$current_day/files.txt");
        if (is_bool($current_file_list) === true) {
            $current_file_list = array();
        }
        for ($c = 0; $c < sizeof($current_file_list); $c++) {
            $current_file_list[$c] = trim($current_file_list[$c]);
            if (strstr($current_file_list[$c], $timeLapseImageSize)) {
                $check = str_replace("{$timeLapseImageSize}_", '', $current_file_list[$c]);
                $check = str_replace('.jpg', '', $check);
                $current_image_time = strtotime("{$dates[$b]}, $check");

                if ($current_image_time > $start_hour && $current_image_time < $stop_hour) {
                    $archived_images[] = "{$cam}/$current_year/$current_month/$current_day/" . trim($current_file_list[$c]);
                }
            }
        }
    }
    if (is_array($archived_images)) {
        sort($archived_images);
    }

    return $archived_images;
}

function get_project_images($cam) {
    global $basedir_archive;

    global $project_start_time_unix;
    global $project_stop_time_unix;

    global $project_start_hour;
    global $project_start_min;
    global $project_start_ampm;

    global $project_stop_hour;
    global $project_stop_min;
    global $project_stop_ampm;

    global $project_images_per_day;
    global $project_limit_start_hour;
    global $project_limit_start_min;
    global $project_limit_start_ampm;
    global $project_limit_stop_hour;
    global $project_limit_stop_min;
    global $project_limit_stop_ampm;

    global $timeLapseImageSize;

    $start_date = date('Ymd', $project_start_time_unix);
    $stop_date = date('Ymd', $project_stop_time_unix);
    $current_date = date('Ymd', time() + 86400);
    $current_date_unix = time();

    $directories = Array();
    $dates = Array();
    $a = 0;
    $working_date = $project_start_time_unix;

    while (($working_date <= $project_stop_time_unix) && ($working_date < $current_date_unix)) {
        $directories[$a] = "{$basedir_archive}/{$cam}/" . date("Y", $working_date) . "/" . date("m", $working_date) . "/" . date("d", $working_date);
        $dates[$a] = date("Ymd", $working_date);
        $working_date = $working_date + 86400;
        $a++;
        if ($a == 1000) { break; }
    }

    $filtered_list = array();
    $final_list = array();

    for ($b = 0; $b < sizeof($directories); $b++) {
        if ($project_limit_start_hour) {
            $start_hour = strtotime("{$dates[$b]}, {$project_limit_start_hour}:{$project_limit_start_min}$project_limit_start_ampm");
            $stop_hour = strtotime("{$dates[$b]}, {$project_limit_stop_hour}:{$project_limit_stop_min}$project_limit_stop_ampm");
        } else {
            $start_hour = strtotime("{$dates[$b]}, {$project_start_hour}:{$project_start_min}$project_start_ampm");
            $stop_hour = strtotime("{$dates[$b]}, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
        }

        $current_year = substr($dates[$b], 0, 4);
        $current_month = substr($dates[$b], 4, 2);
        $current_day = substr($dates[$b], 6, 2);

        $current_list = _getFileListForDay($cam, $current_year, $current_month, $current_day, "{$directories[$b]}/files.txt");
        if (is_bool($current_list) === false) {
            for ($a = 0; $a < sizeof($current_list); $a++) {
                if (strstr($current_list[$a], $timeLapseImageSize)) {
                    $check = str_replace("{$timeLapseImageSize}_", '', $current_list[$a]);
                    $check = str_replace('.jpg', '', $check);
                    $current_image_time = strtotime("{$dates[$b]}, $check");

                    if (($current_image_time > $start_hour) && ($current_image_time < $stop_hour)) {
                        $filtered_list[$b][] = "{$cam}/$current_year/$current_month/$current_day/" . trim($current_list[$a]);
                    }
                }
            }
            if (isset($filtered_list[$b]) && is_null($filtered_list[$b]) === false) {
                $forward_skip = round(sizeof($filtered_list[$b]) / $project_images_per_day);
                if ($forward_skip <= 0) { $forward_skip = 1; }

                if ($forward_skip > 0) {
                    $a = 0;
                    while (isset($filtered_list[$b][$a]) && $filtered_list[$b][$a]) {
                        $final_list[] = $filtered_list[$b][$a];
                        $a = $a + $forward_skip;
                    }
                }
            }
        }
    }
    if (empty($final_list)) {
        $final_list = array();
    }
    sort($final_list);

    return $final_list;
}

/////////////////////////////////////////////////////////////////////////
//////////////   PARAMETER VALIDATION     ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

$cam = isset($_GET['cam']) ? trim($_GET['cam']) : '';
$mode = isset($_GET['mode']) ? trim($_GET['mode']) : '';

// Validate required parameters
if (empty($cam)) {
    echo json_encode(['status' => 'error', 'message' => 'Missing required parameter: cam']);
    exit();
}

if (empty($mode)) {
    echo json_encode(['status' => 'error', 'message' => 'Missing required parameter: mode']);
    exit();
}

$valid_modes = ['last2hours', 'today', 'yesterday', 'project', 'custom'];
if (!in_array($mode, $valid_modes)) {
    echo json_encode(['status' => 'error', 'message' => 'Invalid mode. Must be one of: ' . implode(', ', $valid_modes)]);
    exit();
}

// Validate cam format - must start with tlc_ and only contain alphanumeric + underscores
if (!preg_match('/^tlc_[a-zA-Z0-9_]+$/', $cam)) {
    echo json_encode(['status' => 'error', 'message' => 'Invalid camera identifier format']);
    exit();
}

// Validate custom mode has required date params
if ($mode === 'custom') {
    if (empty($_GET['s1y']) || empty($_GET['s2y'])) {
        echo json_encode(['status' => 'error', 'message' => 'Custom mode requires start (s1y,s1m,s1d,s1t) and stop (s2y,s2m,s2d,s2t) parameters']);
        exit();
    }
}

/////////////////////////////////////////////////////////////////////////
//////////////   CAMERA CONFIG (timezone + image size)  /////////////////
/////////////////////////////////////////////////////////////////////////

// Store original cam for the response (before zoom variants modify it)
$original_cam = $cam;

// Default image size - can be overridden by query param
$timeLapseImageSize = isset($_GET['image_size']) ? $_GET['image_size'] : '980x655';
$displayImageSize = $timeLapseImageSize;
$newS3 = TRUE;

// Include the camera configuration files to set timezone and image size
// These files check $cam and call date_default_timezone_set() etc.
require(__DIR__ . '/tlc.include.b2native-camconfig.php');

// Re-apply image_size override if explicitly provided (camconfig may have overwritten it)
if (isset($_GET['image_size'])) {
    $timeLapseImageSize = $_GET['image_size'];
    $displayImageSize = $timeLapseImageSize;
}

/////////////////////////////////////////////////////////////////////////
//////////////   PROJECT SETTINGS         ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

$basedir_archive = '/home/subdomains/livetimelapse/public_html/webcams/archive_timelapse';

// Project settings - accept from query string with sensible defaults
$project_start_date = isset($_GET['project_start_date']) ? $_GET['project_start_date'] : '20200101';
$project_start_hour = isset($_GET['project_start_hour']) ? $_GET['project_start_hour'] : '6';
$project_start_min = '00';
$project_start_ampm = isset($_GET['project_start_ampm']) ? $_GET['project_start_ampm'] : 'am';

$project_stop_hour = isset($_GET['project_stop_hour']) ? $_GET['project_stop_hour'] : '6';
$project_stop_min = '00';
$project_stop_ampm = isset($_GET['project_stop_ampm']) ? $_GET['project_stop_ampm'] : 'pm';

$max_project_images = isset($_GET['max_project_images']) ? intval($_GET['max_project_images']) : 200;
if ($max_project_images < 1) { $max_project_images = 200; }

// Project limit hours (narrower window for project mode sampling)
$project_limit_start_hour = isset($_GET['project_limit_start_hour']) ? $_GET['project_limit_start_hour'] : '';
$project_limit_start_min = isset($_GET['project_limit_start_min']) ? $_GET['project_limit_start_min'] : '00';
$project_limit_start_ampm = isset($_GET['project_limit_start_ampm']) ? $_GET['project_limit_start_ampm'] : 'am';
$project_limit_stop_hour = isset($_GET['project_limit_stop_hour']) ? $_GET['project_limit_stop_hour'] : '';
$project_limit_stop_min = isset($_GET['project_limit_stop_min']) ? $_GET['project_limit_stop_min'] : '00';
$project_limit_stop_ampm = isset($_GET['project_limit_stop_ampm']) ? $_GET['project_limit_stop_ampm'] : 'pm';

// Calculate project_images_per_day (same logic as calling pages)
$project_start_time_unix = strtotime("$project_start_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");

// Project stop date - default to far future
$project_stop_date = isset($_GET['project_stop_date']) ? $_GET['project_stop_date'] : '20301231';
$project_stop_time_unix = strtotime("$project_stop_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");

$current_date_midnight = date("Ymd", time() + 86400);
$project_duration_unix = strtotime("$current_date_midnight, 12:00am") - strtotime("$project_start_date, 12:00am");
$project_duration_days = $project_duration_unix / 86400;
if ($project_duration_days < 1) { $project_duration_days = 1; }
$project_images_per_day = round($max_project_images / $project_duration_days, 1) - 1;
if ($project_images_per_day < 1) { $project_images_per_day = 1; }

/////////////////////////////////////////////////////////////////////////
//////////////   SET MODE FLAGS           ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

$last2hours = '';
$today = '';
$yesterday = '';
$project = '';

switch ($mode) {
    case 'last2hours': $last2hours = 'on'; break;
    case 'today':      $today = 'on';      break;
    case 'yesterday':  $yesterday = 'on';  break;
    case 'project':    $project = 'on';    break;
}

/////////////////////////////////////////////////////////////////////////
//////////////   TIME PERIOD CALCULATION  ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

$start_time_unix = 0;
$stop_time_unix = 0;

if ($last2hours == 'on' || $today == 'on' || $yesterday == 'on' || $project == 'on') {

    if ($last2hours == 'on') {
        $start_time_unix = time() - 7200;
        $stop_time_unix = time();

        $current_time = time();
        $current_date = date("Ymd");
        $yesterdays_date = date("Ymd", time() - 86400);
        $relative_project_start = strtotime("$current_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
        $relative_project_stop = strtotime("$current_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");

        if (($current_time > $relative_project_stop || $current_time < $relative_project_start)) {
            if ($current_time > $relative_project_stop) {
                $relative_project_start = strtotime("$current_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
                $relative_project_stop = strtotime("$current_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
                $start_time_unix = $relative_project_stop - 7200;
                $stop_time_unix = $relative_project_stop;
            } else {
                $relative_project_start = strtotime("$yesterdays_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
                $relative_project_stop = strtotime("$yesterdays_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
                $start_time_unix = $relative_project_stop - 3600;
                $stop_time_unix = $relative_project_stop;
            }
        }

        if ($start_time_unix < $relative_project_start) { $start_time_unix = $relative_project_start; }

    } elseif ($today == 'on') {
        $today_date = date("Ymd");
        $start_time_unix = strtotime("$today_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
        $stop_time_unix = strtotime("$today_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");

    } elseif ($yesterday == 'on') {
        $yesterday_date = date("Ymd", time() - 86400);
        $start_time_unix = strtotime("$yesterday_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
        $stop_time_unix = strtotime("$yesterday_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");

    } elseif ($project == 'on') {
        $today_date = date("Ymd");
        $start_time_unix = strtotime("$project_start_date, {$project_start_hour}:{$project_start_min}$project_start_ampm");
        $stop_time_unix = strtotime("$today_date, {$project_stop_hour}:{$project_stop_min}$project_stop_ampm");
    }

    $start_time_unix = round_time($start_time_unix, 'down', '10');
    $stop_time_unix = round_time($stop_time_unix, 'up', '10');

} elseif ($mode === 'custom') {
    $start_year = $_GET['s1y'];
    $start_month = $_GET['s1m'];
    $start_day = check_month_days($start_month, $_GET['s1d']);
    $start_time = $_GET['s1t'];

    $stop_year = $_GET['s2y'];
    $stop_month = $_GET['s2m'];
    $stop_day = check_month_days($stop_month, $_GET['s2d']);
    $stop_time = $_GET['s2t'];

    $start_time_unix = strtotime("$start_month $start_day, $start_year, $start_time");
    $stop_time_unix = strtotime("$stop_month $stop_day, $stop_year, $stop_time");

    $start_time_unix = round_time($start_time_unix, 'down', '10');
    $stop_time_unix = round_time($stop_time_unix, 'up', '10');
}

/////////////////////////////////////////////////////////////////////////
//////////////   BUILD IMAGE LIST         ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

$image_list = array();

if ($start_time_unix > $stop_time_unix && $mode !== 'project') {
    echo json_encode(['status' => 'error', 'message' => 'Start time is after stop time']);
    exit();
} elseif ($project == 'on') {
    $image_list = get_project_images($cam);
} else {
    $image_list = get_images($cam, '', $start_time_unix, $stop_time_unix);
}

if (!is_array($image_list)) {
    $image_list = array();
}

/////////////////////////////////////////////////////////////////////////
//////////////   BUILD B2 URLS            ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

// All image URLs routed through CDN Worker — no region lookup needed
$bucketName = str_replace("_", "-", $cam);

// Build full URLs via CDN
$images = array();
for ($a = 0; $a < sizeof($image_list); $a++) {
    $imagePath = str_replace("{$bucketName}", "{$cam}", $image_list[$a]);
    $images[] = "https://images.livetimelapse.com.au/{$bucketName}/{$imagePath}";
}

/////////////////////////////////////////////////////////////////////////
//////////////   JSON OUTPUT              ///////////////////////////////
/////////////////////////////////////////////////////////////////////////

$response = [
    'status' => 'success',
    'camera' => $original_cam,
    'mode' => $mode,
    'time_range' => [
        'start' => date('c', $start_time_unix),
        'stop' => date('c', $stop_time_unix)
    ],
    'image_size' => $timeLapseImageSize,
    'image_count' => count($images),
    'images' => $images
];

echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
