using System;
using System.Diagnostics;
using Expedience.Infrastructure.Models;

namespace Expedience.Web.Services;

public interface IApiService
{
    public ValueTask<List<DutyCompletionRecord>?> GetDutyCompletionRecordsAsync(string expac, CancellationToken cancellationToken);
    public ValueTask<List<DeepDungeonRecord>?> GetDeepDungeonRecordsAsync(CancellationToken cancellationToken);
    public ValueTask<List<ContentTypeRecord>?> GetTreasureHuntRecordsAsync(CancellationToken cancellationToken);
    public ValueTask<List<DutyCompletionResult>?> GetTopXRecords(int recordType, int territoryId, int limit, CancellationToken cancellationToken);
}

public class ApiService : IApiService
{
    private readonly ILogger _logger;
    private readonly HttpClient _httpClient;

    public ApiService(ILogger<ApiService> logger, HttpClient httpClient)
    {
        _logger = logger;
        _httpClient = httpClient;
    }

    public async ValueTask<List<DutyCompletionRecord>?> GetDutyCompletionRecordsAsync(string expac, CancellationToken cancellationToken)
    {
        var stopwatch = Stopwatch.StartNew();
        try
        {
            var records = await _httpClient.GetFromJsonAsync<List<DutyCompletionRecord>?>($"/api/DutyCompletionRecords/{expac}", cancellationToken);
            _logger.LogInformation("Retrieved Duty Completion Records in {duration}ms", stopwatch.ElapsedMilliseconds);
            return records;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred trying to retrieve Duty Completion Records for {expac}: {errorMessage}", 
                expac, ex.Message);
        }

        return [];
    }

    public async ValueTask<List<DeepDungeonRecord>?> GetDeepDungeonRecordsAsync(CancellationToken cancellationToken)
    {
        var stopwatch = Stopwatch.StartNew();
        try
        {
            var records = await _httpClient.GetFromJsonAsync<List<DeepDungeonRecord>?>($"/api/DeepDungeonRecords", cancellationToken);
            _logger.LogInformation("Retrieved Deep Dungeon Records in {duration}ms", stopwatch.ElapsedMilliseconds);
            return records;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred trying to retrieve Deep Dungeon Records: {errorMessage}", ex.Message);
        }

        return [];
    }

    public async ValueTask<List<DutyCompletionResult>> GetTopXRecords(int recordType, int territoryId, int limit, CancellationToken cancellationToken)
    {
        var stopwatch = Stopwatch.StartNew();
        try
        {
            var records = await _httpClient.GetFromJsonAsync<List<DutyCompletionResult>?>($"/api/TopX/{recordType}/{territoryId}/{limit}", cancellationToken);
            _logger.LogInformation("Retrieved Top {limit} records for {territoryId} {recordType} in {duration}ms", 
                limit, territoryId, recordType, stopwatch.ElapsedMilliseconds);

            return records;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred trying to retrieve Top {limit} records for {territoryId} {recordType}: {errorMessage}", 
               limit, territoryId, recordType, ex.Message);
        }

        return [];
    }

    public async ValueTask<List<ContentTypeRecord>?> GetTreasureHuntRecordsAsync(CancellationToken cancellationToken)
    {
        var stopwatch = Stopwatch.StartNew();
        try
        {
            var records = await _httpClient.GetFromJsonAsync<List<ContentTypeRecord>?>($"/api/TreasureHuntRecords", cancellationToken);
            _logger.LogInformation("Retrieved Treasure Hunt Records in {duration}ms", stopwatch.ElapsedMilliseconds);
            
            return records;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An error occurred trying to retrieve Treasure Hunt Records: {errorMessage}", ex.Message);
        }

        return [];
    }
}
