using System;
using System.IO;
using CounterDrone.Core;
using CounterDrone.Core.Services;
using SQLite;
using Xunit;

namespace CounterDrone.Core.Tests
{
    public class ModelServiceTests : IDisposable
    {
        private readonly string _testDir;
        private readonly SQLiteConnection _db;
        private readonly IModelService _service;
        private readonly IPathProvider _paths;

        public ModelServiceTests()
        {
            _testDir = Path.Combine(Path.GetTempPath(), $"cd_test_{Guid.NewGuid():N}");
            _paths = new TestPathProvider(_testDir);
            var dbManager = new DatabaseManager(_paths);
            _db = dbManager.OpenMainDb();
            _service = new ModelService(new Repository.ModelRepository(_db), _paths);
        }

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

        private string CreateTempModelFile(string extension)
        {
            var path = Path.Combine(_testDir, $"test_model{extension}");
            File.WriteAllText(path, "dummy content");
            return path;
        }

        [Fact]
        public void ImportModel_ValidObj_Succeeds()
        {
            var filePath = CreateTempModelFile(".obj");
            var model = _service.ImportModel(filePath, "TestModel");

            Assert.NotNull(model);
            Assert.Equal("TestModel", model.Name);
            Assert.NotEmpty(model.Id);
        }

        [Fact]
        public void ImportModel_EmptyName_Throws()
        {
            var filePath = CreateTempModelFile(".fbx");
            Assert.Throws<ArgumentException>(() => _service.ImportModel(filePath, ""));
        }

        [Fact]
        public void ImportModel_UnsupportedFormat_Throws()
        {
            var filePath = CreateTempModelFile(".xyz");
            Assert.Throws<ArgumentException>(() => _service.ImportModel(filePath, "BadFormat"));
        }

        [Fact]
        public void ImportModel_AllSupportedFormats()
        {
            foreach (var ext in new[] { ".fbx", ".obj", ".stl", ".glb", ".gltf" })
            {
                var filePath = CreateTempModelFile(ext);
                var model = _service.ImportModel(filePath, $"Model_{ext}");
                Assert.NotNull(model);
            }
        }

        [Fact]
        public void GetAllModels_ReturnsImportedModels()
        {
            _service.ImportModel(CreateTempModelFile(".fbx"), "A");
            _service.ImportModel(CreateTempModelFile(".obj"), "B");

            var all = _service.GetAllModels();
            Assert.Equal(2, all.Count);
        }

        [Fact]
        public void DeleteModel_RemovesModel()
        {
            var model = _service.ImportModel(CreateTempModelFile(".fbx"), "ToDelete");
            _service.DeleteModel(model.Id);

            var result = _service.GetModel(model.Id);
            Assert.Null(result);
        }

        [Fact]
        public void GetModel_NonExistent_ReturnsNull()
        {
            Assert.Null(_service.GetModel("not-exist"));
        }
    }
}
