using System.Net.Http.Json;
using System.Text.Json.Serialization;
using QuantEngine.Core.Interfaces;

namespace QuantEngine.Web.Client.Services;

public class ApiClient
{
    private readonly HttpClient _http;
    private readonly ILogger<ApiClient> _logger;
    public ApiClient(HttpClient http, ILogger<ApiClient> logger)
    {
        _http = http;
        _logger = logger;
    }

    // Collection API Methods

    public async Task<CollectionDashboardStateDto?> GetCollectionStateAsync()
    {
        try
        {
            return await _http.GetFromJsonAsync<CollectionDashboardStateDto>("api/collection/state");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error fetching collection state");
            return null;
        }
    }

    public async Task<CollectionRunsResponse?> GetCollectionRunsAsync(int limit = 20)
    {
        try
        {
            return await _http.GetFromJsonAsync<CollectionRunsResponse>($"api/collection/runs?limit={limit}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error fetching collection runs");
            return null;
        }
    }

    public async Task<CollectionRunSnapshotsResponse?> GetCollectionSnapshotsAsync(string runId)
    {
        try
        {
            return await _http.GetFromJsonAsync<CollectionRunSnapshotsResponse>($"api/collection/runs/{runId}/snapshots");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error fetching snapshots for run {runId}");
            return null;
        }
    }

    public async Task<CollectionRunErrorsResponse?> GetCollectionErrorsAsync(string runId, int limit = 50)
    {
        try
        {
            return await _http.GetFromJsonAsync<CollectionRunErrorsResponse>($"api/collection/runs/{runId}/errors?limit={limit}");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"Error fetching errors for run {runId}");
            return null;
        }
    }

    public async Task<CollectionRunStartResponse?> StartCollectionRunAsync()
    {
        try
        {
            var response = await _http.PostAsJsonAsync("api/collection/run", new { });
            if (response.IsSuccessStatusCode)
            {
                return await response.Content.ReadFromJsonAsync<CollectionRunStartResponse>();
            }
            return null;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error starting collection run");
            return null;
        }
    }
}

// DTOs

public class CollectionDashboardStateDto
{
    [JsonPropertyName("lastRunId")]
    public string? LastRunId { get; set; }

    [JsonPropertyName("lastRunStatus")]
    public string? LastRunStatus { get; set; }

    [JsonPropertyName("lastFinishedAt")]
    public string? LastFinishedAt { get; set; }

    [JsonPropertyName("totalSnapshots")]
    public int TotalSnapshots { get; set; }

    [JsonPropertyName("totalErrors")]
    public int TotalErrors { get; set; }

    [JsonPropertyName("recentErrors")]
    public List<CollectionErrorDto> RecentErrors { get; set; } = new();
}

public class CollectionRunDto
{
    [JsonPropertyName("runId")]
    public string RunId { get; set; } = "";

    [JsonPropertyName("status")]
    public string Status { get; set; } = "";

    [JsonPropertyName("startedAt")]
    public string StartedAt { get; set; } = "";

    [JsonPropertyName("finishedAt")]
    public string? FinishedAt { get; set; }

    [JsonPropertyName("totalSnapshots")]
    public int? TotalSnapshots { get; set; }

    [JsonPropertyName("totalErrors")]
    public int? TotalErrors { get; set; }
}

public class CollectionSnapshotDto
{
    [JsonPropertyName("runId")]
    public string RunId { get; set; } = "";

    [JsonPropertyName("datasetName")]
    public string DatasetName { get; set; } = "";

    [JsonPropertyName("ticker")]
    public string Ticker { get; set; } = "";

    [JsonPropertyName("sourceName")]
    public string SourceName { get; set; } = "";

    [JsonPropertyName("capturedAt")]
    public string CapturedAt { get; set; } = "";
}

public class CollectionErrorDto
{
    [JsonPropertyName("runId")]
    public string RunId { get; set; } = "";

    [JsonPropertyName("sourceName")]
    public string SourceName { get; set; } = "";

    [JsonPropertyName("errorKind")]
    public string ErrorKind { get; set; } = "";

    [JsonPropertyName("errorMessage")]
    public string ErrorMessage { get; set; } = "";

    [JsonPropertyName("ticker")]
    public string Ticker { get; set; } = "";
}

public class CollectionRunsResponse
{
    [JsonPropertyName("runs")]
    public List<CollectionRunDto> Runs { get; set; } = new();

    [JsonPropertyName("count")]
    public int Count { get; set; }
}

public class CollectionRunSnapshotsResponse
{
    [JsonPropertyName("runId")]
    public string RunId { get; set; } = "";

    [JsonPropertyName("snapshots")]
    public List<CollectionSnapshotDto> Snapshots { get; set; } = new();

    [JsonPropertyName("count")]
    public int Count { get; set; }
}

public class CollectionRunErrorsResponse
{
    [JsonPropertyName("runId")]
    public string RunId { get; set; } = "";

    [JsonPropertyName("errors")]
    public List<CollectionErrorDto> Errors { get; set; } = new();

    [JsonPropertyName("count")]
    public int Count { get; set; }
}

public class CollectionRunStartResponse
{
    [JsonPropertyName("runId")]
    public string RunId { get; set; } = "";

    [JsonPropertyName("status")]
    public string Status { get; set; } = "";

    [JsonPropertyName("startedAt")]
    public string StartedAt { get; set; } = "";
}
