import { Button } from '@theorchard/suite-components';
import dayjs from 'dayjs';
import React from 'react';
import DateTimePicker from '../dateTimePicker';
import TimeOffsetPicker from '../timeOffsetPicker';
import TimezoneBreakdown from '../timezoneBreakdown';
import TimezoneConverterLink from '../timezoneConverterLink';
import type { FC } from 'react';
import type {
    AddToTimedReleaseParams,
    DeliveryStore,
    Timezone,
} from 'src/types';

export interface TimedReleaseTimeSelectorProps {
    saleDateTime?: Date;
    timeOffset: string;
    existingSaleDateTime?: Date;
    existingTimeOffset?: string;
    hasTimedReleases: boolean;
    onPrevious: () => void;
    onSaleDateTimeChange: (date: Date) => void;
    onTimeOffsetChange: (offset: string) => void;
    onAddToSchedule: (params: AddToTimedReleaseParams) => void;
    selectedUnsupportedStores: DeliveryStore[];
    selectedSupportedStores: DeliveryStore[];
}

/**
 * Attempt to retrieve Timezone object from the browser. Intl.DateTimeFormat is
 * not universally supported by browsers, so return undefined if errors occur.
 */
const getBrowserTimezone = (): Timezone | undefined => {
    try {
        return {
            iana: Intl.DateTimeFormat().resolvedOptions().timeZone,
            abbreviation: $t(
                'releaseScheduler.timedReleaseTimeSelector.yourTimezone'
            ),
            offset: -(new Date().getTimezoneOffset() / 60),
        };
    } catch {
        return undefined;
    }
};

const timezones: Timezone[] = [
    { iana: 'America/Los_Angeles', offset: -8, abbreviation: 'PT' },
    { iana: 'America/New_York', offset: -5, abbreviation: 'ET' },
    { iana: 'Australia/Sydney', offset: 10, abbreviation: 'AET' },
    getBrowserTimezone(),
].filter(timezone => !!timezone) as Timezone[];

const TimedReleaseTimeSelector: FC<TimedReleaseTimeSelectorProps> = ({
    onPrevious,
    saleDateTime,
    timeOffset,
    existingSaleDateTime,
    existingTimeOffset,
    hasTimedReleases,
    onSaleDateTimeChange,
    onTimeOffsetChange,
    onAddToSchedule,
    selectedUnsupportedStores,
    selectedSupportedStores,
}) => {
    return (
        <div className="TimedReleaseTimeSelector">
            <div className="TimedReleaseTimeSelector-prompt">
                {$t('releaseScheduler.timedReleaseTimeSelector.timeHeader')}
            </div>
            <div className="TimeSelector-body">
                <DateTimePicker
                    enabled={!hasTimedReleases}
                    disabledMessage={$t(
                        'releaseScheduler.timedReleaseTimeSelector.disabledMessage'
                    )}
                    labelTimeFormat="h:mma"
                    timeLabelFormatter={formattedTime => {
                        return `${$t(
                            'releaseScheduler.timedReleaseTimeSelector.timeInGMT',
                            {
                                time: formattedTime,
                            }
                        )}`;
                    }}
                    dateTime={existingSaleDateTime || saleDateTime}
                    onDateTimeChange={onSaleDateTimeChange}
                />
                {saleDateTime && (
                    <TimezoneBreakdown
                        className="TimedReleaseTimeSelector-timezone-breakdown"
                        timezones={timezones}
                        date={existingSaleDateTime || saleDateTime}
                    />
                )}
                <div className="TimedReleaseTimeSelector-timezone-converter-link">
                    <TimezoneConverterLink
                        dateTime={dayjs
                            .utc(existingSaleDateTime || saleDateTime)
                            .toISOString()}
                    />
                </div>
                {selectedUnsupportedStores.length > 0 ? (
                    <>
                        <hr className="TimedReleaseTimeSelector-separator" />
                        <p className="TimedReleaseTimeSelector-schedule-prompt">
                            {$t(
                                'releaseScheduler.timedReleaseTimeSelector.schedulePrompt',
                                {
                                    deliveryStoreCount:
                                        selectedUnsupportedStores.length,
                                }
                            )}
                        </p>
                        <div className="TimedReleaseTimeSelector-time-offset">
                            <label className="TimedReleaseTimeSelector-offset-prompt-label">
                                {$t(
                                    'releaseScheduler.timedReleaseTimeSelector.timeOffsetPrompt'
                                )}
                            </label>
                            <TimeOffsetPicker
                                options={['01:00', '00:45', '00:30', '00:15']}
                                onChange={onTimeOffsetChange}
                                value={existingTimeOffset || timeOffset}
                                disabledMessage={$t(
                                    'releaseScheduler.timedReleaseTimeSelector.timeOffsetSelected'
                                )}
                                enabled={!existingTimeOffset}
                                formatHours={() =>
                                    $t(
                                        'releaseScheduler.timedReleaseTimeSelector.hourOffset'
                                    )
                                }
                                formatMinutes={minutes =>
                                    $t(
                                        'releaseScheduler.timedReleaseTimeSelector.minutesOffset',
                                        { minutes }
                                    )
                                }
                            />
                        </div>
                    </>
                ) : null}
            </div>
            <div className="TimedReleaseTimeSelector-button-bar">
                <Button data-testid="back-button" onClick={onPrevious}>
                    {$t('releaseScheduler.timedReleaseTimeSelector.back')}
                </Button>
                <Button
                    onClick={() => {
                        if (!saleDateTime) return;
                        // it would be great if these were dates all the way up
                        const saleDateTimeString = existingSaleDateTime
                            ? dayjs
                                  .utc(existingSaleDateTime)
                                  .format('YYYY-MM-DDTHH:mm:ss[Z]')
                            : dayjs
                                  .utc(saleDateTime)
                                  .format('YYYY-MM-DDTHH:mm:ss[Z]');
                        onAddToSchedule({
                            timed: selectedSupportedStores.map(
                                deliveryStore => ({
                                    deliveryStore,
                                    saleDateTime: saleDateTimeString,
                                })
                            ),
                            unsupportedTimed: selectedUnsupportedStores.map(
                                deliveryStore => ({
                                    deliveryStore,
                                    saleDateTime: saleDateTimeString,
                                    timeOffset:
                                        existingTimeOffset || timeOffset,
                                })
                            ),
                        });
                        window.location.hash = '';
                        window.location.hash = 'Timed-Releases';
                    }}
                >
                    {$t(
                        'releaseScheduler.timedReleaseTimeSelector.addToSchedule'
                    )}
                </Button>
            </div>
        </div>
    );
};

export default TimedReleaseTimeSelector;
