import 'package:audio_service/audio_service.dart';
import 'package:country_pickers/country.dart';
import 'package:country_pickers/country_picker_dialog.dart';
import 'package:filesize/filesize.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
import 'package:fluttericon/font_awesome5_icons.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:freezer/api/cache.dart';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/api/download.dart';
import 'package:freezer/api/player.dart';
import 'package:freezer/ui/downloads_screen.dart';
import 'package:freezer/ui/elements.dart';
import 'package:freezer/ui/error.dart';
import 'package:freezer/ui/home_screen.dart';
import 'package:freezer/ui/updater.dart';
import 'package:i18n_extension/i18n_widget.dart';
import 'package:language_pickers/language_pickers.dart';
import 'package:language_pickers/languages.dart';
import 'package:package_info/package_info.dart';
import 'package:path_provider_ex/path_provider_ex.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:freezer/translations.i18n.dart';
import 'package:clipboard/clipboard.dart';
import 'package:scrobblenaut/scrobblenaut.dart';
import 'package:url_launcher/url_launcher.dart';

import '../settings.dart';
import '../main.dart';

import 'dart:io';

class SettingsScreen extends StatefulWidget {
  @override
  _SettingsScreenState createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {

  List<Map<String, String>> _languages() {
    //Missing language
    defaultLanguagesList.add({
      'name': 'Filipino',
      'isoCode': 'fil'
    });
    defaultLanguagesList.add({
      'name': 'Furry',
      'isoCode': 'uwu'
    });
    List<Map<String, String>> _l = supportedLocales.map<Map<String, String>>((l) {
      Map _lang = defaultLanguagesList.firstWhere((lang) => lang['isoCode'] == l.languageCode);
      return {
        'name': _lang['name'],
        'isoCode': _lang['isoCode'],
        'locale': l.toString()
      };
    }).toList();
    return _l;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('Settings'.i18n),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: Text('General'.i18n),
            leading: LeadingIcon(Icons.settings, color: Color(0xffeca704)),
            onTap: () => Navigator.of(context).push(MaterialPageRoute(
                builder: (context) => GeneralSettings()
            )),
          ),
          ListTile(
            title: Text('Download Settings'.i18n),
            leading: LeadingIcon(Icons.cloud_download, color: Color(0xffbe3266)),
            onTap: () => Navigator.of(context).push(MaterialPageRoute(
              builder: (context) => DownloadsSettings()
            )),
          ),
          ListTile(
            title: Text('Appearance'.i18n),
            leading: LeadingIcon(Icons.color_lens, color: Color(0xff4b2e7e)),
            onTap: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => AppearanceSettings())
            ),
          ),
          ListTile(
            title: Text('Quality'.i18n),
            leading: LeadingIcon(Icons.high_quality, color: Color(0xff384697)),
            onTap: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => QualitySettings())
            ),
          ),
          ListTile(
            title: Text('Deezer'.i18n),
            leading: LeadingIcon(Icons.equalizer, color: Color(0xff0880b5)),
            onTap: () => Navigator.push(context, MaterialPageRoute(
                builder: (context) => DeezerSettings()
            )),
          ),
          //Language select
          ListTile(
            title: Text('Language'.i18n),
            leading: LeadingIcon(Icons.language, color: Color(0xff009a85)),
            onTap: () {
              showDialog(
                context: context,
                builder: (context) => SimpleDialog(
                  title: Text('Select language'.i18n),
                  children: List.generate(_languages().length, (int i) {
                    Map l = _languages()[i];
                    return ListTile(
                      title: Text(l['name']),
                      subtitle: Text(l['locale']),
                      onTap: () async {
                        setState(() => settings.language = l['locale']);
                        await settings.save();
                        showDialog(
                            context: context,
                            builder: (context) {
                              return AlertDialog(
                                title: Text('Language'.i18n),
                                content: Text('Language changed, please restart Freezer to apply!'.i18n),
                                actions: [
                                  FlatButton(
                                    child: Text('OK'),
                                    onPressed: () {
                                      Navigator.of(context).pop();
                                      Navigator.of(context).pop();
                                    },
                                  )
                                ],
                              );
                            }
                        );
                      },
                    );
                  })
                )
              );
            },
          ),
          ListTile(
            title: Text('Updates'.i18n),
            leading: LeadingIcon(Icons.update, color: Color(0xff2ba766)),
            onTap: () => Navigator.push(context, MaterialPageRoute(
              builder: (context) => UpdaterScreen()
            )),
          ),
          ListTile(
            title: Text('About'.i18n),
            leading: LeadingIcon(Icons.info, color: Colors.grey),
            onTap: () => Navigator.push(context, MaterialPageRoute(
                builder: (context) => CreditsScreen()
            )),
          ),
        ],
      ),
    );
  }
}

class AppearanceSettings extends StatefulWidget {
  @override
  _AppearanceSettingsState createState() => _AppearanceSettingsState();
}

class _AppearanceSettingsState extends State<AppearanceSettings> {


  ColorSwatch<dynamic> _swatch(int c) => ColorSwatch(c, {500: Color(c)});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('Appearance'.i18n),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: Text('Theme'.i18n),
            subtitle: Text('Currently'.i18n + ': ${settings.theme.toString().split('.').last}'),
            leading: Icon(Icons.color_lens),
            onTap: () {
              showDialog(
                context: context,
                builder: (context) {
                  return SimpleDialog(
                    title: Text('Select theme'.i18n),
                    children: <Widget>[
                      SimpleDialogOption(
                        child: Text('Light'.i18n),
                        onPressed: () {
                          setState(() => settings.theme = Themes.Light);
                          settings.save();
                          updateTheme();
                          Navigator.of(context).pop();
                        },
                      ),
                      SimpleDialogOption(
                        child: Text('Dark'.i18n),
                        onPressed: () {
                          setState(() => settings.theme = Themes.Dark);
                          settings.save();
                          updateTheme();
                          Navigator.of(context).pop();
                        },
                      ),
                      SimpleDialogOption(
                        child: Text('Black (AMOLED)'.i18n),
                        onPressed: () {
                          setState(() => settings.theme = Themes.Black);
                          settings.save();
                          updateTheme();
                          Navigator.of(context).pop();
                        },
                      ),
                      SimpleDialogOption(
                        child: Text('Deezer (Dark)'.i18n),
                        onPressed: () {
                          setState(() => settings.theme = Themes.Deezer);
                          settings.save();
                          updateTheme();
                          Navigator.of(context).pop();
                        },
                      ),
                    ],
                  );
                }
              );
            },
          ),
          ListTile(
            title: Text('Use system theme'.i18n),
            trailing: Switch(
              value: settings.useSystemTheme,
              onChanged: (bool v) async {
                setState(() {
                  settings.useSystemTheme = v;
                });
                updateTheme();
                await settings.save();
              },
            ),
            leading: Icon(Icons.android)
          ),
          ListTile(
            title: Text('Player gradient background'.i18n),
            leading: Icon(Icons.colorize),
            trailing: Switch(
              value: settings.colorGradientBackground,
              onChanged: (bool v) async {
                setState(() => settings.colorGradientBackground = v);
                await settings.save();
              },
            ),
          ),
          ListTile(
            title: Text('Primary color'.i18n),
            leading: Icon(Icons.format_paint),
            subtitle: Text(
              'Selected color'.i18n,
              style: TextStyle(
                color: settings.primaryColor
              ),
            ),
            onTap: () {
              showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                    title: Text('Primary color'.i18n),
                    content: Container(
                      height: 240,
                      child: MaterialColorPicker(
                        colors: [
                          ...Colors.primaries,
                          //Logo colors
                          _swatch(0xffeca704),
                          _swatch(0xffbe3266),
                          _swatch(0xff4b2e7e),
                          _swatch(0xff384697),
                          _swatch(0xff0880b5),
                          _swatch(0xff009a85),
                          _swatch(0xff2ba766)
                        ],
                        allowShades: false,
                        selectedColor: settings.primaryColor,
                        onMainColorChange: (ColorSwatch color) {
                          setState(() {
                            settings.primaryColor = color;
                          });
                          settings.save();
                          updateTheme();
                          Navigator.of(context).pop();
                        },
                      ),
                    ),
                  );
                }
              );
            },
          ),
          ListTile(
            title: Text('Use album art primary color'.i18n),
            subtitle: Text('Warning: might be buggy'.i18n),
            leading: Icon(Icons.invert_colors),
            trailing: Switch(
              value: settings.useArtColor,
              onChanged: (v) => setState(() => settings.updateUseArtColor(v)),
            ),
          )
        ],
      ),
    );
  }
}


class QualitySettings extends StatefulWidget {
  @override
  _QualitySettingsState createState() => _QualitySettingsState();
}

class _QualitySettingsState extends State<QualitySettings> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('Quality'.i18n),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: Text('Mobile streaming'.i18n),
            leading: LeadingIcon(Icons.network_cell, color: Color(0xff384697)),
          ),
          QualityPicker('mobile'),
          FreezerDivider(),
          ListTile(
            title: Text('Wifi streaming'.i18n),
            leading: LeadingIcon(Icons.network_wifi, color: Color(0xff0880b5)),
          ),
          QualityPicker('wifi'),
          FreezerDivider(),
          ListTile(
            title: Text('Offline'.i18n),
            leading: LeadingIcon(Icons.offline_pin, color: Color(0xff009a85)),
          ),
          QualityPicker('offline'),
          FreezerDivider(),
          ListTile(
            title: Text('External downloads'.i18n),
            leading: LeadingIcon(Icons.file_download, color: Color(0xff2ba766)),
          ),
          QualityPicker('download'),
        ],
      ),
    );
  }
}

class QualityPicker extends StatefulWidget {

  final String field;
  QualityPicker(this.field, {Key key}): super(key: key);

  @override
  _QualityPickerState createState() => _QualityPickerState();
}

class _QualityPickerState extends State<QualityPicker> {

  AudioQuality _quality;

  @override
  void initState() {
    _getQuality();
    super.initState();
  }

  //Get current quality
  void _getQuality() {
    switch (widget.field) {
      case 'mobile':
        _quality = settings.mobileQuality; break;
      case 'wifi':
        _quality = settings.wifiQuality; break;
      case 'download':
        _quality = settings.downloadQuality; break;
      case 'offline':
        _quality = settings.offlineQuality; break;
    }
  }

  //Update quality in settings
  void _updateQuality(AudioQuality q) async {
    setState(() {
      _quality = q;
    });
    switch (widget.field) {
      case 'mobile':
        settings.mobileQuality = _quality;
        settings.updateAudioServiceQuality();
        break;
      case 'wifi':
        settings.wifiQuality = _quality;
        settings.updateAudioServiceQuality();
        break;
      case 'download':
        settings.downloadQuality = _quality; break;
      case 'offline':
        settings.offlineQuality = _quality; break;
    }
    await settings.save();
    await settings.updateAudioServiceQuality();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ListTile(
          title: Text('MP3 128kbps'),
          leading: Radio(
            groupValue: _quality,
            value: AudioQuality.MP3_128,
            onChanged: (q) => _updateQuality(q),
          ),
        ),
        ListTile(
          title: Text('MP3 320kbps'),
          leading: Radio(
            groupValue: _quality,
            value: AudioQuality.MP3_320,
            onChanged: (q) => _updateQuality(q),
          ),
        ),
        ListTile(
          title: Text('FLAC'),
          leading: Radio(
            groupValue: _quality,
            value: AudioQuality.FLAC,
            onChanged: (q) => _updateQuality(q),
          ),
        ),
        if (widget.field == 'download')
          ListTile(
            title: Text('Ask before downloading'.i18n),
            leading: Radio(
              groupValue: _quality,
              value: AudioQuality.ASK,
              onChanged: (q) => _updateQuality(q),
            )
          )
      ],
    );
  }
}

class DeezerSettings extends StatefulWidget {
  @override
  _DeezerSettingsState createState() => _DeezerSettingsState();
}

class _DeezerSettingsState extends State<DeezerSettings> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('Deezer'.i18n),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: Text('Content language'.i18n),
            subtitle: Text('Not app language, used in headers. Now'.i18n + ': ${settings.deezerLanguage}'),
            leading: Icon(Icons.language),
            onTap: () {
              showDialog(
                context: context,
                builder: (context) => LanguagePickerDialog(
                  titlePadding: EdgeInsets.all(8.0),
                  isSearchable: true,
                  title: Text('Select language'.i18n),
                  languagesList: defaultLanguagesList.map<Map<String, String>>((l) => {
                    'isoCode': l['isoCode'], 'name': l['name'] + ' (${l["isoCode"]})'
                  }).toList(),
                  onValuePicked: (Language language) {
                    setState(() => settings.deezerLanguage = language.isoCode);
                    settings.save();
                  },
                )
              );
            },
          ),
          ListTile(
            title: Text('Content country'.i18n),
            subtitle: Text('Country used in headers. Now'.i18n + ': ${settings.deezerCountry}'),
            leading: Icon(Icons.vpn_lock),
            onTap: () {
              showDialog(
                context: context,
                builder: (context) => CountryPickerDialog(
                  titlePadding: EdgeInsets.all(8.0),
                  isSearchable: true,
                  onValuePicked: (Country country) {
                    setState(() => settings.deezerCountry = country.isoCode);
                    settings.save();
                  },
                )
              );
            },
          ),
          ListTile(
            title: Text('Log tracks'.i18n),
            subtitle: Text('Send track listen logs to Deezer, enable it for features like Flow to work properly'.i18n),
            trailing: Switch(
              value: settings.logListen,
              onChanged: (bool v) {
                setState(() => settings.logListen = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.history_toggle_off),
          ),
          //TODO: Reimplement proxy
//          ListTile(
//            title: Text('Proxy'.i18n),
//            leading: Icon(Icons.vpn_key),
//            subtitle: Text(settings.proxyAddress??'Not set'.i18n),
//            onTap: () {
//              String _new;
//              showDialog(
//                context: context,
//                builder: (BuildContext context) {
//                  return AlertDialog(
//                    title: Text('Proxy'.i18n),
//                    content: TextField(
//                      onChanged: (String v) => _new = v,
//                      decoration: InputDecoration(
//                        hintText: 'IP:PORT'
//                      ),
//                    ),
//                    actions: [
//                      FlatButton(
//                        child: Text('Cancel'.i18n),
//                        onPressed: () => Navigator.of(context).pop(),
//                      ),
//                      FlatButton(
//                        child: Text('Reset'.i18n),
//                        onPressed: () async {
//                          setState(() {
//                            settings.proxyAddress = null;
//                          });
//                          await settings.save();
//                          Navigator.of(context).pop();
//                        },
//                      ),
//                      FlatButton(
//                        child: Text('Save'.i18n),
//                        onPressed: () async {
//                          setState(() {
//                            settings.proxyAddress = _new;
//                          });
//                          await settings.save();
//                          Navigator.of(context).pop();
//                        },
//                      )
//                    ],
//                  );
//                }
//              );
//            },
//          )
        ],
      ),
    );
  }
}

class DownloadsSettings extends StatefulWidget {
  @override
  _DownloadsSettingsState createState() => _DownloadsSettingsState();
}

class _DownloadsSettingsState extends State<DownloadsSettings> {

  double _downloadThreads = settings.downloadThreads.toDouble();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('Download Settings'.i18n),
      body: ListView(
        children: [
          ListTile(
            title: Text('Download path'.i18n),
            leading: Icon(Icons.folder),
            subtitle: Text(settings.downloadPath),
            onTap: () async {
              //Check permissions
              if (!(await Permission.storage.request().isGranted)) return;
              //Navigate
              Navigator.of(context).push(MaterialPageRoute(
                  builder: (context) => DirectoryPicker(settings.downloadPath, onSelect: (String p) async {
                    setState(() => settings.downloadPath = p);
                    await settings.save();
                  },)
              ));
            },
          ),
          ListTile(
            title: Text('Downloads naming'.i18n),
            subtitle: Text('Currently'.i18n + ': ${settings.downloadFilename}'),
            leading: Icon(Icons.text_format),
            onTap: () {
              showDialog(
                  context: context,
                  builder: (context) {

                    TextEditingController _controller = TextEditingController();
                    String filename = settings.downloadFilename;
                    _controller.value = _controller.value.copyWith(text: filename);
                    String _new = _controller.value.text;

                    //Dialog with filename format
                    return AlertDialog(
                      title: Text('Downloaded tracks filename'.i18n),
                      content: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          TextField(
                            controller: _controller,
                            onChanged: (String s) => _new = s,
                          ),
                          Container(height: 8.0),
                          Text(
                            'Valid variables are'.i18n + ': %artists%, %artist%, %title%, %album%, %trackNumber%, %0trackNumber%, %feats%, %playlistTrackNumber%, %0playlistTrackNumber%, %year%, %date%\n\n' +
                            "If you want to use custom directory naming - use '/' as directory separator.".i18n,
                            style: TextStyle(
                              fontSize: 12.0,
                            ),
                          )
                        ],
                      ),
                      actions: [
                        FlatButton(
                          child: Text('Cancel'.i18n),
                          onPressed: () => Navigator.of(context).pop(),
                        ),
                        FlatButton(
                          child: Text('Reset'.i18n),
                          onPressed: () {
                            _controller.value = _controller.value.copyWith(
                                text: '%artists% - %title%'
                            );
                            _new = '%artists% - %title%';
                          },
                        ),
                        FlatButton(
                          child: Text('Clear'.i18n),
                          onPressed: () => _controller.clear(),
                        ),
                        FlatButton(
                          child: Text('Save'.i18n),
                          onPressed: () async {
                            setState(() {
                              settings.downloadFilename = _new;
                            });
                            await settings.save();
                            Navigator.of(context).pop();
                          },
                        )
                      ],
                    );
                  }
              );
            },
          ),
          Padding(
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            child: Text(
              'Download threads'.i18n + ': ${_downloadThreads.round().toString()}',
              style: TextStyle(
                fontSize: 16.0
              ),
            ),
          ),
          Slider(
            min: 1,
            max: 16,
            divisions: 15,
            value: _downloadThreads,
            label: _downloadThreads.round().toString(),
            onChanged: (double v) => setState(() => _downloadThreads = v),
            onChangeEnd: (double val) async {
              _downloadThreads = val;
              setState(() {
                settings.downloadThreads = _downloadThreads.round();
                _downloadThreads = settings.downloadThreads.toDouble();
              });
              await settings.save();

              //Prevent null
              if (val > 8 && cache.threadsWarning != true) {
                showDialog(
                  context: context,
                  builder: (context) {
                    return AlertDialog(
                      title: Text('Warning'.i18n),
                      content: Text('Using too many concurrent downloads on older/weaker devices might cause crashes!'.i18n),
                      actions: [
                        FlatButton(
                          child: Text('Dismiss'.i18n),
                          onPressed: () => Navigator.of(context).pop(),
                        )
                      ],
                    );
                  }
                );

                cache.threadsWarning = true;
                await cache.save();
              }
            }
          ),
          FreezerDivider(),
          ListTile(
            title: Text('Create folders for artist'.i18n),
            trailing: Switch(
              value: settings.artistFolder,
              onChanged: (v) {
                setState(() => settings.artistFolder = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.folder),
          ),
          ListTile(
            title: Text('Create folders for albums'.i18n),
            trailing: Switch(
              value: settings.albumFolder,
              onChanged: (v) {
                setState(() => settings.albumFolder = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.folder)
          ),
          ListTile(
            title: Text('Create folder for playlist'.i18n),
            trailing: Switch(
              value: settings.playlistFolder,
              onChanged: (v) {
                setState(() => settings.playlistFolder = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.folder)
          ),
          FreezerDivider(),
          ListTile(
            title: Text('Separate albums by discs'.i18n),
            trailing: Switch(
              value: settings.albumDiscFolder,
              onChanged: (v) {
                setState(() => settings.albumDiscFolder = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.album)
          ),
          ListTile(
            title: Text('Overwrite already downloaded files'.i18n),
            trailing: Switch(
              value: settings.overwriteDownload,
              onChanged: (v) {
                setState(() => settings.overwriteDownload = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.delete)
          ),
          ListTile(
            title: Text('Download .LRC lyrics'.i18n),
            trailing: Switch(
              value: settings.downloadLyrics,
              onChanged: (v) {
                setState(() => settings.downloadLyrics = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.subtitles)
          ),
          FreezerDivider(),
          ListTile(
            title: Text('Save cover file for every track'.i18n),
            trailing: Switch(
              value: settings.trackCover,
              onChanged: (v) {
                setState(() => settings.trackCover = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.image)
          ),
          ListTile(
            title: Text('Save album cover'.i18n),
            trailing: Switch(
              value: settings.albumCover,
              onChanged: (v) {
                setState(() => settings.albumCover = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.image)
          ),
          ListTile(
            title: Text('Create .nomedia files'.i18n),
            subtitle: Text('To prevent gallery being filled with album art'.i18n),
            trailing: Switch(
              value: settings.nomediaFiles,
              onChanged: (v) {
                setState(() => settings.nomediaFiles = v);
                settings.save();
              },
            ),
            leading: Icon(Icons.insert_drive_file)
          ),
          FreezerDivider(),
          ListTile(
            title: Text('Download Log'.i18n),
            leading: Icon(Icons.sticky_note_2),
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => DownloadLogViewer())
            ),
          )
        ],
      ),
    );
  }
}


class GeneralSettings extends StatefulWidget {
  @override
  _GeneralSettingsState createState() => _GeneralSettingsState();
}

class _GeneralSettingsState extends State<GeneralSettings> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('General'.i18n),
      body: ListView(
        children: <Widget>[
          ListTile(
            title: Text('Offline mode'.i18n),
            subtitle: Text('Will be overwritten on start.'.i18n),
            trailing: Switch(
              value: settings.offlineMode,
              onChanged: (bool v) {
                if (v) {
                  setState(() => settings.offlineMode = true);
                  return;
                }
                showDialog(
                    context: context,
                    builder: (context) {
                      deezerAPI.authorize().then((v) {
                        if (v) {
                          setState(() => settings.offlineMode = false);
                        } else {
                          Fluttertoast.showToast(
                              msg: 'Error logging in, check your internet connections.'.i18n,
                              gravity: ToastGravity.BOTTOM,
                              toastLength: Toast.LENGTH_SHORT
                          );
                        }
                        Navigator.of(context).pop();
                      });
                      return AlertDialog(
                          title: Text('Logging in...'.i18n),
                          content: Row(
                            mainAxisSize: MainAxisSize.max,
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              CircularProgressIndicator()
                            ],
                          )
                      );
                    }
                );
              },
            ),
            leading: Icon(Icons.lock),
          ),
          ListTile(
            title: Text('Copy ARL'.i18n),
            subtitle: Text('Copy userToken/ARL Cookie for use in other apps.'.i18n),
            leading: Icon(Icons.lock),
            onTap: () async {
              await FlutterClipboard.copy(settings.arl);
              await Fluttertoast.showToast(
                msg: 'Copied'.i18n,
              );
            },
          ),
          ListTile(
            title: Text('LastFM'.i18n),
            subtitle: Text(
                (settings.lastFMPassword != null && settings.lastFMUsername != null)
                ? 'Log out'.i18n
                : 'Login to enable scrobbling.'.i18n
            ),
            leading: Icon(FontAwesome5.lastfm),
            onTap: () async {
              //Log out
              if (settings.lastFMPassword != null && settings.lastFMUsername != null) {
                settings.lastFMUsername = null;
                settings.lastFMPassword = null;
                playerHelper.scrobblenaut = null;
                await settings.save();
                setState(() {});
                Fluttertoast.showToast(msg: 'Logged out!'.i18n);
                return;
              }
              await showDialog(
                context: context,
                builder: (context) => LastFMLogin()
              );
              setState(() {});
            },
          ),
          ListTile(
            title: Text('Log out'.i18n, style: TextStyle(color: Colors.red),),
            leading: Icon(Icons.exit_to_app),
            onTap: () {
              showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                    title: Text('Log out'.i18n),
                    content: Text('Due to plugin incompatibility, login using browser is unavailable without restart.'.i18n),
                    actions: <Widget>[
                      FlatButton(
                        child: Text('Cancel'.i18n),
                        onPressed: () => Navigator.of(context).pop(),
                      ),
                      FlatButton(
                        child: Text('(ARL ONLY) Continue'.i18n),
                        onPressed: () async {
                          await logOut();
                          Navigator.of(context).pop();
                        },
                      ),
                      FlatButton(
                        child: Text('Log out & Exit'.i18n),
                        onPressed: () async {
                          try {AudioService.stop();} catch (e) {}
                          await logOut();
                          SystemNavigator.pop();
                        },
                      )
                    ],
                  );
                }
              );
            }
          ),
          ListTile(
            title: Text('Ignore interruptions'.i18n),
            subtitle: Text('Requires app restart to apply!'.i18n),
            leading: Icon(Icons.not_interested),
            trailing: Switch(
              value: settings.ignoreInterruptions,
              onChanged: (bool v) async {
                setState(() => settings.ignoreInterruptions = v);
                await settings.save();
              },
            ),
          )
        ],
      ),
    );
  }
}

class LastFMLogin extends StatefulWidget {
  @override
  _LastFMLoginState createState() => _LastFMLoginState();
}

class _LastFMLoginState extends State<LastFMLogin> {

  String _username = '';
  String _password = '';

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Login to LastFM'.i18n),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextField(
            decoration: InputDecoration(
              hintText: 'Username'.i18n
            ),
            onChanged: (v) => _username = v,
          ),
          Container(height: 8.0),
          TextField(
            obscureText: true,
            decoration: InputDecoration(
              hintText: 'Password'.i18n
            ),
            onChanged: (v) => _password = v,
          )
        ],
      ),
      actions: [
        FlatButton(
          child: Text('Cancel'.i18n),
          onPressed: () => Navigator.of(context).pop(),
        ),
        FlatButton(
          child: Text('Login'.i18n),
          onPressed: () async {
            LastFM last;
            try {
              last = await LastFM.authenticate(
                  apiKey: 'b6ab5ae967bcd8b10b23f68f42493829',
                  apiSecret: '861b0dff9a8a574bec747f9dab8b82bf',
                  username: _username,
                  password: _password
              );
            } catch (e) {
              Fluttertoast.showToast(msg: 'Authorization error!'.i18n);
              return;
            }
            //Save
            settings.lastFMUsername = last.username;
            settings.lastFMPassword = last.passwordHash;
            await settings.save();
            playerHelper.scrobblenaut = Scrobblenaut(lastFM: last);
            Navigator.of(context).pop();
          },
        ),
      ],
    );
  }
}


class DirectoryPicker extends StatefulWidget {

  final String initialPath;
  final Function onSelect;
  DirectoryPicker(this.initialPath, {this.onSelect, Key key}): super(key: key);

  @override
  _DirectoryPickerState createState() => _DirectoryPickerState();
}

class _DirectoryPickerState extends State<DirectoryPicker> {

  String _path;
  String _previous;
  String _root;

  @override
  void initState() {
    _path = widget.initialPath;
    super.initState();
  }

  Future _resetPath() async {
    StorageInfo si = (await PathProviderEx.getStorageInfo())[0];
    setState(() => _path = si.appFilesDir);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar(
        'Pick-a-Path'.i18n,
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.sd_card),
            onPressed: () {
              String path = '';
              //Chose storage
              showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                    title: Text('Select storage'.i18n),
                    content: FutureBuilder(
                      future: PathProviderEx.getStorageInfo(),
                      builder: (context, snapshot) {
                        if (snapshot.hasError) return ErrorScreen();
                        if (!snapshot.hasData) return Padding(
                          padding: EdgeInsets.symmetric(vertical: 8.0),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              CircularProgressIndicator()
                            ],
                          ),
                        );
                        return Column(
                          mainAxisSize: MainAxisSize.min,
                          children: <Widget>[
                            ...List.generate(snapshot.data.length, (i) {
                              StorageInfo si = snapshot.data[i];
                              return ListTile(
                                title: Text(si.rootDir),
                                leading: Icon(Icons.sd_card),
                                trailing: Text(filesize(si.availableBytes)),
                                onTap: () {
                                  setState(() {
                                    _path = si.appFilesDir;
                                    //Android 5+ blocks sd card, so this prevents going outside
                                    //app data dir, until permission request fix.
                                    _root = si.rootDir;
                                    if (i != 0) _root = si.appFilesDir;
                                  });
                                  Navigator.of(context).pop();
                                },
                              );
                            })
                          ],
                        );
                      },
                    ),
                  );
                }
              );
            }
          )
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.done),
        onPressed: () {
          //When folder confirmed
          if (widget.onSelect != null) widget.onSelect(_path);
          Navigator.of(context).pop();
        },
      ),
      body: FutureBuilder(
        future: Directory(_path).list().toList(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {

          //On error go to last good path
          if (snapshot.hasError) Future.delayed(Duration(milliseconds: 50), () {
            if (_previous == null) {
              _resetPath();
              return;
            }
            setState(() => _path = _previous);
          });
          if (!snapshot.hasData) return Center(child: CircularProgressIndicator(),);

          List<FileSystemEntity> data = snapshot.data;
          return ListView(
            children: <Widget>[
              ListTile(
                title: Text(_path),
              ),
              ListTile(
                title: Text('Go up'.i18n),
                leading: Icon(Icons.arrow_upward),
                onTap: () {
                  setState(() {
                    if (_root == _path) {
                      Fluttertoast.showToast(
                          msg: 'Permission denied'.i18n,
                          gravity: ToastGravity.BOTTOM
                      );
                      return;
                    }
                    _previous = _path;
                    _path = Directory(_path).parent.path;
                  });
                },
              ),
              ...List.generate(data.length, (i) {
                FileSystemEntity f = data[i];
                if (f is Directory) {
                  return ListTile(
                    title: Text(f.path.split('/').last),
                    leading: Icon(Icons.folder),
                    onTap: () {
                      setState(() {
                        _previous = _path;
                        _path = f.path;
                      });
                    },
                  );
                }
                return Container(height: 0, width: 0,);
              })
            ],
          );
        },
      ),
    );
  }
}

class CreditsScreen extends StatefulWidget {
  @override
  _CreditsScreenState createState() => _CreditsScreenState();
}

class _CreditsScreenState extends State<CreditsScreen> {

  String _version = '';

  static final List<List<String>> translators = [
    ['Xandar Null', 'Arabic'],
    ['Markus', 'German'],
    ['Andrea', 'Italian'],
    ['Diego Hiro', 'Portuguese'],
    ['Orfej', 'Russian'],
    ['Chino Pacia', 'Filipino'],
    ['ArcherDelta & PetFix', 'Spanish'],
    ['Shazzaam', 'Croatian'],
    ['VIRGIN_KLM', 'Greek'],
    ['koreezzz', 'Korean'],
    ['Fwwwwwwwwwweze', 'French'],
    ['kobyrevah', 'Hebrew'],
    ['HoScHaKaL', 'Turkish'],
    ['MicroMihai', 'Romanian'],
    ['LenteraMalam', 'Indonesian'],
    ['RTWO2', 'Persian']
  ];

  @override
  void initState() {
    PackageInfo.fromPlatform().then((info) {
      setState(() {
        _version = 'v${info.version}';
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: FreezerAppBar('About'.i18n),
      body: ListView(
        children: [
          FreezerTitle(),
          Text(
            _version,
            textAlign: TextAlign.center,
            style: TextStyle(
              fontStyle: FontStyle.italic
            ),
          ),
          FreezerDivider(),
          ListTile(
            title: Text('Telegram Channel'.i18n),
            subtitle: Text('To get latest releases'.i18n),
            leading: Icon(FontAwesome5.telegram, color: Color(0xFF27A2DF), size: 36.0),
            onTap: () {
              launch('https://t.me/freezereleases');
            },
          ),
          ListTile(
            title: Text('Telegram Group'.i18n),
            subtitle: Text('Official chat'.i18n),
            leading: Icon(FontAwesome5.telegram, color: Colors.cyan, size: 36.0),
            onTap: () {
              launch('https://t.me/freezerandroid');
            },
          ),
          ListTile(
            title: Text('Discord'.i18n),
            subtitle: Text('Official Discord server'.i18n),
            leading: Icon(FontAwesome5.discord, color: Color(0xff7289da), size: 36.0),
            onTap: () {
              launch('https://discord.gg/7ap654Tp3z');
            },
          ),
          ListTile(
            title: Text('Repository'.i18n),
            subtitle: Text('Source code, report issues there.'.i18n),
            leading: Icon(Icons.code, color: Colors.green, size: 36.0),
            onTap: () {
              launch('https://git.rip/freezer/');
            },
          ),
          FreezerDivider(),
          ListTile(
            title: Text('exttex'),
            subtitle: Text('Developer'),
          ),
          ListTile(
            title: Text('Bas Curtiz'),
            subtitle: Text('Icon, logo, banner, design suggestions, tester'),
          ),
          ListTile(
            title: Text('Tobs'),
            subtitle: Text('Alpha testers'),
          ),
          ListTile(
            title: Text('Deemix'),
            subtitle: Text('Better app <3'),
          ),
          ListTile(
            title: Text('Xandar Null'),
            subtitle: Text('Tester, translations help'),
          ),
          ListTile(
            title: Text('Francesco'),
            subtitle: Text('Tester'),
            onTap: () {
              setState(() {
                settings.primaryColor = Color(0xff333333);
              });
              updateTheme();
              settings.save();
            },
          ),
          ListTile(
            title: Text('Annexhack'),
            subtitle: Text('Android Auto help'),
          ),
          FreezerDivider(),
          ...List.generate(translators.length, (i) => ListTile(
            title: Text(translators[i][0]),
            subtitle: Text(translators[i][1]),
          )),
          Padding(
            padding: EdgeInsets.fromLTRB(0, 4, 0, 8),
            child: Text(
              'Huge thanks to all the contributors! <3'.i18n,
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 16.0
              ),
            ),
          )
        ],
      ),
    );
  }
}