// Copyright 2019 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/foundation.dart';
import 'package:flutter/services.dart';
import 'package:google_sign_in/google_sign_in.dart';

/// Service class for interacting with Google Sign In authentication for Cocoon backend.
///
/// Almost all operations with the plugin can throw an exception and should be caught
/// to prevent this service from crashing.
class GoogleSignInService extends ChangeNotifier {
  /// Creates a new [GoogleSignIn].
  GoogleSignInService({GoogleSignIn? googleSignIn})
      : _googleSignIn = googleSignIn ??
            GoogleSignIn(
              scopes: _googleScopes,
            ) {
    _googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? accountValue) {
      // We could decode the idToken here and look at its TTL, but it can be
      // revoked (from another website) at any time, so the only reliable way of
      // knowing that we're still authenticated is... to monitor the statuses of
      // the requests to the server (if they return an error, clear user/log out!)
      user = accountValue;
      notifyListeners();
    });

    try {
      _googleSignIn.signInSilently();
    } on PlatformException catch (error) {
      debugPrint('GoogleSignIn error code: ${error.code}');
      debugPrint(error.message);
    }
  }

  /// A list of Google API OAuth Scopes this project needs access to.
  ///
  /// Currently, the project shows just basic user profile information
  /// when logged in.
  ///
  /// See https://developers.google.com/identity/protocols/googlescopes
  static const List<String> _googleScopes = <String>[];

  /// The instance of the GoogleSignIn plugin to use.
  final GoogleSignIn _googleSignIn;

  /// Whether or not the application has been signed in to.
  ///
  /// If the plugin fails, default to unauthenticated.
  bool get isAuthenticated {
    return user != null;
  }

  /// The Google Account for the signed in user, null if no user is signed in.
  ///
  /// Read only object with only access to clear client auth tokens.
  GoogleSignInAccount? user;

  /// Authentication token to be sent to Cocoon Backend to verify API calls.
  Future<String> get idToken async {
    assert(isAuthenticated, 'Ensure user isAuthenticated before requesting an idToken.');

    final GoogleSignInAuthentication? key = await user?.authentication;
    final String? idToken = key?.idToken;
    assert(idToken != null && idToken.isNotEmpty);

    return idToken!;
  }

  /// Initiate the Google Sign In process.
  Future<void> signIn() async {
    try {
      user = await _googleSignIn.signIn();
      notifyListeners();
    } on PlatformException catch (error) {
      debugPrint('GoogleSignIn error code: ${error.code}');
      debugPrint(error.message);
    }
  }

  Future<void> signOut() async {
    try {
      user = await _googleSignIn.signOut();
      notifyListeners();
    } on PlatformException catch (error) {
      debugPrint('GoogleSignIn error code: ${error.code}');
      debugPrint(error.message);
    }
  }

  /// Clears the active user from the service, without calling signOut on the plugin.
  ///
  /// This refreshes the UI of the app, while making it easy for users to re-login.
  Future<void> clearUser() async {
    user = null;
    notifyListeners();
  }
}
