Option Strict On
Option Explicit On

Imports System
Imports System.Linq
Imports System.Collections.Generic
Imports System.Globalization
Imports System.IO
Imports System.Windows.Forms
Imports Nexamas.UI.Application
Imports Nexamas.UI.Components
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Localization
Imports Nexamas.UI.Output
Imports Nexamas.UI.Theming

''' <summary>
''' Repository-owned consumer compile host for Batch 3 documentation recipes.
''' This project must use only public package-facing APIs. It is not a Showcase helper,
''' not a Friend test harness, and not proof that the recipes are Showcase-ready.
''' </summary>
Friend Module Program
    <STAThread>
    Public Sub Main(args As String())
        Global.System.Windows.Forms.Application.EnableVisualStyles()
        Global.System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(False)
        Dim smokeMode As Boolean = args IsNot Nothing AndAlso
            args.Any(Function(value As String) String.Equals(value, "--smoke", StringComparison.OrdinalIgnoreCase))

        Global.System.Windows.Forms.Application.Run(New Batch3RecipeVerificationForm(smokeMode))
    End Sub
End Module

''' <summary>
''' Runtime host for the Batch 3 sample.
''' </summary>
Friend NotInheritable Class Batch3RecipeVerificationForm
    Inherits Form

    Private Shared ReadOnly RuntimeRouteIds As String() = New String() {"overview", "theme-output", "localization", "large-data"}

    Private ReadOnly _application As MASApplication
    Private ReadOnly _window As MASApplicationWindow
    Private ReadOnly _smokeTimer As Timer
    Private _smokeRouteIndex As Integer
    Private _localizationPage As IDisposable

    Public Sub New(smokeMode As Boolean)
        Text = "Nexamas UI Batch 3 Recipe Verification"
        Width = 1420
        Height = 940
        MinimumSize = New System.Drawing.Size(1120, 760)
        StartPosition = FormStartPosition.CenterScreen
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi
        Me.DoubleBuffered = True

        _application = MASApplication.Create()
        _window = _application.CreateWindow(owner:=Me)

        ConfigureRuntimePages()

        If smokeMode Then
            _smokeTimer = New Timer() With {.Interval = 1200}
            AddHandler _smokeTimer.Tick, AddressOf HandleSmokeTick
            _smokeTimer.Start()
        End If
    End Sub

    Private Sub AttachLocalizationPage()
        _window.Pages.NavigateTo("localization")
    End Sub

    Private Sub ConfigureRuntimePages()
        Dim pages As MASApplicationPageHost = _window.Pages
        pages.ClearPages()
        pages.RegisterPage(
            pageId:="overview",
            title:="Overview",
            groupName:="Batch 3",
            description:="Theme, Output, Localization / RTL, and large-data recipes are separated into scroll-safe routes.",
            buildPage:=Sub(page As MASApplicationLayoutPageBuilder)
                           Batch3RecipeSnippets.BuildRuntimeOverviewPage(
                               _window,
                               page,
                               Sub() pages.NavigateTo("theme-output"),
                               AddressOf AttachLocalizationPage,
                               Sub() pages.NavigateTo("large-data"))
                       End Sub)
        pages.RegisterPage(
            pageId:="theme-output",
            title:="Theme and Output",
            groupName:="Batch 3",
            description:="Theme selection, surface materials, visual capture, capability checks, and manifest export.",
            buildPage:=Sub(page As MASApplicationLayoutPageBuilder)
                           Batch3RecipeSnippets.BuildRuntimeThemeOutputPage(_application, _window, page)
                       End Sub)
        pages.RegisterPage(
            pageId:="localization",
            title:="Localization / RTL",
            groupName:="Batch 3",
            description:="The official Nexamas UI-owned Localization / RTL page attached inside a vertically scrollable workspace.",
            buildPage:=Sub(page As MASApplicationLayoutPageBuilder)
                           If _localizationPage IsNot Nothing Then
                               _localizationPage.Dispose()
                               _localizationPage = Nothing
                           End If
                           _localizationPage = MASLocalizationRtl.AttachPage(_window, page)
                       End Sub)
        pages.RegisterPage(
            pageId:="large-data",
            title:="Large DataGrid",
            groupName:="Batch 3",
            description:="A dedicated 250-row DataGrid surface with sufficient height and no competing dashboard content.",
            buildPage:=Sub(page As MASApplicationLayoutPageBuilder)
                           Batch3RecipeSnippets.BuildRuntimeLargeDataPage(_window, page)
                       End Sub)

        pages.WithNavigationVisible(True).
            WithBreadcrumbVisible(True).
            WithBreadcrumbRootText("Recipe verification").
            WithRegionBackgrounds(True).
            WithRhythm(MASApplicationSurfaceRhythm.Comfortable).
            WithNavigationSize(MASApplicationSurfaceSideSize.Compact)
        pages.Show()
    End Sub

    Private Sub HandleSmokeTick(sender As Object, e As EventArgs)
        If _smokeRouteIndex < RuntimeRouteIds.Length - 1 Then
            _smokeRouteIndex += 1
            _window.Pages.NavigateTo(RuntimeRouteIds(_smokeRouteIndex))
            Return
        End If

        _smokeTimer.Stop()
        Close()
    End Sub

    Protected Overrides Sub OnFormClosed(e As FormClosedEventArgs)
        If _smokeTimer IsNot Nothing Then
            RemoveHandler _smokeTimer.Tick, AddressOf HandleSmokeTick
            _smokeTimer.Dispose()
        End If
        If _localizationPage IsNot Nothing Then
            _localizationPage.Dispose()
            _localizationPage = Nothing
        End If

        If _window IsNot Nothing Then _window.Dispose()
        If _application IsNot Nothing Then _application.Dispose()
        MyBase.OnFormClosed(e)
    End Sub
End Class

''' <summary>
''' Public-API-only snippets corresponding to Batch 3 recipe IDs.
''' These methods intentionally mirror the documentation snippets closely so a successful Windows build
''' can be recorded against the recipe build-verification ledger.
''' </summary>
Friend NotInheritable Class Batch3RecipeSnippets
    Private Sub New()
    End Sub

    Public Shared Sub BuildBatch3LandingPage(application As MASApplication,
                                            window As MASApplicationWindow,
                                            attachLocalization As Action)
        Dim title As MASTitle = window.Controls.AddTitle("Batch 3 recipes")
        Dim status As MASLabel = window.Controls.AddLabel("Ready. Theme, RTL, Output, and large-data boundary recipes are present in this consumer compile host.")

        Dim themeButton As MASButton = window.Controls.AddButton("Apply theme/material")
        Dim optionsButton As MASButton = window.Controls.AddButton("List surface options")
        Dim rtlPageButton As MASButton = window.Controls.AddButton("Attach RTL page")
        Dim captureButton As MASButton = window.Controls.AddButton("Export visual capture")
        Dim manifestButton As MASButton = window.Controls.AddButton("Export Output manifest")

        AddHandler themeButton.Click,
            Sub(sender As Object, e As EventArgs)
                ApplyThemeAndSurface(application, window)
                status.WithText("Theme/surface recipe executed.")
            End Sub

        AddHandler optionsButton.Click,
            Sub(sender As Object, e As EventArgs)
                Dim names As String() = GetSurfaceMaterialDisplayNames()
                status.WithText("Selectable surface materials: " & names.Length.ToString(CultureInfo.InvariantCulture))
            End Sub

        AddHandler rtlPageButton.Click,
            Sub(sender As Object, e As EventArgs)
                If attachLocalization IsNot Nothing Then attachLocalization.Invoke()
            End Sub

        AddHandler captureButton.Click,
            Sub(sender As Object, e As EventArgs)
                Dim result As MASOutputResult = ExportVisualCapture(application)
                status.WithText(result.Summary)
            End Sub

        AddHandler manifestButton.Click,
            Sub(sender As Object, e As EventArgs)
                Dim canExportPdfNow As Boolean = CanExportPdf(application)
                Dim result As MASOutputResult = ExportOutputCatalog(application)
                status.WithText("Manifest: " & result.Status.ToString() & "; PDF available: " & canExportPdfNow.ToString())
            End Sub

        Dim grid As MASDataGrid = CreateLargeCustomerGridControl(window, CreateLargeRows(250))

        window.Controls.LayoutPage(
            Sub(page As MASApplicationLayoutPageBuilder)
                page.Padding(MASLayoutSpacing.Spacious)
                page.Spacing(MASLayoutSpacing.Medium)
                page.FullWidth(title, MASSize.FillWidth)
                page.FullWidth(status, MASSize.FillWidth)
                page.ActionGroup(
                    Sub(actions As MASApplicationActionGroupLayoutBuilder)
                        actions.AlignStart().EqualItemWidth().
                            Add(themeButton, MASSize.Default).
                            Add(optionsButton, MASSize.Default).
                            Add(rtlPageButton, MASSize.Default).
                            Add(captureButton, MASSize.Default).
                            Add(manifestButton, MASSize.Default)
                    End Sub)
                page.FullWidth(grid, MASSize.FillWidth)
            End Sub)
    End Sub

    ' Recipe: Theme.Surface.Apply
    Public Shared Sub ApplyThemeAndSurface(application As MASApplication,
                                           window As MASApplicationWindow)
        For Each theme As IMASAppTheme In application.Theme.GetAll()
            If theme IsNot Nothing Then
                ' Use theme.Id and theme.DisplayName in a settings UI.
            End If
        Next

        If Not window.Theme.TryUseGlobally("premium-office-mas-signature") Then
            window.Services.Toasts.Warning("The requested theme was not registered.", "Theme")
        End If

        Dim options As MASApplicationSurfaceMaterialOption() =
            MASApplicationSurfaceMaterialGateway.GetSelectableMaterials()

        If options Is Nothing OrElse options.Length = 0 Then Return

        Dim scope As MASApplicationSurfaceMaterialScope =
            MASApplicationSurfaceMaterialGateway.CreateScope(window)

        scope.Apply(options(0).Key)
    End Sub

    ' Recipe: Theme.Surface.Options
    Public Shared Function GetSurfaceMaterialDisplayNames() As String()
        Dim options As MASApplicationSurfaceMaterialOption() =
            MASApplicationSurfaceMaterialGateway.GetSelectableMaterials()

        If options Is Nothing Then Return Array.Empty(Of String)()

        Dim names As New List(Of String)()
        For Each optionItem As MASApplicationSurfaceMaterialOption In options
            If optionItem IsNot Nothing Then names.Add(optionItem.DisplayName)
        Next

        Return names.ToArray()
    End Function

    ' Recipe: Localization.Rtl.AttachPage
    Public Shared Function AttachLocalizationPage(window As MASApplicationWindow) As IDisposable
        Return MASLocalizationRtl.AttachPage(window)
    End Function

    ' Recipe: Localization.Rtl.AttachSection
    Public Shared Function AddLocalizationSection(window As MASApplicationWindow) As IDisposable
        Dim sectionLifetime As IDisposable = Nothing

        window.Controls.LayoutPage(
            Sub(page As MASApplicationLayoutPageBuilder)
                sectionLifetime = MASLocalizationRtl.AttachPage(window, page)
            End Sub)

        Return sectionLifetime
    End Function

    ' Recipe: Output.VisualCapture
    Public Shared Function ExportVisualCapture(application As MASApplication) As MASOutputResult
        Dim filePath As String = Path.Combine(
            Path.GetTempPath(),
            "Nexamas.UI.VisualCapture.png")

        Dim result As MASOutputResult = application.Output.ExportVisualCapturePng(
            MASOutputTarget.File(filePath),
            MASOutputOptions.ForVisualCapture())

        If Not result.Succeeded Then
            ' Read result.Status and result.Summary before showing a failure message.
        End If

        Return result
    End Function

    ' Recipe: Output.CapabilityCatalog
    Public Shared Function CanExportPdf(application As MASApplication) As Boolean
        Return application.Output.CanExport(
            MASOutputArtifactKind.PdfDocument,
            MASOutputFormat.Pdf)
    End Function

    ' Recipe: Output.Manifest
    Public Shared Function ExportOutputCatalog(application As MASApplication) As MASOutputResult
        Dim outputDirectory As String = Path.Combine(
            Path.GetTempPath(),
            "Nexamas.UI.Output")

        Dim result As MASOutputResult = application.Output.ExportCapabilityCatalogManifest(
            MASOutputFormat.Json,
            MASOutputTarget.Directory(outputDirectory))

        If Not result.Succeeded Then
            ' Inspect result.Status and result.Summary.
        End If

        Return result
    End Function

    ' Recipe: DataGrid.LargeData.Boundary
    Public Shared Sub BuildLargeCustomerGrid(window As MASApplicationWindow,
                                             rows As IEnumerable(Of Object()))
        Dim grid As MASDataGrid = CreateLargeCustomerGridControl(window, rows)

        window.Controls.LayoutPage(
            Sub(page As MASApplicationLayoutPageBuilder)
                page.Padding(MASLayoutSpacing.Spacious)
                page.FullWidth(grid, MASSize.FillWidth)
            End Sub)
    End Sub

    Private Shared Function CreateLargeCustomerGridControl(window As MASApplicationWindow,
                                                           rows As IEnumerable(Of Object())) As MASDataGrid
        Dim view As New MASDataView()

        view.AddColumn("id", "ID").WithWidth(80).ReadOnlyColumn()
        view.AddColumn("name", "Name").WithWidth(220)
        view.AddColumn("status", "Status").WithWidth(160)

        Using refresh As IDisposable = view.DeferRefresh()
            view.AddRows(rows)
        End Using

        Dim grid As MASDataGrid = window.Controls.AddDataGrid(
            Sub(dataGrid As MASDataGrid)
                dataGrid.SetDataView(view)
                dataGrid.SummaryFooterMode = MASDataGridSummaryFooterMode.Automatic
                dataGrid.SummaryAutoPreparationRowLimit = 5000
                dataGrid.WithSize(MASSize.FillWidth)
            End Sub)

        Return grid
    End Function

    Private Shared Iterator Function CreateLargeRows(count As Integer) As IEnumerable(Of Object())
        For index As Integer = 1 To count
            Yield New Object() {
                index,
                "Customer " & index.ToString(CultureInfo.InvariantCulture),
                If(index Mod 2 = 0, "Active", "Pending")
            }
        Next
    End Function

    Public Shared Sub BuildRuntimeOverviewPage(window As MASApplicationWindow,
                                               page As MASApplicationLayoutPageBuilder,
                                               openThemeOutput As Action,
                                               openLocalization As Action,
                                               openLargeData As Action)
        Dim banner As MASStatusBanner = window.Controls.AddStatusBanner(
            title:="Batch 3 recipe groups",
            message:="Open one focused route at a time. The PageHost keeps the active workspace scrollable and prevents retained product pages from drawing over the landing page.",
            tone:=MASToastTone.Info)
        Dim themeOutputButton As MASButton = window.Controls.AddButton("Open Theme and Output")
        Dim localizationButton As MASButton = window.Controls.AddButton("Open Localization / RTL")
        Dim largeDataButton As MASButton = window.Controls.AddButton("Open Large DataGrid")
        Dim note As MASLabel = window.Controls.AddLabel("Each route uses only public package-facing APIs and keeps its own controls, sizing intent, and lifetime boundary.")

        AddHandler themeOutputButton.Click, Sub(sender As Object, e As EventArgs) If openThemeOutput IsNot Nothing Then openThemeOutput.Invoke()
        AddHandler localizationButton.Click, Sub(sender As Object, e As EventArgs) If openLocalization IsNot Nothing Then openLocalization.Invoke()
        AddHandler largeDataButton.Click, Sub(sender As Object, e As EventArgs) If openLargeData IsNot Nothing Then openLargeData.Invoke()

        page.Spacing(MASLayoutSpacing.Large)
        page.FullWidth(banner, MASSize.FillWidth)
        page.FullWidth(note, MASSize.FillWidth)
        page.Flow().
            Gap(MASLayoutSpacing.Medium).
            EqualItemWidth().
            Add(themeOutputButton, MASSize.Default).
            Add(localizationButton, MASSize.Default).
            Add(largeDataButton, MASSize.Default)
    End Sub

    Public Shared Sub BuildRuntimeThemeOutputPage(application As MASApplication,
                                                  window As MASApplicationWindow,
                                                  page As MASApplicationLayoutPageBuilder)
        Dim status As MASLabel = window.Controls.AddLabel("Ready. Run one public Theme or Output recipe at a time.")
        Dim themeButton As MASButton = window.Controls.AddButton("Apply theme/material")
        Dim optionsButton As MASButton = window.Controls.AddButton("List surface options")
        Dim captureButton As MASButton = window.Controls.AddButton("Export visual capture")
        Dim manifestButton As MASButton = window.Controls.AddButton("Export Output manifest")

        AddHandler themeButton.Click,
            Sub(sender As Object, e As EventArgs)
                ApplyThemeAndSurface(application, window)
                status.WithText("Theme/surface recipe executed.")
            End Sub
        AddHandler optionsButton.Click,
            Sub(sender As Object, e As EventArgs)
                Dim names As String() = GetSurfaceMaterialDisplayNames()
                status.WithText("Selectable surface materials: " & names.Length.ToString(CultureInfo.InvariantCulture))
            End Sub
        AddHandler captureButton.Click,
            Sub(sender As Object, e As EventArgs)
                Dim result As MASOutputResult = ExportVisualCapture(application)
                status.WithText(result.Summary)
            End Sub
        AddHandler manifestButton.Click,
            Sub(sender As Object, e As EventArgs)
                Dim canExportPdfNow As Boolean = CanExportPdf(application)
                Dim result As MASOutputResult = ExportOutputCatalog(application)
                status.WithText("Manifest: " & result.Status.ToString() & "; PDF available: " & canExportPdfNow.ToString())
            End Sub

        page.Spacing(MASLayoutSpacing.Large)
        page.FullWidth(status, MASSize.FillWidth)
        page.Flow().
            Gap(MASLayoutSpacing.Medium).
            EqualItemWidth().
            Add(themeButton, MASSize.Default).
            Add(optionsButton, MASSize.Default).
            Add(captureButton, MASSize.Default).
            Add(manifestButton, MASSize.Default)
    End Sub

    Public Shared Sub BuildRuntimeLargeDataPage(window As MASApplicationWindow,
                                                page As MASApplicationLayoutPageBuilder)
        Dim note As MASLabel = window.Controls.AddLabel("The large-data recipe owns the main workspace instead of sharing height with unrelated Theme and Localization surfaces.")
        Dim grid As MASDataGrid = CreateLargeCustomerGridControl(window, CreateLargeRows(250))

        page.Spacing(MASLayoutSpacing.Large)
        page.FullWidth(note, MASSize.FillWidth)
        page.FullWidth(grid, MASSize.FillWidth.OffsetHeight(420.0F))
    End Sub

End Class
