<?php

namespace App\Support;

use Illuminate\Support\Carbon;

/**
 * The two halves of a wall clock, kept in one place.
 *
 * A `datetime-local` field has no timezone: it is the numbers a person reads
 * off their own clock. That makes it a round trip with two ends, and getting
 * one end right is not half a fix — it is a fresh bug. Filling a field from a
 * UTC timestamp shows an operator 21:00 for a window that starts at 23:00
 * their time; parsing what they type as UTC stores 21:00 for the 19:00 they
 * meant. Do both, or neither works.
 *
 * They live as a pair here so that nobody can change one end without the other
 * being in front of them.
 */
final class LocalTime
{
    /** The value for a datetime-local input, in the reader's own zone. */
    public static function toField(?Carbon $at): string
    {
        return $at?->local()->format('Y-m-d\TH:i') ?? '';
    }

    /**
     * What a person typed into such a field, as UTC for storage.
     *
     * Returns null for anything unusable rather than throwing: these fields
     * are read on every keystroke, and half of "2026-07-2" is normal.
     */
    public static function fromField(string $value): ?Carbon
    {
        if (trim($value) === '') {
            return null;
        }

        try {
            // Parsed IN the display zone — the string carries no offset, so
            // without this it would be read as UTC and silently shifted.
            return Carbon::parse($value, config('app.display_timezone'))->utc();
        } catch (\Throwable) {
            return null;
        }
    }
}
