import 'dart:async';

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

import 'app_localizations_en.dart';
import 'app_localizations_ja.dart';
import 'app_localizations_ko.dart';
import 'app_localizations_zh.dart';

// ignore_for_file: type=lint

/// Callers can lookup localized strings with an instance of L10n
/// returned by `L10n.of(context)`.
///
/// Applications need to include `L10n.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_localizations.dart';
///
/// return MaterialApp(
///   localizationsDelegates: L10n.localizationsDelegates,
///   supportedLocales: L10n.supportedLocales,
///   home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
///   # Internationalization support.
///   flutter_localizations:
///     sdk: flutter
///   intl: any # Use the pinned version from flutter_localizations
///
///   # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, you’ll need to edit this
/// file.
///
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// project’s Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the L10n.supportedLocales
/// property.
abstract class L10n {
  L10n(String locale)
    : localeName = intl.Intl.canonicalizedLocale(locale.toString());

  final String localeName;

  static L10n of(BuildContext context) {
    return Localizations.of<L10n>(context, L10n)!;
  }

  static const LocalizationsDelegate<L10n> delegate = _L10nDelegate();

  /// A list of this localizations delegate along with the default localizations
  /// delegates.
  ///
  /// Returns a list of localizations delegates containing this delegate along with
  /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
  /// and GlobalWidgetsLocalizations.delegate.
  ///
  /// Additional delegates can be added by appending to this list in
  /// MaterialApp. This list does not have to be used at all if a custom list
  /// of delegates is preferred or required.
  static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
      <LocalizationsDelegate<dynamic>>[
        delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ];

  /// A list of this localizations delegate's supported locales.
  static const List<Locale> supportedLocales = <Locale>[
    Locale('en'),
    Locale('ja'),
    Locale('ko'),
    Locale('zh'),
  ];

  /// Application title
  ///
  /// In en, this message translates to:
  /// **'ASCII NEVER DIE'**
  String get appTitle;

  /// Tag indicating offline mode
  ///
  /// In en, this message translates to:
  /// **'No network'**
  String get tagNoNetwork;

  /// Tag indicating idle RPG gameplay
  ///
  /// In en, this message translates to:
  /// **'Idle RPG loop'**
  String get tagIdleRpg;

  /// Tag indicating local save support
  ///
  /// In en, this message translates to:
  /// **'Local saves'**
  String get tagLocalSaves;

  /// New character button
  ///
  /// In en, this message translates to:
  /// **'New character'**
  String get newCharacter;

  /// Load save button
  ///
  /// In en, this message translates to:
  /// **'Load save'**
  String get loadSave;

  /// Load game dialog title
  ///
  /// In en, this message translates to:
  /// **'Load Game'**
  String get loadGame;

  /// View build plan button
  ///
  /// In en, this message translates to:
  /// **'View build plan'**
  String get viewBuildPlan;

  /// Build roadmap section title
  ///
  /// In en, this message translates to:
  /// **'Build roadmap'**
  String get buildRoadmap;

  /// Tech stack section title
  ///
  /// In en, this message translates to:
  /// **'Tech stack'**
  String get techStack;

  /// Cancel button
  ///
  /// In en, this message translates to:
  /// **'Cancel'**
  String get cancel;

  /// Exit game dialog title
  ///
  /// In en, this message translates to:
  /// **'Exit Game'**
  String get exitGame;

  /// Save progress confirmation message
  ///
  /// In en, this message translates to:
  /// **'Save your progress before leaving?'**
  String get saveProgressQuestion;

  /// Exit without saving button
  ///
  /// In en, this message translates to:
  /// **'Exit without saving'**
  String get exitWithoutSaving;

  /// Save and exit button
  ///
  /// In en, this message translates to:
  /// **'Save and Exit'**
  String get saveAndExit;

  /// Game screen title with character name
  ///
  /// In en, this message translates to:
  /// **'ASCII NEVER DIE - {name}'**
  String progressQuestTitle(String name);

  /// Level up tooltip
  ///
  /// In en, this message translates to:
  /// **'Level Up'**
  String get levelUp;

  /// Complete quest tooltip
  ///
  /// In en, this message translates to:
  /// **'Complete Quest'**
  String get completeQuest;

  /// Complete plot tooltip
  ///
  /// In en, this message translates to:
  /// **'Complete Plot'**
  String get completePlot;

  /// Character sheet panel title
  ///
  /// In en, this message translates to:
  /// **'Character Sheet'**
  String get characterSheet;

  /// Traits section title
  ///
  /// In en, this message translates to:
  /// **'Traits'**
  String get traits;

  /// Stats section title
  ///
  /// In en, this message translates to:
  /// **'Stats'**
  String get stats;

  /// Experience section title
  ///
  /// In en, this message translates to:
  /// **'Experience'**
  String get experience;

  /// XP needed tooltip
  ///
  /// In en, this message translates to:
  /// **'XP needed for next level'**
  String get xpNeededForNextLevel;

  /// Skills section title (unified spellbook + skills)
  ///
  /// In en, this message translates to:
  /// **'Skills'**
  String get spellBook;

  /// Empty skills message
  ///
  /// In en, this message translates to:
  /// **'No skills yet'**
  String get noSpellsYet;

  /// Equipment panel title
  ///
  /// In en, this message translates to:
  /// **'Equipment'**
  String get equipment;

  /// Inventory panel title
  ///
  /// In en, this message translates to:
  /// **'Inventory'**
  String get inventory;

  /// Encumbrance section title
  ///
  /// In en, this message translates to:
  /// **'Encumbrance'**
  String get encumbrance;

  /// Combat log panel title
  ///
  /// In en, this message translates to:
  /// **'Combat Log'**
  String get combatLog;

  /// Plot development panel title
  ///
  /// In en, this message translates to:
  /// **'Plot Development'**
  String get plotDevelopment;

  /// Quests panel title
  ///
  /// In en, this message translates to:
  /// **'Quests'**
  String get quests;

  /// Name trait label
  ///
  /// In en, this message translates to:
  /// **'Name'**
  String get traitName;

  /// Race trait label
  ///
  /// In en, this message translates to:
  /// **'Race'**
  String get traitRace;

  /// Class trait label
  ///
  /// In en, this message translates to:
  /// **'Class'**
  String get traitClass;

  /// Level trait label
  ///
  /// In en, this message translates to:
  /// **'Level'**
  String get traitLevel;

  /// Strength stat
  ///
  /// In en, this message translates to:
  /// **'STR'**
  String get statStr;

  /// Constitution stat
  ///
  /// In en, this message translates to:
  /// **'CON'**
  String get statCon;

  /// Dexterity stat
  ///
  /// In en, this message translates to:
  /// **'DEX'**
  String get statDex;

  /// Intelligence stat
  ///
  /// In en, this message translates to:
  /// **'INT'**
  String get statInt;

  /// Wisdom stat
  ///
  /// In en, this message translates to:
  /// **'WIS'**
  String get statWis;

  /// Charisma stat
  ///
  /// In en, this message translates to:
  /// **'CHA'**
  String get statCha;

  /// Max HP stat
  ///
  /// In en, this message translates to:
  /// **'HP Max'**
  String get statHpMax;

  /// Max MP stat
  ///
  /// In en, this message translates to:
  /// **'MP Max'**
  String get statMpMax;

  /// Weapon equipment slot
  ///
  /// In en, this message translates to:
  /// **'Weapon'**
  String get equipWeapon;

  /// Shield equipment slot
  ///
  /// In en, this message translates to:
  /// **'Shield'**
  String get equipShield;

  /// Helm equipment slot
  ///
  /// In en, this message translates to:
  /// **'Helm'**
  String get equipHelm;

  /// Hauberk equipment slot
  ///
  /// In en, this message translates to:
  /// **'Hauberk'**
  String get equipHauberk;

  /// Brassairts equipment slot
  ///
  /// In en, this message translates to:
  /// **'Brassairts'**
  String get equipBrassairts;

  /// Vambraces equipment slot
  ///
  /// In en, this message translates to:
  /// **'Vambraces'**
  String get equipVambraces;

  /// Gauntlets equipment slot
  ///
  /// In en, this message translates to:
  /// **'Gauntlets'**
  String get equipGauntlets;

  /// Gambeson equipment slot
  ///
  /// In en, this message translates to:
  /// **'Gambeson'**
  String get equipGambeson;

  /// Cuisses equipment slot
  ///
  /// In en, this message translates to:
  /// **'Cuisses'**
  String get equipCuisses;

  /// Greaves equipment slot
  ///
  /// In en, this message translates to:
  /// **'Greaves'**
  String get equipGreaves;

  /// Sollerets equipment slot
  ///
  /// In en, this message translates to:
  /// **'Sollerets'**
  String get equipSollerets;

  /// Coin label
  ///
  /// In en, this message translates to:
  /// **'Coin'**
  String get gold;

  /// Coin with amount
  ///
  /// In en, this message translates to:
  /// **'Coin: {amount}'**
  String goldAmount(int amount);

  /// Prologue plot stage
  ///
  /// In en, this message translates to:
  /// **'Prologue'**
  String get prologue;

  /// Act with roman numeral
  ///
  /// In en, this message translates to:
  /// **'Act {number}'**
  String actNumber(String number);

  /// Empty quests message
  ///
  /// In en, this message translates to:
  /// **'No active quests'**
  String get noActiveQuests;

  /// Quest with number
  ///
  /// In en, this message translates to:
  /// **'Quest #{number}'**
  String questNumber(int number);

  /// Welcome message in task progress panel
  ///
  /// In en, this message translates to:
  /// **'Welcome to ASCII NEVER DIE!'**
  String get welcomeMessage;

  /// No saved games message
  ///
  /// In en, this message translates to:
  /// **'No saved games found.'**
  String get noSavedGames;

  /// Load error message
  ///
  /// In en, this message translates to:
  /// **'Failed to load save file: {error}'**
  String loadError(String error);

  /// Name label in character creation
  ///
  /// In en, this message translates to:
  /// **'Name'**
  String get name;

  /// Generate name tooltip
  ///
  /// In en, this message translates to:
  /// **'Generate Name'**
  String get generateName;

  /// Total label for stats
  ///
  /// In en, this message translates to:
  /// **'Total'**
  String get total;

  /// Undo button for stat reroll
  ///
  /// In en, this message translates to:
  /// **'Undo'**
  String get unroll;

  /// Roll button
  ///
  /// In en, this message translates to:
  /// **'Roll'**
  String get roll;

  /// Race selection title
  ///
  /// In en, this message translates to:
  /// **'Race'**
  String get race;

  /// Class selection title
  ///
  /// In en, this message translates to:
  /// **'Class'**
  String get classTitle;

  /// Percentage complete
  ///
  /// In en, this message translates to:
  /// **'{percent}% complete'**
  String percentComplete(int percent);

  /// New character screen title
  ///
  /// In en, this message translates to:
  /// **'ASCII NEVER DIE - New Character'**
  String get newCharacterTitle;

  /// Confirm character creation button
  ///
  /// In en, this message translates to:
  /// **'Sold!'**
  String get soldButton;

  /// Victory overlay congratulations
  ///
  /// In en, this message translates to:
  /// **'★ CONGRATULATIONS ★'**
  String get endingCongratulations;

  /// Game completion message
  ///
  /// In en, this message translates to:
  /// **'You have completed the game!'**
  String get endingGameComplete;

  /// Hero section title
  ///
  /// In en, this message translates to:
  /// **'THE HERO'**
  String get endingTheHero;

  /// Level display format
  ///
  /// In en, this message translates to:
  /// **'Level {level}'**
  String endingLevelFormat(int level);

  /// Journey statistics section title
  ///
  /// In en, this message translates to:
  /// **'JOURNEY STATISTICS'**
  String get endingJourneyStats;

  /// Monsters killed stat label
  ///
  /// In en, this message translates to:
  /// **'Monsters Slain'**
  String get endingMonstersSlain;

  /// Quests completed stat label
  ///
  /// In en, this message translates to:
  /// **'Quests Completed'**
  String get endingQuestsCompleted;

  /// Play time stat label
  ///
  /// In en, this message translates to:
  /// **'Play Time'**
  String get endingPlayTime;

  /// Final stats section title
  ///
  /// In en, this message translates to:
  /// **'FINAL STATS'**
  String get endingFinalStats;

  /// Credits section title
  ///
  /// In en, this message translates to:
  /// **'CREDITS'**
  String get endingCredits;

  /// Thank you message
  ///
  /// In en, this message translates to:
  /// **'Thank you for playing!'**
  String get endingThankYou;

  /// Legend message
  ///
  /// In en, this message translates to:
  /// **'Your legend lives on...'**
  String get endingLegendLivesOn;

  /// Hall of fame message line 1
  ///
  /// In en, this message translates to:
  /// **'Your heroic deeds will be'**
  String get endingHallOfFameLine1;

  /// Hall of fame message line 2
  ///
  /// In en, this message translates to:
  /// **'remembered in the Hall of Fame'**
  String get endingHallOfFameLine2;

  /// Hall of fame button
  ///
  /// In en, this message translates to:
  /// **'HALL OF FAME'**
  String get endingHallOfFameButton;

  /// Skip button
  ///
  /// In en, this message translates to:
  /// **'SKIP'**
  String get endingSkip;

  /// Tap to skip hint
  ///
  /// In en, this message translates to:
  /// **'TAP TO SKIP'**
  String get endingTapToSkip;

  /// Hold to speed up scrolling hint
  ///
  /// In en, this message translates to:
  /// **'HOLD TO SPEED UP'**
  String get endingHoldToSpeedUp;
}

class _L10nDelegate extends LocalizationsDelegate<L10n> {
  const _L10nDelegate();

  @override
  Future<L10n> load(Locale locale) {
    return SynchronousFuture<L10n>(lookupL10n(locale));
  }

  @override
  bool isSupported(Locale locale) =>
      <String>['en', 'ja', 'ko', 'zh'].contains(locale.languageCode);

  @override
  bool shouldReload(_L10nDelegate old) => false;
}

L10n lookupL10n(Locale locale) {
  // Lookup logic when only language code is specified.
  switch (locale.languageCode) {
    case 'en':
      return L10nEn();
    case 'ja':
      return L10nJa();
    case 'ko':
      return L10nKo();
    case 'zh':
      return L10nZh();
  }

  throw FlutterError(
    'L10n.delegate failed to load unsupported locale "$locale". This is likely '
    'an issue with the localizations generation tool. Please file an issue '
    'on GitHub with a reproducible sample app and the gen-l10n configuration '
    'that was used.',
  );
}
