// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart' as intl;

import 'l10n/generated_cupertino_localizations.dart';
import 'utils/date_localizations.dart' as util;
import 'widgets_localizations.dart';

/// Implementation of localized strings for Cupertino widgets using the `intl`
/// package for date and time formatting.
///
/// Further localization of strings beyond date time formatting are provided
/// by language specific subclasses of [GlobalCupertinoLocalizations].
///
/// ## Supported languages
///
/// This class supports locales with the following [Locale.languageCode]s:
///
/// {@macro flutter.localizations.cupertino.languages}
///
/// This list is available programmatically via [kCupertinoSupportedLanguages].
///
/// ## Sample code
///
/// To include the localizations provided by this class in a [CupertinoApp],
/// add [GlobalCupertinoLocalizations.delegates] to
/// [CupertinoApp.localizationsDelegates], and specify the locales your
/// app supports with [CupertinoApp.supportedLocales]:
///
/// ```dart
/// CupertinoApp(
///   localizationsDelegates: GlobalCupertinoLocalizations.delegates,
///   supportedLocales: [
///     const Locale('en', 'US'), // American English
///     const Locale('he', 'IL'), // Israeli Hebrew
///     // ...
///   ],
///   // ...
/// )
/// ```
///
/// See also:
///
///  * [DefaultCupertinoLocalizations], which provides US English localizations
///    for Cupertino widgets.
abstract class GlobalCupertinoLocalizations implements CupertinoLocalizations {
  /// Initializes an object that defines the Cupertino widgets' localized
  /// strings for the given `localeName`.
  ///
  /// The remaining '*Format' arguments uses the intl package to provide
  /// [DateFormat] configurations for the `localeName`.
  const GlobalCupertinoLocalizations({
    required String localeName,
    required intl.DateFormat fullYearFormat,
    required intl.DateFormat dayFormat,
    required intl.DateFormat mediumDateFormat,
    required intl.DateFormat singleDigitHourFormat,
    required intl.DateFormat singleDigitMinuteFormat,
    required intl.DateFormat doubleDigitMinuteFormat,
    required intl.DateFormat singleDigitSecondFormat,
    required intl.NumberFormat decimalFormat,
  }) : assert(localeName != null),
       _localeName = localeName,
       assert(fullYearFormat != null),
       _fullYearFormat = fullYearFormat,
       assert(dayFormat != null),
       _dayFormat = dayFormat,
       assert(mediumDateFormat != null),
       _mediumDateFormat = mediumDateFormat,
       assert(singleDigitHourFormat != null),
       _singleDigitHourFormat = singleDigitHourFormat,
       assert(singleDigitMinuteFormat != null),
       _singleDigitMinuteFormat = singleDigitMinuteFormat,
       assert(doubleDigitMinuteFormat != null),
       _doubleDigitMinuteFormat = doubleDigitMinuteFormat,
       assert(singleDigitSecondFormat != null),
       _singleDigitSecondFormat = singleDigitSecondFormat,
       assert(decimalFormat != null),
       _decimalFormat =decimalFormat;

  final String _localeName;
  final intl.DateFormat _fullYearFormat;
  final intl.DateFormat _dayFormat;
  final intl.DateFormat _mediumDateFormat;
  final intl.DateFormat _singleDigitHourFormat;
  final intl.DateFormat _singleDigitMinuteFormat;
  final intl.DateFormat _doubleDigitMinuteFormat;
  final intl.DateFormat _singleDigitSecondFormat;
  final intl.NumberFormat _decimalFormat;

  @override
  String datePickerYear(int yearIndex) {
    return _fullYearFormat.format(DateTime.utc(yearIndex));
  }

  @override
  String datePickerMonth(int monthIndex) {
    // It doesn't actually have anything to do with _fullYearFormat. It's just
    // taking advantage of the fact that _fullYearFormat loaded the needed
    // locale's symbols.
    return _fullYearFormat.dateSymbols.MONTHS[monthIndex - 1];
  }

  @override
  String datePickerDayOfMonth(int dayIndex) {
    // Year and month doesn't matter since we just want to day formatted.
    return _dayFormat.format(DateTime.utc(0, 0, dayIndex));
  }

  @override
  String datePickerMediumDate(DateTime date) {
    return _mediumDateFormat.format(date);
  }

  @override
  String datePickerHour(int hour) {
    return _singleDigitHourFormat.format(DateTime.utc(0, 0, 0, hour));
  }

  @override
  String datePickerMinute(int minute) {
    return _doubleDigitMinuteFormat.format(DateTime.utc(0, 0, 0, 0, minute));
  }

  /// Subclasses should provide the optional zero pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerHourSemanticsLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerHourSemanticsLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerHourSemanticsLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerHourSemanticsLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerHourSemanticsLabelMany => null;
  /// Subclasses should provide the required other pluralization of [datePickerHourSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerHourSemanticsLabelOther;

  @override
  String? datePickerHourSemanticsLabel(int hour) {
    return intl.Intl.pluralLogic(
      hour,
      zero: datePickerHourSemanticsLabelZero,
      one: datePickerHourSemanticsLabelOne,
      two: datePickerHourSemanticsLabelTwo,
      few: datePickerHourSemanticsLabelFew,
      many: datePickerHourSemanticsLabelMany,
      other: datePickerHourSemanticsLabelOther,
      locale: _localeName,
    )?.replaceFirst(r'$hour', _decimalFormat.format(hour));
  }

  /// Subclasses should provide the optional zero pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerMinuteSemanticsLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerMinuteSemanticsLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerMinuteSemanticsLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerMinuteSemanticsLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerMinuteSemanticsLabelMany => null;
  /// Subclasses should provide the required other pluralization of [datePickerMinuteSemanticsLabel] based on the ARB file.
  @protected
  String? get datePickerMinuteSemanticsLabelOther;

  @override
  String? datePickerMinuteSemanticsLabel(int minute) {
    return intl.Intl.pluralLogic(
      minute,
      zero: datePickerMinuteSemanticsLabelZero,
      one: datePickerMinuteSemanticsLabelOne,
      two: datePickerMinuteSemanticsLabelTwo,
      few: datePickerMinuteSemanticsLabelFew,
      many: datePickerMinuteSemanticsLabelMany,
      other: datePickerMinuteSemanticsLabelOther,
      locale: _localeName,
    )?.replaceFirst(r'$minute', _decimalFormat.format(minute));
  }

  /// A string describing the [DatePickerDateOrder] enum value.
  ///
  /// Subclasses should provide this string value based on the ARB file for
  /// the locale.
  ///
  /// See also:
  ///
  ///  * [datePickerDateOrder], which provides the [DatePickerDateOrder]
  ///    enum value for [CupertinoLocalizations] based on this string value
  @protected
  String get datePickerDateOrderString;

  @override
  DatePickerDateOrder get datePickerDateOrder {
    switch (datePickerDateOrderString) {
      case 'dmy':
        return DatePickerDateOrder.dmy;
      case 'mdy':
        return DatePickerDateOrder.mdy;
      case 'ymd':
        return DatePickerDateOrder.ymd;
      case 'ydm':
        return DatePickerDateOrder.ydm;
      default:
        assert(
          false,
          'Failed to load DatePickerDateOrder $datePickerDateOrderString for '
          "locale $_localeName.\nNon conforming string for $_localeName's "
          '.arb file',
        );
        return DatePickerDateOrder.mdy;
    }
  }

  /// A string describing the [DatePickerDateTimeOrder] enum value.
  ///
  /// Subclasses should provide this string value based on the ARB file for
  /// the locale.
  ///
  /// See also:
  ///
  ///  * [datePickerDateTimeOrder], which provides the [DatePickerDateTimeOrder]
  ///    enum value for [CupertinoLocalizations] based on this string value.
  @protected
  String get datePickerDateTimeOrderString;

  @override
  DatePickerDateTimeOrder get datePickerDateTimeOrder {
    switch (datePickerDateTimeOrderString) {
      case 'date_time_dayPeriod':
        return DatePickerDateTimeOrder.date_time_dayPeriod;
      case 'date_dayPeriod_time':
        return DatePickerDateTimeOrder.date_dayPeriod_time;
      case 'time_dayPeriod_date':
        return DatePickerDateTimeOrder.time_dayPeriod_date;
      case 'dayPeriod_time_date':
        return DatePickerDateTimeOrder.dayPeriod_time_date;
      default:
        assert(
          false,
          'Failed to load DatePickerDateTimeOrder $datePickerDateTimeOrderString '
          "for locale $_localeName.\nNon conforming string for $_localeName's "
          '.arb file',
        );
        return DatePickerDateTimeOrder.date_time_dayPeriod;
    }
  }

  /// The raw version of [tabSemanticsLabel], with `$tabIndex` and `$tabCount` verbatim
  /// in the string.
  @protected
  String get tabSemanticsLabelRaw;

  @override
  String tabSemanticsLabel({ required int tabIndex, required int tabCount }) {
    assert(tabIndex >= 1);
    assert(tabCount >= 1);
    final String template = tabSemanticsLabelRaw;
    return template
      .replaceFirst(r'$tabIndex', _decimalFormat.format(tabIndex))
      .replaceFirst(r'$tabCount', _decimalFormat.format(tabCount));
  }

  @override
  String timerPickerHour(int hour) {
    return _singleDigitHourFormat.format(DateTime.utc(0, 0, 0, hour));
  }

  @override
  String timerPickerMinute(int minute) {
    return _singleDigitMinuteFormat.format(DateTime.utc(0, 0, 0, 0, minute));
  }

  @override
  String timerPickerSecond(int second) {
    return _singleDigitSecondFormat.format(DateTime.utc(0, 0, 0, 0, 0, second));
  }

  /// Subclasses should provide the optional zero pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected
  String? get timerPickerHourLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected
  String? get timerPickerHourLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected
  String? get timerPickerHourLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected
  String? get timerPickerHourLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected
  String? get timerPickerHourLabelMany => null;
  /// Subclasses should provide the required other pluralization of [timerPickerHourLabel] based on the ARB file.
  @protected
  String? get timerPickerHourLabelOther;

  @override
  String? timerPickerHourLabel(int hour) {
    return intl.Intl.pluralLogic(
      hour,
      zero: timerPickerHourLabelZero,
      one: timerPickerHourLabelOne,
      two: timerPickerHourLabelTwo,
      few: timerPickerHourLabelFew,
      many: timerPickerHourLabelMany,
      other: timerPickerHourLabelOther,
      locale: _localeName,
    )?.replaceFirst(r'$hour', _decimalFormat.format(hour));
  }

  @override
  List<String> get timerPickerHourLabels => <String>[
    if (timerPickerHourLabelZero != null) timerPickerHourLabelZero!,
    if (timerPickerHourLabelOne != null) timerPickerHourLabelOne!,
    if (timerPickerHourLabelTwo != null) timerPickerHourLabelTwo!,
    if (timerPickerHourLabelFew != null) timerPickerHourLabelFew!,
    if (timerPickerHourLabelMany != null) timerPickerHourLabelMany!,
    if (timerPickerHourLabelOther != null) timerPickerHourLabelOther!,
  ];

  /// Subclasses should provide the optional zero pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected
  String? get timerPickerMinuteLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected
  String? get timerPickerMinuteLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected
  String? get timerPickerMinuteLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected
  String? get timerPickerMinuteLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected
  String? get timerPickerMinuteLabelMany => null;
  /// Subclasses should provide the required other pluralization of [timerPickerMinuteLabel] based on the ARB file.
  @protected
  String? get timerPickerMinuteLabelOther;

  @override
  String? timerPickerMinuteLabel(int minute) {
    return intl.Intl.pluralLogic(
      minute,
      zero: timerPickerMinuteLabelZero,
      one: timerPickerMinuteLabelOne,
      two: timerPickerMinuteLabelTwo,
      few: timerPickerMinuteLabelFew,
      many: timerPickerMinuteLabelMany,
      other: timerPickerMinuteLabelOther,
      locale: _localeName,
    )?.replaceFirst(r'$minute', _decimalFormat.format(minute));
  }

  @override
  List<String> get timerPickerMinuteLabels => <String>[
    if (timerPickerMinuteLabelZero != null) timerPickerMinuteLabelZero!,
    if (timerPickerMinuteLabelOne != null) timerPickerMinuteLabelOne!,
    if (timerPickerMinuteLabelTwo != null) timerPickerMinuteLabelTwo!,
    if (timerPickerMinuteLabelFew != null) timerPickerMinuteLabelFew!,
    if (timerPickerMinuteLabelMany != null) timerPickerMinuteLabelMany!,
    if (timerPickerMinuteLabelOther != null) timerPickerMinuteLabelOther!,
  ];

  /// Subclasses should provide the optional zero pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected
  String? get timerPickerSecondLabelZero => null;
  /// Subclasses should provide the optional one pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected
  String? get timerPickerSecondLabelOne => null;
  /// Subclasses should provide the optional two pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected
  String? get timerPickerSecondLabelTwo => null;
  /// Subclasses should provide the optional few pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected
  String? get timerPickerSecondLabelFew => null;
  /// Subclasses should provide the optional many pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected
  String? get timerPickerSecondLabelMany => null;
  /// Subclasses should provide the required other pluralization of [timerPickerSecondLabel] based on the ARB file.
  @protected
  String? get timerPickerSecondLabelOther;

  @override
  String? timerPickerSecondLabel(int second) {
    return intl.Intl.pluralLogic(
      second,
      zero: timerPickerSecondLabelZero,
      one: timerPickerSecondLabelOne,
      two: timerPickerSecondLabelTwo,
      few: timerPickerSecondLabelFew,
      many: timerPickerSecondLabelMany,
      other: timerPickerSecondLabelOther,
      locale: _localeName,
    )?.replaceFirst(r'$second', _decimalFormat.format(second));
  }

  @override
  List<String> get timerPickerSecondLabels => <String>[
    if (timerPickerSecondLabelZero != null) timerPickerSecondLabelZero!,
    if (timerPickerSecondLabelOne != null) timerPickerSecondLabelOne!,
    if (timerPickerSecondLabelTwo != null) timerPickerSecondLabelTwo!,
    if (timerPickerSecondLabelFew != null) timerPickerSecondLabelFew!,
    if (timerPickerSecondLabelMany != null) timerPickerSecondLabelMany!,
    if (timerPickerSecondLabelOther != null) timerPickerSecondLabelOther!,
  ];

  /// A [LocalizationsDelegate] for [CupertinoLocalizations].
  ///
  /// Most internationalized apps will use [GlobalCupertinoLocalizations.delegates]
  /// as the value of [CupertinoApp.localizationsDelegates] to include
  /// the localizations for both the cupertino and widget libraries.
  static const LocalizationsDelegate<CupertinoLocalizations> delegate = _GlobalCupertinoLocalizationsDelegate();

  /// A value for [CupertinoApp.localizationsDelegates] that's typically used by
  /// internationalized apps.
  ///
  /// ## Sample code
  ///
  /// To include the localizations provided by this class and by
  /// [GlobalWidgetsLocalizations] in a [CupertinoApp],
  /// use [GlobalCupertinoLocalizations.delegates] as the value of
  /// [CupertinoApp.localizationsDelegates], and specify the locales your
  /// app supports with [CupertinoApp.supportedLocales]:
  ///
  /// ```dart
  /// CupertinoApp(
  ///   localizationsDelegates: GlobalCupertinoLocalizations.delegates,
  ///   supportedLocales: [
  ///     const Locale('en', 'US'), // English
  ///     const Locale('he', 'IL'), // Hebrew
  ///   ],
  ///   // ...
  /// )
  /// ```
  static const List<LocalizationsDelegate<dynamic>> delegates = <LocalizationsDelegate<dynamic>>[
    GlobalCupertinoLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
  ];
}

class _GlobalCupertinoLocalizationsDelegate extends LocalizationsDelegate<CupertinoLocalizations> {
  const _GlobalCupertinoLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => kCupertinoSupportedLanguages.contains(locale.languageCode);

  static final Map<Locale, Future<CupertinoLocalizations>> _loadedTranslations = <Locale, Future<CupertinoLocalizations>>{};

  @override
  Future<CupertinoLocalizations> load(Locale locale) {
    assert(isSupported(locale));
    return _loadedTranslations.putIfAbsent(locale, () {
      util.loadDateIntlDataIfNotLoaded();

      final String localeName = intl.Intl.canonicalizedLocale(locale.toString());
      assert(
        locale.toString() == localeName,
        'Flutter does not support the non-standard locale form $locale (which '
        'might be $localeName',
      );

      late intl.DateFormat fullYearFormat;
      late intl.DateFormat dayFormat;
      late intl.DateFormat mediumDateFormat;
      // We don't want any additional decoration here. The am/pm is handled in
      // the date picker. We just want an hour number localized.
      late intl.DateFormat singleDigitHourFormat;
      late intl.DateFormat singleDigitMinuteFormat;
      late intl.DateFormat doubleDigitMinuteFormat;
      late intl.DateFormat singleDigitSecondFormat;
      late intl.NumberFormat decimalFormat;

      void loadFormats(String? locale) {
        fullYearFormat = intl.DateFormat.y(locale);
        dayFormat = intl.DateFormat.d(locale);
        mediumDateFormat = intl.DateFormat.MMMEd(locale);
        // TODO(xster): fix when https://github.com/dart-lang/intl/issues/207 is resolved.
        singleDigitHourFormat = intl.DateFormat('HH', locale);
        singleDigitMinuteFormat = intl.DateFormat.m(locale);
        doubleDigitMinuteFormat = intl.DateFormat('mm', locale);
        singleDigitSecondFormat = intl.DateFormat.s(locale);
        decimalFormat = intl.NumberFormat.decimalPattern(locale);
      }

      if (intl.DateFormat.localeExists(localeName)) {
        loadFormats(localeName);
      } else if (intl.DateFormat.localeExists(locale.languageCode)) {
        loadFormats(locale.languageCode);
      } else {
        loadFormats(null);
      }

      return SynchronousFuture<CupertinoLocalizations>(getCupertinoTranslation(
        locale,
        fullYearFormat,
        dayFormat,
        mediumDateFormat,
        singleDigitHourFormat,
        singleDigitMinuteFormat,
        doubleDigitMinuteFormat,
        singleDigitSecondFormat,
        decimalFormat,
      )!);
    });
  }

  @override
  bool shouldReload(_GlobalCupertinoLocalizationsDelegate old) => false;

  @override
  String toString() => 'GlobalCupertinoLocalizations.delegate(${kCupertinoSupportedLanguages.length} locales)';
}
