Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Values

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only immutable drop decision snapshot for MASKanbanBoard. It gives the
    ''' production gates a deterministic way to prove legal targets, rejected-drop
    ''' reasons, requested-index normalization, and source-detach intent without
    ''' introducing a public workflow or task-provider API.
    ''' </summary>
    Friend NotInheritable Class MASKanbanBoardDropRuleSnapshot
        Friend Sub New(cardKey As String,
                       sourceColumnKey As String,
                       targetColumnKey As String,
                       requestedTargetCardIndex As Integer,
                       resolvedTargetCardIndex As Integer,
                       isLegalTarget As Boolean,
                       isNoOp As Boolean,
                       wouldDetachSource As Boolean,
                       rejectReason As String)
            Me.CardKey = If(cardKey, String.Empty).Trim()
            Me.SourceColumnKey = If(sourceColumnKey, String.Empty).Trim()
            Me.TargetColumnKey = If(targetColumnKey, String.Empty).Trim()
            Me.RequestedTargetCardIndex = requestedTargetCardIndex
            Me.ResolvedTargetCardIndex = Math.Max(0, resolvedTargetCardIndex)
            Me.IsLegalTarget = isLegalTarget
            Me.IsNoOp = isNoOp
            Me.WouldDetachSource = wouldDetachSource
            Me.RejectReason = If(rejectReason, String.Empty).Trim()
        End Sub

        Friend ReadOnly Property CardKey As String
        Friend ReadOnly Property SourceColumnKey As String
        Friend ReadOnly Property TargetColumnKey As String
        Friend ReadOnly Property RequestedTargetCardIndex As Integer
        Friend ReadOnly Property ResolvedTargetCardIndex As Integer
        Friend ReadOnly Property IsLegalTarget As Boolean
        Friend ReadOnly Property IsNoOp As Boolean
        Friend ReadOnly Property WouldDetachSource As Boolean
        Friend ReadOnly Property RejectReason As String

        Friend ReadOnly Property HasRejectedDropFeedback As Boolean
            Get
                Return IsLegalTarget OrElse RejectReason.Length > 0
            End Get
        End Property
    End Class

    Partial Public NotInheritable Class MASKanbanBoard

#Region "Friend drop-rule diagnostics"

        Friend Function CreateDropRuleSnapshot(cardKey As String,
                                               targetColumnKey As String,
                                               targetCardIndex As Integer) As MASKanbanBoardDropRuleSnapshot
            Dim normalizedCardKey As String = If(cardKey, String.Empty).Trim()
            Dim normalizedTargetColumnKey As String = If(targetColumnKey, String.Empty).Trim()
            If normalizedCardKey.Length = 0 Then
                Return New MASKanbanBoardDropRuleSnapshot(normalizedCardKey, String.Empty, normalizedTargetColumnKey, targetCardIndex, 0, False, False, HasKanbanSource, "Card key is required.")
            End If
            If normalizedTargetColumnKey.Length = 0 Then
                Return New MASKanbanBoardDropRuleSnapshot(normalizedCardKey, String.Empty, normalizedTargetColumnKey, targetCardIndex, 0, False, False, HasKanbanSource, "Target column key is required.")
            End If

            Dim location As Tuple(Of Integer, Integer) = FindCardLocation(normalizedCardKey)
            If location Is Nothing OrElse location.Item1 < 0 OrElse location.Item1 >= _columns.Count Then
                Return New MASKanbanBoardDropRuleSnapshot(normalizedCardKey, String.Empty, normalizedTargetColumnKey, targetCardIndex, 0, False, False, HasKanbanSource, "Card was not found in the board projection.")
            End If

            Dim sourceColumn As KanbanColumnState = _columns(location.Item1)
            If sourceColumn Is Nothing OrElse location.Item2 < 0 OrElse location.Item2 >= sourceColumn.Cards.Count Then
                Return New MASKanbanBoardDropRuleSnapshot(normalizedCardKey, String.Empty, normalizedTargetColumnKey, targetCardIndex, 0, False, False, HasKanbanSource, "Card location is not valid for the current board projection.")
            End If

            Dim targetColumn As KanbanColumnState = FindColumn(normalizedTargetColumnKey)
            If targetColumn Is Nothing Then
                Return New MASKanbanBoardDropRuleSnapshot(normalizedCardKey, sourceColumn.Key, normalizedTargetColumnKey, targetCardIndex, 0, False, False, HasKanbanSource, "Target column was not found in the board projection.")
            End If

            Dim resolvedIndex As Integer = ResolveInsertCardIndex(targetColumn, Math.Max(0, targetCardIndex))
            Dim targetColumnIndex As Integer = ResolveColumnIndex(targetColumn)
            Dim isNoOp As Boolean = targetColumnIndex = location.Item1 AndAlso resolvedIndex = location.Item2
            Return New MASKanbanBoardDropRuleSnapshot(normalizedCardKey,
                                                       sourceColumn.Key,
                                                       targetColumn.Key,
                                                       targetCardIndex,
                                                       resolvedIndex,
                                                       True,
                                                       isNoOp,
                                                       HasKanbanSource AndAlso Not isNoOp,
                                                       String.Empty)
        End Function

        Friend Function CanDropCard(cardKey As String,
                                    targetColumnKey As String,
                                    targetCardIndex As Integer) As Boolean
            Dim snapshot As MASKanbanBoardDropRuleSnapshot = CreateDropRuleSnapshot(cardKey, targetColumnKey, targetCardIndex)
            Return snapshot IsNot Nothing AndAlso snapshot.IsLegalTarget
        End Function

#End Region

    End Class

End Namespace
