using System.Collections.Generic;
using System.Threading.Tasks;
using QuantEngine.Core.Domain;
using QuantEngine.Core.Interfaces;

namespace QuantEngine.Application.Services
{
    public class HistoryIngestionService
    {
        private readonly IPostgresqlHistoryStore _store;

        public HistoryIngestionService(IPostgresqlHistoryStore store)
        {
            _store = store;
        }

        public Task<int> AppendDecisionAsync(IDictionary<string, object?> payload)
            => _store.AppendAsync("decision_result_history", payload);

        public Task<int> AppendFactorOutputAsync(IDictionary<string, object?> payload)
            => _store.AppendAsync("factor_output_history", payload);

        public Task<int> AppendMarketRawAsync(IDictionary<string, object?> payload)
            => _store.AppendAsync("market_raw_history", payload);

        public Task<int> AppendGapAsync(IDictionary<string, object?> payload)
            => _store.AppendAsync("market_vs_engine_gap_history", payload);

        public Task<int> AppendDecisionAsync(
            FinalDecisionResult decision,
            SellDecisionResult? sellDecision = null,
            TimingDecisionResult? timingDecision = null,
            string? instrumentId = null,
            string? sourceVersion = null,
            string? gate = null)
        {
            var payload = new Dictionary<string, object?>
            {
                ["decision_id"] = Guid.NewGuid().ToString("N"),
                ["decided_at"] = DateTimeOffset.UtcNow,
                ["instrument_id"] = instrumentId ?? string.Empty,
                ["action"] = decision.FinalAction,
                ["gate"] = gate ?? (string.IsNullOrWhiteSpace(sellDecision?.Validation) ? "PASS" : sellDecision.Validation),
                ["score"] = decision.PriorityScore,
                ["source_version"] = sourceVersion ?? decision.DecisionSource,
                ["provenance"] = new Dictionary<string, object?>
                {
                    ["final_action"] = decision.FinalAction,
                    ["action_priority"] = decision.ActionPriority,
                    ["priority_score"] = decision.PriorityScore,
                    ["decision_source"] = decision.DecisionSource,
                    ["sell_action"] = sellDecision?.Action,
                    ["sell_validation"] = sellDecision?.Validation,
                    ["timing_action"] = timingDecision?.Action,
                    ["timing_reason"] = timingDecision?.Reason
                }
            };

            return _store.AppendAsync("decision_result_history", payload);
        }

        public Task<int> AppendFactorOutputAsync(
            string factorId,
            string factorVersion,
            double outputValue,
            string outputGate,
            string? sourceVersion = null,
            DateTimeOffset? observedAt = null)
        {
            var payload = new Dictionary<string, object?>
            {
                ["factor_output_id"] = Guid.NewGuid().ToString("N"),
                ["observed_at"] = observedAt ?? DateTimeOffset.UtcNow,
                ["factor_id"] = factorId,
                ["factor_version"] = factorVersion,
                ["output_value"] = outputValue,
                ["output_gate"] = outputGate,
                ["source_version"] = sourceVersion ?? factorVersion,
                ["provenance"] = new Dictionary<string, object?>
                {
                    ["factor_id"] = factorId,
                    ["factor_version"] = factorVersion,
                    ["output_value"] = outputValue,
                    ["output_gate"] = outputGate,
                    ["source_version"] = sourceVersion ?? factorVersion
                }
            };

            return _store.AppendAsync("factor_output_history", payload);
        }
    }
}
