using System.Text.Json;
using TradingBot.Models;

namespace TradingBot.Services;

/// <summary>
/// Service for persisting trade history and active positions to disk
/// </summary>
public class TradeHistoryService
{
    private readonly string _dataDirectory;
    private readonly string _tradesFilePath;
    private readonly string _activePositionsFilePath;
    private readonly ILogger<TradeHistoryService> _logger;
    private readonly JsonSerializerOptions _jsonOptions;

    public TradeHistoryService(ILogger<TradeHistoryService> logger)
    {
        _logger = logger;
        _dataDirectory = Path.Combine(Directory.GetCurrentDirectory(), "data");
        _tradesFilePath = Path.Combine(_dataDirectory, "trade-history.json");
        _activePositionsFilePath = Path.Combine(_dataDirectory, "active-positions.json");

        _jsonOptions = new JsonSerializerOptions
        {
            WriteIndented = true,
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase
        };

        EnsureDataDirectoryExists();
    }

    private void EnsureDataDirectoryExists()
    {
        if (!Directory.Exists(_dataDirectory))
        {
            Directory.CreateDirectory(_dataDirectory);
            _logger.LogInformation("Created data directory: {Directory}", _dataDirectory);
        }
    }

    /// <summary>
    /// Save complete trade history to disk
    /// </summary>
    public async Task SaveTradeHistoryAsync(List<Trade> trades)
    {
        try
        {
            var json = JsonSerializer.Serialize(trades, _jsonOptions);
            await File.WriteAllTextAsync(_tradesFilePath, json);
            _logger.LogInformation("Saved {Count} trades to history", trades.Count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to save trade history");
        }
    }

    /// <summary>
    /// Load trade history from disk
    /// </summary>
    public async Task<List<Trade>> LoadTradeHistoryAsync()
    {
        try
        {
            if (!File.Exists(_tradesFilePath))
            {
                _logger.LogInformation("No trade history file found, starting fresh");
                return new List<Trade>();
            }

            var json = await File.ReadAllTextAsync(_tradesFilePath);
            var trades = JsonSerializer.Deserialize<List<Trade>>(json, _jsonOptions);
            
            _logger.LogInformation("Loaded {Count} trades from history", trades?.Count ?? 0);
            return trades ?? new List<Trade>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to load trade history, starting fresh");
            return new List<Trade>();
        }
    }

    /// <summary>
    /// Save active positions (open trades) to disk
    /// </summary>
    public async Task SaveActivePositionsAsync(Dictionary<string, Trade> activePositions)
    {
        try
        {
            var json = JsonSerializer.Serialize(activePositions, _jsonOptions);
            await File.WriteAllTextAsync(_activePositionsFilePath, json);
            _logger.LogInformation("Saved {Count} active positions", activePositions.Count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to save active positions");
        }
    }

    /// <summary>
    /// Load active positions from disk
    /// </summary>
    public async Task<Dictionary<string, Trade>> LoadActivePositionsAsync()
    {
        try
        {
            if (!File.Exists(_activePositionsFilePath))
            {
                _logger.LogInformation("No active positions file found");
                return new Dictionary<string, Trade>();
            }

            var json = await File.ReadAllTextAsync(_activePositionsFilePath);
            var positions = JsonSerializer.Deserialize<Dictionary<string, Trade>>(json, _jsonOptions);
            
            _logger.LogInformation("Loaded {Count} active positions", positions?.Count ?? 0);
            return positions ?? new Dictionary<string, Trade>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to load active positions");
            return new Dictionary<string, Trade>();
        }
    }

    /// <summary>
    /// Clear all persisted data
    /// </summary>
    public void ClearAll()
    {
        try
        {
            if (File.Exists(_tradesFilePath))
                File.Delete(_tradesFilePath);
            
            if (File.Exists(_activePositionsFilePath))
                File.Delete(_activePositionsFilePath);

            _logger.LogInformation("Cleared all persisted trade data");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to clear persisted data");
        }
    }

    /// <summary>
    /// Get total file size of persisted data
    /// </summary>
    public long GetDataSize()
    {
        long size = 0;
        
        if (File.Exists(_tradesFilePath))
            size += new FileInfo(_tradesFilePath).Length;
        
        if (File.Exists(_activePositionsFilePath))
            size += new FileInfo(_activePositionsFilePath).Length;

        return size;
    }
}
