import { __, sprintf } from '@wordpress/i18n';
import { currentLocale } from './locale';
import {
	MILLISECONDS_PER_SECOND,
	SECONDS_PER_DAY,
	SECONDS_PER_HOUR,
	SECONDS_PER_MINUTE,
} from './timeUnits';

const NIGHT_ENDS_AT_HOUR = 6;
const NIGHT_STARTS_AT_HOUR = 21;
const CLOCK_DIGITS = 2;

function twoDigits( clockPart: number ): string {
	return String( clockPart ).padStart( CLOCK_DIGITS, '0' );
}

export function clock( totalSeconds: number ): string {
	const seconds = Math.max( 0, Math.round( totalSeconds ) );
	const minutesPart = twoDigits( Math.floor( seconds / SECONDS_PER_MINUTE ) );
	const secondsPart = twoDigits( seconds % SECONDS_PER_MINUTE );

	return `${ minutesPart }:${ secondsPart }`;
}

function isNight( moment: Date ): boolean {
	const hour = moment.getHours();

	return hour < NIGHT_ENDS_AT_HOUR || hour >= NIGHT_STARTS_AT_HOUR;
}

function timeOfDay( moment: Date ): string {
	return new Intl.DateTimeFormat( currentLocale(), {
		hour: '2-digit',
		minute: '2-digit',
		hourCycle: 'h23',
	} ).format( moment );
}

function withinADay( moment: Date, now: number ): string {
	const time = timeOfDay( moment );

	if ( isNight( moment ) ) {
		/* translators: %s: time of day, for example 02:00 */
		return sprintf( __( 'Tonight, %s', 'aiplaz-link-checkup' ), time );
	}

	if ( moment.getDate() === new Date( now ).getDate() ) {
		/* translators: %s: time of day, for example 14:00 */
		return sprintf( __( 'Today, %s', 'aiplaz-link-checkup' ), time );
	}

	/* translators: %s: time of day, for example 09:00 */
	return sprintf( __( 'Tomorrow, %s', 'aiplaz-link-checkup' ), time );
}

export function timeUntil( isoTime: string, now: number ): string {
	const moment = new Date( isoTime );
	const secondsLeft = ( moment.getTime() - now ) / MILLISECONDS_PER_SECOND;

	if ( secondsLeft < SECONDS_PER_HOUR ) {
		return sprintf(
			/* translators: %s: time left as minutes and seconds, for example 00:40 */
			__( 'in %s', 'aiplaz-link-checkup' ),
			clock( secondsLeft )
		);
	}

	if ( secondsLeft < SECONDS_PER_DAY ) {
		return withinADay( moment, now );
	}

	const weekday = new Intl.DateTimeFormat( currentLocale(), {
		weekday: 'long',
	} ).format( moment );

	return `${ weekday }, ${ timeOfDay( moment ) }`;
}
