using MongoDB.Driver;
using Nalu.Web.Data.Models;

namespace Nalu.Web.Data.Repositories;

public class UserRepository(MongoDbContext db)
{
    public async Task<NaluUser?> FindByEmailAsync(string email, CancellationToken ct = default)
    {
        if (!db.IsConnected) return null;

        return await db.Users
            .Find(u => u.Email == email && u.IsActive)
            .FirstOrDefaultAsync(ct);
    }

    public async Task<NaluUser?> FindByProviderAsync(string provider, string providerId, CancellationToken ct = default)
    {
        if (!db.IsConnected) return null;

        return await db.Users
            .Find(u => u.Provider == provider && u.ProviderId == providerId)
            .FirstOrDefaultAsync(ct);
    }

    public async Task<NaluUser?> FindByIdAsync(string id, CancellationToken ct = default)
    {
        if (!db.IsConnected) return null;

        return await db.Users
            .Find(u => u.Id == id)
            .FirstOrDefaultAsync(ct);
    }

    public async Task UpsertAsync(NaluUser user, CancellationToken ct = default)
    {
        await db.Users.ReplaceOneAsync(
            u => u.Provider == user.Provider && u.ProviderId == user.ProviderId,
            user,
            new ReplaceOptions { IsUpsert = true },
            ct);
    }

    public async Task UpdatePlanAsync(string userId, string plan, CancellationToken ct = default)
    {
        await db.Users.UpdateOneAsync(
            u => u.Id == userId,
            Builders<NaluUser>.Update
                .Set(u => u.Plan, plan)
                .Set(u => u.LastLoginAt, DateTime.UtcNow),
            cancellationToken: ct);
    }

    public async Task SetStripeCustomerAsync(string userId, string stripeCustomerId, CancellationToken ct = default)
    {
        await db.Users.UpdateOneAsync(
            u => u.Id == userId,
            Builders<NaluUser>.Update.Set(u => u.StripeCustomerId, stripeCustomerId),
            cancellationToken: ct);
    }
}
