import 'package:flutter/material.dart';

import 'package:intl/intl.dart';

import 'package:provider/provider.dart';

import 'package:pshared/config/constants.dart';
import 'package:pshared/models/settings/localizations.dart' as loc;
import 'package:pshared/provider/locale.dart';


String currentLocale(BuildContext context) => Provider.of<LocaleProvider>(context, listen: false).locale.languageCode;

String _localizedString(
  BuildContext context,
  String Function(loc.Localizations locs, String locale, {String? fallback}) localizationFunction,
  loc.Localizations locs, {
  String? fallback,
}) => localizationFunction(locs, currentLocale(context), fallback: fallback);

String _anyLocalizedString(
  BuildContext context,
  String Function(loc.Localizations locs, String locale, {String? fallback}) localizationFunction,
  loc.Localizations locs, {
  String? fallback,
}) => localizationFunction(
  locs,
  currentLocale(context),
  fallback: localizationFunction(
    locs,
    Constants.defaultLocale.languageCode,
    fallback: locs.isEmpty 
      ? fallback
      : localizationFunction(
          locs,
          locs.keys.first,
          fallback: fallback,
        ),
  ),
);

String name(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.name, locs, fallback: fallback);
}

String anyName(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.name, locs, fallback: fallback);
}

String hint(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.hint, locs, fallback: fallback);
}

String anyHint(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.hint, locs, fallback: fallback);
}

String link(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.link, locs, fallback: fallback);
}

String anyLink(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.link, locs, fallback: fallback);
}

String error(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.error, locs, fallback: fallback);
}

String anyError(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.error, locs, fallback: fallback);
}

String address(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.address, locs, fallback: fallback);
}

String anyAddress(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.address, locs, fallback: fallback);
}

String details(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.details, locs, fallback: fallback);
}

String anyDetails(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.details, locs, fallback: fallback);
}

String route(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _localizedString(context, loc.Localization.route, locs, fallback: fallback);
}

String anyRoute(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.route, locs, fallback: fallback);
}

String anyLocationName(BuildContext context, loc.Localizations locs, {String? fallback}) {
  return _anyLocalizedString(context, loc.Localization.locationName, locs, fallback: fallback);
}

String translate(BuildContext context, loc.Localizations locs, String key, {String? fallback}) {
  return loc.Localization.translate(locs, currentLocale(context), key, fallback: fallback);
}


String anyTranslateFromLang(loc.Localizations locs, String lang, String key, {String? fallback}) => 
  loc.Localization.translate(locs, lang, key,
    fallback: loc.Localization.translate(locs, Constants.defaultLocale.languageCode, key,
      fallback: loc.Localization.translate(locs, locs.keys.first, key, fallback: fallback),
    ),
  );

String anyTranslate(BuildContext context, loc.Localizations locs, String key, {String? fallback}) =>
  anyTranslateFromLang(locs, currentLocale(context), key, fallback: fallback);

String dateToLocalFormat(BuildContext context, DateTime dateTime) {
  String locale = Provider.of<LocaleProvider>(context, listen: false).locale.toString();
  final dateFormat = DateFormat('E, ', locale).add_yMd();
  return dateFormat.format(dateTime);
}

String dateTimeToLocalFormat(BuildContext context, DateTime dateTime) {
  String locale = Provider.of<LocaleProvider>(context, listen: false).locale.toString();
  final dateFormat = DateFormat('E, ', locale).add_yMd().add_jm();
  return dateFormat.format(dateTime);
}

String dateTimeToLocalFormatAuto(BuildContext context, DateTime dateTime, bool? dateOnly) {
  return (dateOnly ?? false) ? dateToLocalFormat(context, dateTime) : dateTimeToLocalFormat(context, dateTime);
}

String dateTimeOrNullToLocalFormat(BuildContext context, DateTime? dateTime, {String? fallback}) {
  if (dateTime == null) return fallback ?? '';
  return dateTimeToLocalFormat(context, dateTime);
}
