using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using Xunit;
using QuantEngine.Core.Domain;
using QuantEngine.Core.Models;

namespace QuantEngine.Core.Tests
{
    public class HarnessParityFixture : IDisposable
    {
        public int TotalTests = 0;
        public int PassedTests = 0;
        private readonly object _lock = new object();

        public void RegisterResult(bool passed)
        {
            lock (_lock)
            {
                TotalTests++;
                if (passed) PassedTests++;
            }
        }

        public void Dispose()
        {
            var tempDir = @"C:\Temp\data_feed\Temp";
            if (!Directory.Exists(tempDir))
            {
                Directory.CreateDirectory(tempDir);
            }

            var outputPath = Path.Combine(tempDir, "dotnet_harness_parity_v1.json");
            var result = new
            {
                gate = PassedTests == TotalTests && TotalTests >= 13 ? "PASS" : "FAIL",
                total = TotalTests,
                passed = PassedTests,
                fields_injected = 58 // HarnessInjector.QuantFields length
            };

            File.WriteAllText(outputPath, JsonSerializer.Serialize(result, new JsonSerializerOptions { WriteIndented = true }));
        }
    }

    public class HarnessInjectorTests : IClassFixture<HarnessParityFixture>
    {
        private readonly HarnessParityFixture _fixture;

        public HarnessInjectorTests(HarnessParityFixture fixture)
        {
            _fixture = fixture;
        }

        private (Dictionary<string, object> raw, List<AccountSnapshot> snaps, List<Setting> sets) CreateMockInputs()
        {
            var raw = new Dictionary<string, object>
            {
                { "kospi_index", 2700.0 }
            };
            var snaps = new List<AccountSnapshot>();
            var sets = new List<Setting>
            {
                new Setting { Key = "total_asset_krw", ValueJson = "450000000" }
            };
            return (raw, snaps, sets);
        }

        [Fact]
        public void Harness_10_5_1_InjectsDataFreshness()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("FRESH", result["data_freshness_status"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_1_InjectsIntradayScope()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("INTRADAY_ACTIVE", result["intraday_scope"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_1_InjectsRatchetStage()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("NORMAL", result["ratchet_stage"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_1_InjectsSellPriceSanity()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("PASS", result["sell_price_sanity"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_2_InjectsCashRecoveryPlan()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("NO_PLAN_REQUIRED", result["cash_recovery_plan"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_2_InjectsSemiconductorCluster()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("PASS", result["semiconductor_cluster"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_2_InjectsPositionCountGate()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("PASS", result["position_count_gate"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_3_InjectsHeatConcentration()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal(0.0, result["heat_concentration"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_3_InjectsAntiChasingVelocity()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("CLEAR", result["anti_chasing_velocity"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_3_InjectsDistributionSellDetector()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("PASS", result["distribution_sell_detector"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_4_InjectsPreDistributionWarning()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("PASS", result["pre_distribution_warning"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_4_InjectsTradeQuality()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal("GOOD", result["trade_quality"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }

        [Fact]
        public void Harness_10_5_4_InjectsSfgScalers()
        {
            bool success = false;
            try
            {
                var (raw, snaps, sets) = CreateMockInputs();
                var result = HarnessInjector.InjectComputedHarness(raw, snaps, sets);
                Assert.Equal(1.0, result["sfg_scaler_mrs"]);
                Assert.Equal(1.0, result["sfg_scaler_cla"]);
                success = true;
            }
            finally
            {
                _fixture.RegisterResult(success);
            }
        }
    }
}
