<?php

/**
 * Backfill journeylists.journeydate to bus run (service) day.
 *
 * Uses tickets.journeydata (boarding day) + pick_stand_id to compute the correct manifest date.
 *
 * Usage (from project root):
 *   php database/scripts/backfill_journeylists_service_dates.php --dry-run
 *   php database/scripts/backfill_journeylists_service_dates.php --apply
 */

declare(strict_types=1);

$dryRun = in_array('--dry-run', $argv ?? [], true) || ! in_array('--apply', $argv ?? [], true);
$tripFilter = null;
foreach ($argv ?? [] as $arg) {
    if (str_starts_with($arg, '--trip=')) {
        $tripFilter = (int) substr($arg, 7);
    }
}

define('FCPATH', dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR);

require dirname(__DIR__, 2) . '/vendor/autoload.php';

$pathsConfig = new Config\Paths();
require rtrim($pathsConfig->systemDirectory, '\\/ ') . '/bootstrap.php';

$app = Config\Services::codeigniter();
$app->initialize();

$db = \Config\Database::connect();

\App\Libraries\BookingInventorySupport::syncBookingTimezone();

$sql = 'SELECT jl.id, jl.booking_id, jl.trip_id, jl.subtrip_id, jl.pick_stand_id, jl.journeydate,
               t.journeydata, t.cancel_status, t.refund
        FROM journeylists jl
        INNER JOIN tickets t ON t.booking_id = jl.booking_id AND t.trip_id = jl.trip_id
        WHERE jl.deleted_at IS NULL';
$params = [];
if ($tripFilter > 0) {
    $sql .= ' AND jl.trip_id = ?';
    $params[] = $tripFilter;
}
$sql .= ' ORDER BY jl.id ASC';

$rows = $db->query($sql, $params)->getResult();

$wouldUpdate = 0;
$updated     = 0;
$skipped     = 0;

foreach ($rows as $row) {
    if ((int) ($row->cancel_status ?? 0) !== 0 || (int) ($row->refund ?? 0) !== 0) {
        $skipped++;
        continue;
    }

    $boardingDay = \App\Libraries\BookingInventorySupport::normalizeCalendarDate((string) ($row->journeydata ?? ''));
    if ($boardingDay === '1970-01-01') {
        $skipped++;
        continue;
    }

    $serviceDay = \App\Libraries\BookingInventorySupport::busRunForBooking(
        (int) $row->trip_id,
        (int) $row->subtrip_id,
        $boardingDay,
        (int) ($row->pick_stand_id ?? 0)
    );

    $storedManifest = \App\Libraries\BookingInventorySupport::normalizeCalendarDate((string) ($row->journeydate ?? ''));
    if ($storedManifest === $serviceDay) {
        continue;
    }

    $wouldUpdate++;
    echo sprintf(
        "%s id=%d booking=%s pick=%d boarding=%s manifest %s -> %s\n",
        $dryRun ? '[dry-run]' : '[apply]',
        (int) $row->id,
        (string) $row->booking_id,
        (int) ($row->pick_stand_id ?? 0),
        $boardingDay,
        $storedManifest,
        $serviceDay
    );

    if (! $dryRun) {
        $db->query(
            'UPDATE journeylists SET journeydate = ? WHERE id = ?',
            [$serviceDay, (int) $row->id]
        );
        $updated++;
    }
}

echo PHP_EOL . sprintf(
    "Done. candidates=%d %s=%d skipped=%d\n",
    $wouldUpdate,
    $dryRun ? 'would_update' : 'updated',
    $dryRun ? $wouldUpdate : $updated,
    $skipped
);

if ($dryRun) {
    echo "Re-run with --apply to persist changes.\n";
}
