Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Values

Namespace Nexamas.UI.Components

    Friend Enum MASMasterDetailContentStateKind
        Normal = 0
        Empty = 1
        Faulted = 2
    End Enum

    ''' <summary>
    ''' Friend-only state snapshot for MasterDetailView empty/error presentation.
    ''' This is visual-state governance only; it is not routing, provider ownership,
    ''' object inspection, or public data binding.
    ''' </summary>
    Friend NotInheritable Class MASMasterDetailContentStateSnapshot
        Friend Sub New(kind As MASMasterDetailContentStateKind,
                       message As String,
                       reason As String,
                       revision As Integer,
                       itemCount As Integer,
                       selectedItemKey As String,
                       sourceRevision As Integer)
            Me.Kind = kind
            Me.Message = MASMasterDetailViewPolicy.ClampText(MASMasterDetailViewPolicy.NormalizeText(message), 420)
            Me.Reason = MASMasterDetailViewPolicy.NormalizeText(reason)
            Me.Revision = Math.Max(0, revision)
            Me.ItemCount = Math.Max(0, itemCount)
            Me.SelectedItemKey = MASMasterDetailViewPolicy.NormalizeText(selectedItemKey)
            Me.SourceRevision = sourceRevision
        End Sub

        Friend ReadOnly Property Kind As MASMasterDetailContentStateKind
        Friend ReadOnly Property Message As String
        Friend ReadOnly Property Reason As String
        Friend ReadOnly Property Revision As Integer
        Friend ReadOnly Property ItemCount As Integer
        Friend ReadOnly Property SelectedItemKey As String
        Friend ReadOnly Property SourceRevision As Integer

        Friend ReadOnly Property IsEmptyStateVisible As Boolean
            Get
                Return Kind = MASMasterDetailContentStateKind.Empty AndAlso ItemCount = 0
            End Get
        End Property

        Friend ReadOnly Property IsErrorStateVisible As Boolean
            Get
                Return Kind = MASMasterDetailContentStateKind.Faulted AndAlso Message.Length > 0
            End Get
        End Property

        Friend ReadOnly Property IsNormalState As Boolean
            Get
                Return Kind = MASMasterDetailContentStateKind.Normal
            End Get
        End Property

        Friend ReadOnly Property IsStructurallyValid As Boolean
            Get
                If Kind = MASMasterDetailContentStateKind.Normal Then Return True
                Return Message.Length > 0 AndAlso Reason.Length > 0
            End Get
        End Property
    End Class

    Partial Public NotInheritable Class MASMasterDetailView

#Region "Friend empty/error state foundation"

        Private _masterDetailContentState As MASMasterDetailContentStateKind = MASMasterDetailContentStateKind.Normal
        Private _masterDetailContentMessage As String = String.Empty
        Private _masterDetailContentReason As String = String.Empty
        Private _masterDetailContentStateRevision As Integer

        Friend Function SetMasterDetailEmptyState(Optional message As String = Nothing,
                                                  Optional reason As String = "") As Boolean
            Dim text As String = MASMasterDetailViewPolicy.ClampText(MASMasterDetailViewPolicy.NormalizeText(If(message, MasterDetailViewTokens.EmptyMasterText)), 420)
            Return SetMasterDetailContentState(MASMasterDetailContentStateKind.Empty, text, If(reason, "MasterDetail.Empty"))
        End Function

        Friend Function SetMasterDetailErrorState(message As String,
                                                  Optional reason As String = "") As Boolean
            Dim text As String = MASMasterDetailViewPolicy.ClampText(MASMasterDetailViewPolicy.NormalizeText(message), 420)
            If text.Length = 0 Then text = "Unable to load master/detail content."
            Return SetMasterDetailContentState(MASMasterDetailContentStateKind.Faulted, text, If(reason, "MasterDetail.Error"))
        End Function

        Friend Function ClearMasterDetailStatusState(Optional reason As String = "") As Boolean
            Return SetMasterDetailContentState(MASMasterDetailContentStateKind.Normal, String.Empty, If(reason, "MasterDetail.Normal"))
        End Function

        Friend Function CreateMasterDetailContentStateSnapshot() As MASMasterDetailContentStateSnapshot
            Return New MASMasterDetailContentStateSnapshot(_masterDetailContentState,
                                                           _masterDetailContentMessage,
                                                           _masterDetailContentReason,
                                                           _masterDetailContentStateRevision,
                                                           _items.Count,
                                                           SelectedItemKey,
                                                           _masterDetailSourceRevision)
        End Function

        Friend Function HasEmptyErrorStateFoundationForTests() As Boolean
            ClearItems()
            Dim emptySnapshot As MASMasterDetailContentStateSnapshot = CreateMasterDetailContentStateSnapshot()
            If emptySnapshot Is Nothing OrElse Not emptySnapshot.IsStructurallyValid OrElse Not emptySnapshot.IsEmptyStateVisible Then Return False

            If Not SetMasterDetailErrorState("Provider failed", "MasterDetail.EmptyErrorProof") Then Return False
            Dim errorSnapshot As MASMasterDetailContentStateSnapshot = CreateMasterDetailContentStateSnapshot()
            If errorSnapshot Is Nothing OrElse Not errorSnapshot.IsStructurallyValid OrElse Not errorSnapshot.IsErrorStateVisible Then Return False

            AddItem("case-1", "Case 1", "Ready", "Detail", "Loaded detail")
            Dim normalSnapshot As MASMasterDetailContentStateSnapshot = CreateMasterDetailContentStateSnapshot()
            Return normalSnapshot IsNot Nothing AndAlso normalSnapshot.IsStructurallyValid AndAlso normalSnapshot.IsNormalState AndAlso normalSnapshot.ItemCount = 1
        End Function

        Private Function SetMasterDetailContentState(kind As MASMasterDetailContentStateKind,
                                                     message As String,
                                                     reason As String) As Boolean
            Dim normalizedMessage As String = MASMasterDetailViewPolicy.ClampText(MASMasterDetailViewPolicy.NormalizeText(message), 420)
            If kind = MASMasterDetailContentStateKind.Normal Then normalizedMessage = String.Empty
            Dim normalizedReason As String = MASMasterDetailViewPolicy.NormalizeText(reason)
            If normalizedReason.Length = 0 Then normalizedReason = kind.ToString()

            If _masterDetailContentState = kind AndAlso
               String.Equals(_masterDetailContentMessage, normalizedMessage, StringComparison.Ordinal) AndAlso
               String.Equals(_masterDetailContentReason, normalizedReason, StringComparison.Ordinal) Then
                Return True
            End If

            _masterDetailContentState = kind
            _masterDetailContentMessage = normalizedMessage
            _masterDetailContentReason = normalizedReason
            _masterDetailContentStateRevision += 1
            InvalidateVisual()
            Return True
        End Function

        Private Sub ClearMasterDetailStatusForLoadedItems(reason As String)
            If _items.Count > 0 Then
                ClearMasterDetailStatusState(reason)
            End If
        End Sub

        Private Function ResolveMasterEmptyText() As String
            If _masterDetailContentState = MASMasterDetailContentStateKind.Faulted Then Return _masterDetailContentMessage
            If _masterDetailContentMessage.Length > 0 Then Return _masterDetailContentMessage
            Return MasterDetailViewTokens.EmptyMasterText
        End Function

        Private Function ResolveDetailEmptyText() As String
            If _masterDetailContentState = MASMasterDetailContentStateKind.Faulted Then Return _masterDetailContentMessage
            If _masterDetailContentMessage.Length > 0 Then Return _masterDetailContentMessage
            Return MasterDetailViewTokens.EmptyDetailText
        End Function

#End Region

    End Class

End Namespace
