using System;
using System.IO;
using System.Text.Json;
using CounterDrone.Core;
using CounterDrone.Core.Models;
using CounterDrone.Core.Repository;
using SQLite;
using Xunit;

namespace CounterDrone.Core.Tests
{
    public class AmmunitionSpecRepositoryTests : IDisposable
    {
        private readonly string _testDir;
        private readonly SQLiteConnection _db;
        private readonly AmmunitionSpecRepository _repo;

        public AmmunitionSpecRepositoryTests()
        {
            _testDir = Path.Combine(Path.GetTempPath(), $"cd_test_{Guid.NewGuid():N}");
            var paths = new TestPathProvider(_testDir);
            var dbManager = new DatabaseManager(paths);
            _db = dbManager.OpenMainDb();
            _repo = new AmmunitionSpecRepository(_db);
        }

        public void Dispose()
        {
            _db?.Close();
            if (Directory.Exists(_testDir))
                Directory.Delete(_testDir, true);
        }

        [Fact]
        public void Insert_And_GetById_ReturnsSpec()
        {
            var spec = new AmmunitionSpec
            {
                AerosolType = (int)AerosolType.InertGas,
                Name = "惰性气体弹-A1",
                InitialRadius = 50.0,
                InitialVolume = 500000.0,
                CoreDensity = 1.2,
                EffectiveConcentration = 0.05,
                SourceStrength = 1.0,
                MaxRadius = 200.0,
                MaxDuration = 60.0
            };

            _repo.Insert(spec);

            var result = _repo.GetById(spec.Id);
            Assert.NotNull(result);
            Assert.Equal("惰性气体弹-A1", result.Name);
            Assert.Equal(50.0, result.InitialRadius);
            Assert.Equal((int)AerosolType.InertGas, result.AerosolType);
        }

        [Fact]
        public void GetByAerosolType_FiltersCorrectly()
        {
            _repo.Insert(new AmmunitionSpec
            {
                Name = "Inert-A",
                AerosolType = (int)AerosolType.InertGas
            });
            _repo.Insert(new AmmunitionSpec
            {
                Name = "Inert-B",
                AerosolType = (int)AerosolType.InertGas
            });
            _repo.Insert(new AmmunitionSpec
            {
                Name = "Active-A",
                AerosolType = (int)AerosolType.ActiveMaterial
            });

            var inertSpecs = _repo.GetByAerosolType((int)AerosolType.InertGas);
            Assert.Equal(2, inertSpecs.Count);

            var activeSpecs = _repo.GetByAerosolType((int)AerosolType.ActiveMaterial);
            Assert.Single(activeSpecs);
        }

        [Fact]
        public void ImportFromJson_LoadsSpecs()
        {
            var json = @"[
                {""Id"":""spec-1"",""AerosolType"":0,""Name"":""惰性气体弹"",""InitialRadius"":50,""InitialVolume"":500000,""CoreDensity"":1.2,""EdgeDensity"":0.1,""InitialTemperature"":300,""BuoyancyFactor"":0.5,""EffectiveConcentration"":0.05,""DispersionRateBase"":5,""MaxRadius"":200,""MaxDuration"":60,""ParticlesJson"":""{}""},
                {""Id"":""spec-2"",""AerosolType"":1,""Name"":""活性材料弹"",""InitialRadius"":30,""InitialVolume"":100000,""CoreDensity"":2.0,""EdgeDensity"":0.2,""InitialTemperature"":500,""BuoyancyFactor"":0.3,""EffectiveConcentration"":0.1,""DispersionRateBase"":3,""MaxRadius"":150,""MaxDuration"":45,""ParticlesJson"":""{}""}
            ]";

            var specs = JsonSerializer.Deserialize<AmmunitionSpec[]>(json);
            Assert.NotNull(specs);
            _repo.InsertAll(specs);

            var all = _repo.GetAll();
            Assert.Equal(2, all.Count);
            Assert.Contains(all, s => s.Name == "惰性气体弹");
            Assert.Contains(all, s => s.Name == "活性材料弹");
        }
    }
}
