using Microsoft.Extensions.Configuration;
using MongoDB.Driver;
using Postall.Domain;
using Postall.Domain.Dtos.Responses;
using Postall.Domain.Entities;
using Postall.Domain.Services.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Json;
using System.Text;
using System.Threading.Tasks;

namespace Postall.Infra.Services
{
    public class FacebookTokenService: IFacebookServices
    {
        private readonly IConfiguration _config;
        private readonly IUserSocialRepository _userSocialRepository;
        private readonly HttpClient _httpClient;

        public FacebookTokenService(IConfiguration configuration, IHttpClientFactory httpClientFactory, IUserSocialRepository userSocialRepository)
        {
            _config = configuration;
            this._userSocialRepository = userSocialRepository;
            _httpClient = httpClientFactory.CreateClient("Facebook");
        }

        public async Task<string> GetLongLivedToken(string shortLivedToken)
        {
            var appId = _config.GetSection("Authentication:Facebook:AppId").Value;
            var appSecret = _config.GetSection("Authentication:Facebook:AppSecret").Value;

            var response = await _httpClient.GetFromJsonAsync<FacebookTokenResponse>(
                $"https://graph.facebook.com/oauth/access_token?" +
                $"grant_type=fb_exchange_token&" +
                $"client_id={appId}&" +
                $"client_secret={appSecret}&" +
                $"fb_exchange_token={shortLivedToken}");

            return response.AccessToken;
        }

        public async Task SaveFacebookToken(string userId, string token)
        {
            var update = Builders<UserSocialData>.Update
                .Set(x => x.FacebookToken.AccessToken, token)
                .Set(x => x.FacebookToken.ExpiresAt, DateTime.UtcNow.AddDays(60));

            if (_userSocialRepository.GetByIdAsync(userId) == null)
            {
                await _userSocialRepository.AddAsync(new UserSocialData() { UserId = Guid.NewGuid().ToString("N")});
                return;
            }

            await _userSocialRepository.UpdateOneAsync(
                userId,
                update
            );
        }

        private async Task UpdateOneAsync(Func<object, bool> value, UpdateDefinition<UserSocialData> update, UpdateOptions updateOptions)
        {
            throw new NotImplementedException();
        }
    }
}
