using System;
using System.Linq;
using CncModels.Entity;
using CncRepository.Impl;
using Xunit;

namespace CncRepository.Tests
{
    /// <summary>
    /// 品牌字段映射仓储测试
    /// </summary>
    [Collection("Database")]
    public class BrandFieldMappingRepositoryTests : IDisposable
    {
        private readonly BrandFieldMappingRepository _repo;

        public BrandFieldMappingRepositoryTests()
        {
            _repo = new BrandFieldMappingRepository(TestDb.ConnectionString);
            TestDb.TruncateAll();
        }

        public void Dispose()
        {
            TestDb.TruncateAll();
        }

        [Fact]
        public void GetByBrandId_返回所有映射含禁用()
        {
            // 插入2条启用 + 1条禁用
            TestDb.Execute(@"INSERT INTO cnc_brand_field_mapping (brand_id, standard_field, field_name, match_by, data_type, is_required, is_enabled, created_at)
                VALUES (1, 'program_name', 'Tag5', 'id', 'string', 1, 1, NOW()),
                       (1, 'part_count', 'Tag8', 'id', 'number', 1, 1, NOW()),
                       (1, 'spindle_load', 'Tag21', 'id', 'number', 0, 0, NOW())");
            var result = _repo.GetByBrandId(1);
            Assert.Equal(3, result.Count);
        }

        [Fact]
        public void GetEnabledByBrandId_只返回启用的映射()
        {
            TestDb.Execute(@"INSERT IGNORE INTO cnc_brand (id, brand_name, device_field, tags_path, is_enabled, created_at, updated_at)
                VALUES (1, 'FANUC', 'device', 'tags', 1, NOW(), NOW())");
            TestDb.Execute(@"INSERT INTO cnc_brand_field_mapping (brand_id, standard_field, field_name, match_by, data_type, is_required, is_enabled, created_at)
                VALUES (1, 'program_name', 'Tag5', 'id', 'string', 1, 1, NOW()),
                       (1, 'part_count', 'Tag8', 'id', 'number', 1, 1, NOW()),
                       (1, 'spindle_load', 'Tag21', 'id', 'number', 0, 0, NOW())");
            var result = _repo.GetEnabledByBrandId(1);
            Assert.Equal(2, result.Count);
            Assert.All(result, m => Assert.Equal(1, m.IsEnabled));
        }

        [Fact]
        public void Create_默认启用()
        {
            // 确保 brand_id=1 存在
            TestDb.Execute(@"INSERT IGNORE INTO cnc_brand (id, brand_name, device_field, tags_path, is_enabled, created_at, updated_at)
                VALUES (1, 'FANUC', 'device', 'tags', 1, NOW(), NOW())");
            var entity = new BrandFieldMapping
            {
                BrandId = 1,
                StandardField = "program_name",
                FieldName = "Tag5",
                MatchBy = "id",
                DataType = "string",
                IsRequired = 1,
                IsEnabled = 1,
                CreatedAt = DateTime.Now
            };
            var id = _repo.Create(entity);
            Assert.True(id > 0);
            var loaded = _repo.GetById(id);
            Assert.Equal(1, loaded.IsEnabled);
        }

        [Fact]
        public void Update_修改启用状态()
        {
            TestDb.Execute(@"INSERT INTO cnc_brand_field_mapping (brand_id, standard_field, field_name, match_by, data_type, is_required, is_enabled, created_at)
                VALUES (1, 'program_name', 'Tag5', 'id', 'string', 1, 1, NOW())");
            var id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_brand_field_mapping");
            var entity = _repo.GetById(id);
            entity.IsEnabled = 0;
            var result = _repo.Update(entity);
            Assert.True(result);
            Assert.Equal(0, _repo.GetById(id).IsEnabled);
        }

        [Fact]
        public void BatchCreate_批量插入保留启用状态()
        {
            // 确保 brand_id=1 存在
            TestDb.Execute(@"INSERT IGNORE INTO cnc_brand (id, brand_name, device_field, tags_path, is_enabled, created_at, updated_at)
                VALUES (1, 'FANUC', 'device', 'tags', 1, NOW(), NOW())");
            var mappings = new[]
            {
                new BrandFieldMapping { StandardField = "f1", FieldName = "Tag1", MatchBy = "id", DataType = "string", IsRequired = 0, IsEnabled = 1, CreatedAt = DateTime.Now },
                new BrandFieldMapping { StandardField = "f2", FieldName = "Tag2", MatchBy = "id", DataType = "number", IsRequired = 0, IsEnabled = 1, CreatedAt = DateTime.Now },
                new BrandFieldMapping { StandardField = "f3", FieldName = "Tag3", MatchBy = "id", DataType = "string", IsRequired = 0, IsEnabled = 0, CreatedAt = DateTime.Now },
            }.ToList();
            var count = _repo.BatchCreate(1, mappings);
            Assert.Equal(3, count);
            var all = _repo.GetByBrandId(1);
            Assert.Equal(3, all.Count);
            var enabled = _repo.GetEnabledByBrandId(1);
            Assert.Equal(2, enabled.Count);
        }

        [Fact]
        public void Update_修改字段名和启用状态同时生效()
        {
            TestDb.Execute(@"INSERT INTO cnc_brand_field_mapping (brand_id, standard_field, field_name, match_by, data_type, is_required, is_enabled, created_at)
                VALUES (1, 'program_name', 'Tag5', 'id', 'string', 1, 1, NOW())");
            var id = TestDb.QuerySingle<int>("SELECT MAX(id) FROM cnc_brand_field_mapping");
            var entity = _repo.GetById(id);
            entity.FieldName = "Tag5_New";
            entity.IsEnabled = 0;
            _repo.Update(entity);
            var loaded = _repo.GetById(id);
            Assert.Equal("Tag5_New", loaded.FieldName);
            Assert.Equal(0, loaded.IsEnabled);
        }
    }
}
