



import 'package:appwrite/appwrite.dart' as appwrite;
import 'package:appwrite/models.dart' as models;
import 'package:bus_infotainment/auth/api_constants.dart';
import 'package:bus_infotainment/utils/delegates.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

enum AuthStatus {
  UNINITIALIZED,
  AUTHENTICATED,
  UNAUTHENTICATED,
}

class AuthAPI extends ChangeNotifier {

  appwrite.Client client = appwrite.Client();
  late final appwrite.Account account;

  late models.User _currentUser;

  AuthStatus _status = AuthStatus.UNINITIALIZED;

  // late UserInfo _userInfo;

  // Getter methods
  models.User get currentUser => _currentUser;
  // UserInfo get userInfo => _userInfo;
  AuthStatus get status => _status;
  String? get username => _currentUser.name;
  String? get email => _currentUser.email;
  String? get userID => _currentUser.$id;

  AuthAPI() {
    init();
    loadUser();
  }

  init() {
    client
      .setEndpoint(ApiConstants.APPWRITE_ENDPOINT)
      .setProject(ApiConstants.APPWRITE_PROJECT_ID)
      .setSelfSigned();
    account = appwrite.Account(client);
  }

  loadUser() async {
    try {

      {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        String? username = prefs.getString("APPWRITE_SESSIONID_USERNAME");
        String? password = prefs.getString("APPWRITE_SESSIONID_PASSWORD");
        if (username != null && password != null) {
          await createEmailSession(email: username, password: password);
        }
      }



      final user = await account.get();
      _status = AuthStatus.AUTHENTICATED;
      // _userInfo = await UserInfo.getFromId(this, userID!);
      _currentUser = user;
    } catch (e) {
      _status = AuthStatus.UNAUTHENTICATED;
    } finally {
      notifyListeners();
    }
  }

  Future<models.User> createUser({
    required String displayName,
    required String username,
    required String email,
    required String password,
  }) async {
    notifyListeners();

    try {
      final user = await account.create(
        userId: appwrite.ID.unique(),
        email: email,
        password: password,
        name: username,
      );

      final appwrite.Databases databases = appwrite.Databases(client);

      // await databases.createDocument(
      //   databaseId: ApiConstants.SOCIALS_DATABASE_ID,
      //   collectionId: ApiConstants.USERS_COLLECTION_ID,
      //   documentId: user!.$id,
      //   data: {
      //     "username": username,
      //     "display_name": displayName,
      //     "bio": "",
      //     "status": "",
      //     "profilepicture_id": "default",
      //     "profilebanner_id": "default",
      //     "last_activity": DateTime.now().toIso8601String(),
      //     "guild_ids": [],
      //
      //   }
      // );

      return user;
    } finally {
      notifyListeners();
    }
  }

  /* Login */
  Future<models.Session> createEmailSession({
    required String email,
    required String password,
  }) async {

    try {
      final session = await account.createEmailSession(
        email: email,
        password: password,
      );
      _currentUser = await account.get();
      _status = AuthStatus.AUTHENTICATED;
      // _userInfo = await UserInfo.getFromId(this, userID!);
      // _userInfo.username = _currentUser.name!;
      // _userInfo.pushChanges(this);

      // store session in shared preferences
      SharedPreferences prefs = await SharedPreferences.getInstance();
      prefs.setString("APPWRITE_SESSIONID_USERNAME", email);
      prefs.setString("APPWRITE_SESSIONID_PASSWORD", password);

      return session;
    } finally {
      onLogin.trigger(1);
      notifyListeners();
    }
  }

  /* Logout */
  Future<void> deleteSession() async {
    try {
      await account.deleteSession(sessionId: "current");

      {
        SharedPreferences prefs = await SharedPreferences.getInstance();
        prefs.remove("APPWRITE_SESSIONID_USERNAME");
        prefs.remove("APPWRITE_SESSIONID_PASSWORD");
      }

      _status = AuthStatus.UNAUTHENTICATED;
    } finally {
      notifyListeners();
    }
  }

  bool isAuthenticated() {
    return _status == AuthStatus.AUTHENTICATED;
  }

  // Events

  EventDelegate<int> _onLogin = EventDelegate();
  EventDelegate get onLogin => _onLogin;

}