using Firebase.Auth;

using Google.Apis.Auth.OAuth2;
using Google.Cloud.Firestore;
using Google.Cloud.Firestore.V1;

// Create a Firebase authentication provider with your Firebase project API key
var fbAuthProv = new FirebaseAuthProvider(new FirebaseConfig("{API key for your Firebase project}"));

try
{
    // Sign in with your email and password
    var authLnk = await fbAuthProv.SignInWithEmailAndPasswordAsync("{Sign-in user's Email address}", "{Sign-in user's password}");

    // Get google credential from access token
    var gglCre = GoogleCredential.FromAccessToken(authLnk.FirebaseToken);

    // Create a Firestore client builder with the google credential
    var fsCliBldr = new FirestoreClientBuilder() { Credential = gglCre };

    // Create an instance of the Firestore database with your project id
    var fsDb = FirestoreDb.Create("firestoretest220903", fsCliBldr.Build());

    // Collection name
    const string cUSERS = "users";
    // Sign in user id
    string userId = authLnk.User.LocalId;

    // 1. Create data
    await fsDb.Collection(cUSERS).Document(userId).CreateAsync(
        new UserInfo
        {
            FirstName = "Taro",
            LastName = "Yamada",
            Age = 20,
        });

    // 2. Read data
    var readDocSnap = await fsDb.Collection(cUSERS).Document(userId).GetSnapshotAsync();
    var readUserInfo = readDocSnap.ConvertTo<UserInfo>();
    Console.WriteLine(readUserInfo.ToString());

    // 3. Update data
    readUserInfo.Age = 30;
    await fsDb.Collection(cUSERS).Document(userId).SetAsync(readUserInfo);

    // 4. Delete data
    await fsDb.Collection(cUSERS).Document(userId).DeleteAsync();
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

Console.ReadKey();

// DTO class
[FirestoreData]
class UserInfo
{
    [FirestoreProperty]
    public string FirstName { get; set; } = string.Empty;

    [FirestoreProperty]
    public string LastName { get; set; } = string.Empty;

    [FirestoreProperty]
    public short Age { get; set; } = -1;

    public override string ToString() => $"{FirstName} {LastName} {Age}";
}