using System.Security.Claims;
using FluentResults;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using NexusReader.Data.Persistence;
using NexusReader.Domain.Enums;
using NexusReader.Application.Abstractions.Services;

namespace NexusReader.Web.Services;

public class ServerUserPreferenceStore : IUserPreferenceStore
{
    private readonly IDbContextFactory<AppDbContext> _dbContextFactory;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ServerUserPreferenceStore(
        IDbContextFactory<AppDbContext> dbContextFactory,
        IHttpContextAccessor httpContextAccessor)
    {
        _dbContextFactory = dbContextFactory;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<Result> SaveThemePreferenceAsync(ThemeMode mode)
    {
        var userId = _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
        if (string.IsNullOrEmpty(userId))
        {
            return Result.Fail("User is not authenticated on the server.");
        }

        try
        {
            using var dbContext = await _dbContextFactory.CreateDbContextAsync();
            var user = await dbContext.Users
                .AsTracking()
                .FirstOrDefaultAsync(u => u.Id == userId);
                
            if (user == null)
            {
                return Result.Fail("User not found in database.");
            }

            user.ThemePreference = mode;
            await dbContext.SaveChangesAsync();
            return Result.Ok();
        }
        catch (Exception ex)
        {
            return Result.Fail(new Error("Database failure updating theme preference.").CausedBy(ex));
        }
    }

    public async Task<Result<ThemeMode>> GetThemePreferenceAsync()
    {
        var userId = _httpContextAccessor.HttpContext?.User.FindFirstValue(ClaimTypes.NameIdentifier);
        if (string.IsNullOrEmpty(userId))
        {
            return Result.Fail("User is not authenticated on the server.");
        }

        try
        {
            using var dbContext = await _dbContextFactory.CreateDbContextAsync();
            var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Id == userId);
            if (user == null)
            {
                return Result.Fail("User not found in database.");
            }

            return Result.Ok(user.ThemePreference);
        }
        catch (Exception ex)
        {
            return Result.Fail(new Error("Database failure reading theme preference.").CausedBy(ex));
        }
    }
}
