using System.Net;
using System.Text.Json;
using Tiku.Domain.Catalog;
using Tiku.Domain.Common;
using Tiku.Domain.Content;
using Tiku.Domain.Tenancy;

namespace Tiku.IntegrationTests.Api;

public sealed class StudyContentEndpointTests
{
    [Fact]
    public async Task Vocabulary_units_are_active_sorted_and_region_scoped()
    {
        var tenantId = Guid.NewGuid();
        var regionId = Guid.NewGuid();
        await using var factory = new ApiTestFactory();
        await factory.SeedAsync(
            Tenant(tenantId, "master"),
            new Region { Id = regionId, TenantId = tenantId, Name = "测试地区" },
            new VocabularyUnit
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                RegionId = regionId,
                Name = "核心词汇",
                SortOrder = 2,
                IsActive = true
            },
            new VocabularyUnit
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                Name = "全局词汇",
                SortOrder = 1,
                IsActive = true
            },
            new VocabularyUnit
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                RegionId = regionId,
                Name = "停用词汇",
                SortOrder = 0,
                IsActive = false
            });
        using var client = factory.CreateClient();

        using var response =
            await client.GetAsync($"/api/public/catalog/vocabulary-units?tenantCode=master&regionId={regionId}");
        var items = await ReadItemsAsync(response);

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        Assert.Equal(["全局词汇", "核心词汇"], items.Select(item => item.GetProperty("name").GetString()!).ToArray());
    }

    [Fact]
    public async Task Vocabulary_words_support_unit_and_keyword_filters()
    {
        var tenantId = Guid.NewGuid();
        var unitId = Guid.NewGuid();
        await using var factory = new ApiTestFactory();
        await factory.SeedAsync(
            Tenant(tenantId, "master"),
            new VocabularyUnit { Id = unitId, TenantId = tenantId, Name = "Unit 1" },
            new VocabularyWord
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                UnitId = unitId,
                Word = "abandon",
                Meaning = "放弃",
                SortOrder = 1,
                IsActive = true
            },
            new VocabularyWord
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                UnitId = unitId,
                Word = "ability",
                Meaning = "能力",
                SortOrder = 2,
                IsActive = true
            },
            new VocabularyWord
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                Word = "other",
                Meaning = "其他",
                IsActive = true
            });
        using var client = factory.CreateClient();

        using var response =
            await client.GetAsync($"/api/public/catalog/vocabulary-words?tenantCode=master&unitId={unitId}&keyword=放弃");
        var items = await ReadItemsAsync(response);

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        var item = Assert.Single(items);
        Assert.Equal("abandon", item.GetProperty("word").GetString());
    }

    [Fact]
    public async Task Handbook_chapters_are_filtered_by_subject()
    {
        var tenantId = Guid.NewGuid();
        var subjectId = Guid.NewGuid();
        await using var factory = new ApiTestFactory();
        await factory.SeedAsync(
            Tenant(tenantId, "master"),
            new HandbookSubject
            {
                Id = subjectId,
                TenantId = tenantId,
                Name = "语文手册",
                IsActive = true
            },
            new HandbookChapter
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                SubjectId = subjectId,
                Name = "古诗词",
                SortOrder = 1,
                IsActive = true
            },
            new HandbookChapter
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                Name = "其他章节",
                SortOrder = 2,
                IsActive = true
            });
        using var client = factory.CreateClient();

        using var response =
            await client.GetAsync($"/api/public/catalog/handbook-chapters?tenantCode=master&subjectId={subjectId}");
        var items = await ReadItemsAsync(response);

        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        Assert.Equal("古诗词", Assert.Single(items).GetProperty("name").GetString());
    }

    [Fact]
    public async Task Handbook_entries_hide_content_until_requested()
    {
        var tenantId = Guid.NewGuid();
        var chapterId = Guid.NewGuid();
        await using var factory = new ApiTestFactory();
        await factory.SeedAsync(
            Tenant(tenantId, "master"),
            new HandbookChapter
            {
                Id = chapterId,
                TenantId = tenantId,
                Name = "章节",
                IsActive = true
            },
            new HandbookEntry
            {
                Id = Guid.NewGuid(),
                TenantId = tenantId,
                ChapterId = chapterId,
                Title = "知识点",
                Summary = "摘要",
                Content = "完整正文",
                SortOrder = 1,
                IsActive = true
            });
        using var client = factory.CreateClient();

        using var listResponse =
            await client.GetAsync($"/api/public/catalog/handbook-entries?tenantCode=master&chapterId={chapterId}");
        using var detailResponse =
            await client.GetAsync(
                $"/api/public/catalog/handbook-entries?tenantCode=master&chapterId={chapterId}&includeContent=true");
        var listItem = Assert.Single(await ReadItemsAsync(listResponse));
        var detailItem = Assert.Single(await ReadItemsAsync(detailResponse));

        Assert.Equal(HttpStatusCode.OK, listResponse.StatusCode);
        Assert.Equal(HttpStatusCode.OK, detailResponse.StatusCode);
        Assert.Equal(JsonValueKind.Null, listItem.GetProperty("content").ValueKind);
        Assert.Equal("完整正文", detailItem.GetProperty("content").GetString());
    }

    private static Tenant Tenant(Guid id, string slug)
    {
        return new Tenant
        {
            Id = id,
            Slug = slug,
            Name = slug,
            Status = TenantStatus.Active,
            Metadata = JsonDefaults.Object()
        };
    }

    private static async Task<JsonElement[]> ReadItemsAsync(HttpResponseMessage response)
    {
        var body = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
        return body.RootElement
            .GetProperty("items")
            .EnumerateArray()
            .Select(item => item.Clone())
            .ToArray();
    }
}