using Bunit;
using MudBlazor;
using Xunit;
using QuantEngine.Web.Client.Pages;
using QuantEngine.Web.Client.Components;

namespace QuantEngine.Web.Tests;

/// <summary>
/// Unit tests for Dashboard component using bUnit
/// </summary>
public class DashboardComponentTests : TestContext
{
    [Fact]
    public void Dashboard_Renders_Without_Errors()
    {
        // Arrange & Act
        var cut = RenderComponent<Dashboard>();

        // Assert
        cut.Markup.Should().Contain("관리자 대시보드");
    }

    [Fact]
    public void Dashboard_Displays_KPI_Cards()
    {
        // Arrange & Act
        var cut = RenderComponent<Dashboard>();

        // Assert - Should have 4 KPI cards
        cut.FindAll(".mud-paper").Count.Should().BeGreaterThanOrEqualTo(4);
        cut.Markup.Should().Contain("총 수집 실행");
        cut.Markup.Should().Contain("성공률");
        cut.Markup.Should().Contain("최근 에러");
        cut.Markup.Should().Contain("마지막 동기화");
    }

    [Fact]
    public void Dashboard_Shows_System_Status()
    {
        // Arrange & Act
        var cut = RenderComponent<Dashboard>();

        // Assert
        cut.Markup.Should().Contain("시스템 상태");
        cut.Markup.Should().Contain("API 서버");
        cut.Markup.Should().Contain("데이터베이스");
    }

    [Fact]
    public void Dashboard_Has_Activity_Feed()
    {
        // Arrange & Act
        var cut = RenderComponent<Dashboard>();

        // Assert
        cut.Markup.Should().Contain("최근 활동");
    }

    [Fact]
    public void Dashboard_Has_Collections_Table()
    {
        // Arrange & Act
        var cut = RenderComponent<Dashboard>();

        // Assert
        cut.Markup.Should().Contain("최근 데이터 수집 실행");
        cut.Markup.Should().Contain("새로고침");
    }
}

/// <summary>
/// Unit tests for FormField component
/// </summary>
public class FormFieldComponentTests : TestContext
{
    [Fact]
    public void FormField_Renders_Text_Input()
    {
        // Arrange
        var parameters = new ComponentParameterCollection
        {
            { "Label", "사용자명" },
            { "Type", "text" },
            { "Placeholder", "이름 입력" }
        };

        // Act
        var cut = RenderComponent<FormField>(parameters);

        // Assert
        cut.Markup.Should().Contain("사용자명");
        cut.Markup.Should().Contain("이름 입력");
    }

    [Fact]
    public void FormField_Shows_Required_Indicator()
    {
        // Arrange
        var parameters = new ComponentParameterCollection
        {
            { "Label", "이메일" },
            { "Type", "email" },
            { "Required", true }
        };

        // Act
        var cut = RenderComponent<FormField>(parameters);

        // Assert
        cut.Markup.Should().Contain("*");
    }

    [Fact]
    public void FormField_Displays_Error_Message()
    {
        // Arrange
        var parameters = new ComponentParameterCollection
        {
            { "Label", "비밀번호" },
            { "Type", "password" },
            { "ErrorMessage", "최소 8자 이상 입력하세요" }
        };

        // Act
        var cut = RenderComponent<FormField>(parameters);

        // Assert
        cut.Markup.Should().Contain("최소 8자 이상 입력하세요");
    }

    [Fact]
    public void FormField_Shows_Help_Text()
    {
        // Arrange
        var parameters = new ComponentParameterCollection
        {
            { "Label", "핸드폰" },
            { "Type", "tel" },
            { "HelpText", "하이픈 없이 숫자만 입력하세요" }
        };

        // Act
        var cut = RenderComponent<FormField>(parameters);

        // Assert
        cut.Markup.Should().Contain("하이픈 없이 숫자만 입력하세요");
    }
}

/// <summary>
/// Unit tests for Portfolio component
/// </summary>
public class PortfolioComponentTests : TestContext
{
    [Fact]
    public void Portfolio_Renders_Without_Errors()
    {
        // Arrange & Act
        var cut = RenderComponent<Portfolio>();

        // Assert
        cut.Markup.Should().Contain("포트폴리오");
    }

    [Fact]
    public void Portfolio_Displays_Summary_Cards()
    {
        // Arrange & Act
        var cut = RenderComponent<Portfolio>();

        // Assert - Should have summary cards
        cut.Markup.Should().Contain("총 평가액");
        cut.Markup.Should().Contain("보유 종목");
        cut.Markup.Should().Contain("수익률");
        cut.Markup.Should().Contain("위험도");
    }

    [Fact]
    public void Portfolio_Shows_Asset_Table()
    {
        // Arrange & Act
        var cut = RenderComponent<Portfolio>();

        // Assert
        cut.Markup.Should().Contain("자산 구성");
        cut.Markup.Should().Contain("종목/펀드명");
        cut.Markup.Should().Contain("평가액");
    }

    [Fact]
    public void Portfolio_Shows_Asset_Classification()
    {
        // Arrange & Act
        var cut = RenderComponent<Portfolio>();

        // Assert
        cut.Markup.Should().Contain("자산 분류");
        cut.Markup.Should().Contain("대형주");
        cut.Markup.Should().Contain("중형주");
    }

    [Fact]
    public void Portfolio_Shows_Trading_History()
    {
        // Arrange & Act
        var cut = RenderComponent<Portfolio>();

        // Assert
        cut.Markup.Should().Contain("거래 이력");
        cut.Markup.Should().Contain("구분");
        cut.Markup.Should().Contain("금액");
    }
}

/// <summary>
/// Unit tests for NavMenu component
/// </summary>
public class NavMenuComponentTests : TestContext
{
    [Fact]
    public void NavMenu_Renders_Navigation_Links()
    {
        // Arrange & Act
        var cut = RenderComponent<NavMenu>();

        // Assert
        cut.Markup.Should().Contain("대시보드");
        cut.Markup.Should().Contain("관리");
        cut.Markup.Should().Contain("운영");
    }

    [Fact]
    public void NavMenu_Has_Admin_Section()
    {
        // Arrange & Act
        var cut = RenderComponent<NavMenu>();

        // Assert
        cut.Markup.Should().Contain("사용자 관리");
        cut.Markup.Should().Contain("데이터 수집");
        cut.Markup.Should().Contain("설정");
    }

    [Fact]
    public void NavMenu_Has_Help_Section()
    {
        // Arrange & Act
        var cut = RenderComponent<NavMenu>();

        // Assert
        cut.Markup.Should().Contain("도움말");
        cut.Markup.Should().Contain("문서");
        cut.Markup.Should().Contain("API");
    }
}
