Imports System.Text.RegularExpressions
Imports DevExpress.XtraEditors

Public Class frmExpression_Designer
    Private _availableColumns As DataTable
    Private _currentExpression As String = ""

    Public Property Expression As String
        Get
            Return _currentExpression
        End Get
        Set(value As String)
            _currentExpression = value
            txtExpression.Text = value
        End Set
    End Property

    Public Sub New(pAvailableColumns As DataTable, pCurrentExpression As String)
        InitializeComponent()

        _availableColumns = pAvailableColumns
        _currentExpression = pCurrentExpression
    End Sub
    Private Sub ConfigureOperatorButtons()
        Dim yPos As Integer = 10

        ' Arithmetische Operatoren
        AddOperatorButton(btnAdd, "+", 10, yPos, "Addition")
        AddOperatorButton(btnSubtract, "-", 70, yPos, "Subtraktion")
        AddOperatorButton(btnMultiply, "*", 130, yPos, "Multiplikation")
        AddOperatorButton(btnDivide, "/", 190, yPos, "Division")

        yPos += 40

        ' Vergleichsoperatoren
        AddOperatorButton(btnEquals, "=", 10, yPos, "Gleich")
        AddOperatorButton(btnNotEquals, "<>", 70, yPos, "Ungleich")
        AddOperatorButton(btnGreater, ">", 130, yPos, "Größer")
        AddOperatorButton(btnLess, "<", 190, yPos, "Kleiner")

        yPos += 40

        ' Logische Operatoren
        AddOperatorButton(btnAnd, "AND", 10, yPos, "Und")
        AddOperatorButton(btnOr, "OR", 70, yPos, "Oder")
        AddOperatorButton(btnNot, "NOT", 130, yPos, "Nicht")

        yPos += 40

        ' Klammern
        AddOperatorButton(btnOpenBracket, "(", 10, yPos, "Öffnende Klammer")
        AddOperatorButton(btnCloseBracket, ")", 70, yPos, "Schließende Klammer")
    End Sub

    Private Sub AddOperatorButton(btn As SimpleButton, text As String, x As Integer, y As Integer, tooltip As String)
        btn.Text = text
        btn.Location = New Point(x, y)
        btn.Size = New Size(50, 30)
        btn.ToolTip = tooltip
        Me.panelOperators.Controls.Add(btn)
    End Sub
    Private Sub frmExpressionDesigner_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' ZUERST Operatoren-Buttons erstellen
        ConfigureOperatorButtons()

        ' Spalten laden
        LoadAvailableColumns()

        ' Funktionen laden
        LoadFunctions()

        ' Operatoren laden
        LoadOperators()

        ' Aktuelle Expression anzeigen
        txtExpression.Text = _currentExpression

        ' Syntax-Highlighting aktivieren (optional)
        UpdateSyntaxHighlighting()
        ' Event-Handler für Text-Änderungen hinzufügen
        AddHandler txtExpression.EditValueChanged, AddressOf txtExpression_EditValueChanged
    End Sub

    Private Sub txtExpression_EditValueChanged(sender As Object, e As EventArgs)
        ' Validierungsmeldung zurücksetzen
        lblValidation.Text = String.Empty
        lblValidation.ForeColor = Color.Black

        ' Syntax-Highlighting aktualisieren
        UpdateSyntaxHighlighting()

        ' Aktuellen Wert speichern
        _currentExpression = txtExpression.Text
    End Sub
    Private Sub LoadAvailableColumns()
        lstColumns.Items.Clear()

        For Each row As DataRow In _availableColumns.Rows
            Dim columnName As String = row.Item("SPALTENNAME").ToString()
            Dim columnType As String = row.Item("TYPE_COLUMN").ToString()
            Dim displayText As String = $"{columnName} ({columnType})"

            lstColumns.Items.Add(New ListBoxItem With {
                .DisplayText = displayText,
                .ColumnName = columnName,
                .DataType = columnType
            })
        Next
    End Sub

    Private Sub LoadFunctions()
        lstFunctions.Items.Clear()

        ' Mathematische Funktionen
        lstFunctions.Items.Add(New FunctionItem("IIF", "IIF([Bedingung], Wahr, Falsch)", "Bedingte Verzweigung"))
        lstFunctions.Items.Add(New FunctionItem("IsNull", "IsNull([Spalte], Ersatzwert)", "Null-Behandlung"))
        lstFunctions.Items.Add(New FunctionItem("Convert", "Convert([Spalte], 'System.Double')", "Typkonvertierung"))

        ' String-Funktionen
        lstFunctions.Items.Add(New FunctionItem("Len", "Len([Text])", "Länge eines Textes"))
        lstFunctions.Items.Add(New FunctionItem("Trim", "Trim([Text])", "Leerzeichen entfernen"))
        lstFunctions.Items.Add(New FunctionItem("Substring", "Substring([Text], Start, Länge)", "Teilstring extrahieren"))
    End Sub

    Private Sub LoadOperators()
        ' Arithmetische Operatoren
        btnAdd.Tag = " + "
        btnSubtract.Tag = " - "
        btnMultiply.Tag = " * "
        btnDivide.Tag = " / "

        ' Vergleichsoperatoren
        btnEquals.Tag = " = "
        btnNotEquals.Tag = " <> "
        btnGreater.Tag = " > "
        btnLess.Tag = " < "

        ' Logische Operatoren
        btnAnd.Tag = " AND "
        btnOr.Tag = " OR "
        btnNot.Tag = " NOT "

        ' Klammern
        btnOpenBracket.Tag = "("
        btnCloseBracket.Tag = ")"
    End Sub

    Private Sub lstColumns_DoubleClick(sender As Object, e As EventArgs) Handles lstColumns.DoubleClick
        If lstColumns.SelectedItem IsNot Nothing Then
            Dim item As ListBoxItem = CType(lstColumns.SelectedItem, ListBoxItem)
            InsertText($"[{item.ColumnName}]")
        End If
    End Sub

    Private Sub lstFunctions_DoubleClick(sender As Object, e As EventArgs) Handles lstFunctions.DoubleClick
        If lstFunctions.SelectedItem IsNot Nothing Then
            Dim item As FunctionItem = CType(lstFunctions.SelectedItem, FunctionItem)
            InsertText(item.Template)
        End If
    End Sub

    Private Sub Operator_Click(sender As Object, e As EventArgs) Handles btnAdd.Click, btnSubtract.Click, btnMultiply.Click, btnDivide.Click,
                                                                         btnEquals.Click, btnNotEquals.Click, btnGreater.Click, btnLess.Click,
                                                                         btnAnd.Click, btnOr.Click, btnNot.Click,
                                                                         btnOpenBracket.Click, btnCloseBracket.Click
        Dim btn As SimpleButton = CType(sender, SimpleButton)
        InsertText(btn.Tag.ToString())
    End Sub


    Private Sub InsertText(text As String)
        Dim selectionStart As Integer = txtExpression.SelectionStart

        txtExpression.Text = txtExpression.Text.Insert(selectionStart, text)
        txtExpression.SelectionStart = selectionStart + text.Length
        txtExpression.Focus()

        _currentExpression = txtExpression.Text
        ' UpdateSyntaxHighlighting() wird jetzt im Event-Handler aufgerufen
    End Sub

    Private Sub btnValidate_Click(sender As Object, e As EventArgs) Handles btnValidate.Click
        ValidateExpression()
    End Sub

    Private Sub ValidateExpression()
        Try
            ' Testdatatable erstellen
            Dim testTable As New DataTable()

            ' Spalten hinzufügen
            For Each row As DataRow In _availableColumns.Rows
                Dim colName As String = row.Item("SPALTENNAME").ToString()
                Dim colType As String = row.Item("TYPE_COLUMN").ToString()

                Dim dataType As Type = GetType(String)
                Select Case colType
                    Case "INTEGER"
                        dataType = GetType(Integer)
                    Case "DOUBLE", "CURRENCY"
                        dataType = GetType(Double)
                    Case "BOOLEAN"
                        dataType = GetType(Boolean)
                End Select

                testTable.Columns.Add(colName, dataType)
            Next

            ' Test-Spalte mit Expression erstellen
            Dim testColumn As New DataColumn("TEST_EXPRESSION") With {
                .Expression = txtExpression.Text
            }
            testTable.Columns.Add(testColumn)

            ' Erfolg!
            lblValidation.Text = "✓ Expression ist gültig!"
            lblValidation.ForeColor = Color.Green

        Catch ex As Exception
            lblValidation.Text = $"⚠️ Fehler: {ex.Message}"
            lblValidation.ForeColor = Color.Red
        End Try
    End Sub

    Private Sub UpdateSyntaxHighlighting()
        ' Optional: Einfaches Syntax-Highlighting
        ' Spalten-Referenzen markieren
        Dim pattern As String = "\[([^\]]+)\]"
        Dim matches = Regex.Matches(txtExpression.Text, pattern)

        ' Anzahl der referenzierten Spalten anzeigen
        lblColumnCount.Text = $"Referenzierte Spalten: {matches.Count}"
    End Sub

    Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
        ' Finale Validierung
        ValidateExpression()

        If lblValidation.ForeColor = Color.Green Then
            _currentExpression = txtExpression.Text
            Me.DialogResult = DialogResult.OK
            Me.Close()
        Else
            MessageBox.Show("Bitte korrigieren Sie die Expression zuerst!", "Validierung fehlgeschlagen", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End If
    End Sub

    Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
        Me.DialogResult = DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
        txtExpression.EditValue = String.Empty
        _currentExpression = ""
    End Sub

    ' Hilfeklassen
    Private Class ListBoxItem
        Public Property DisplayText As String
        Public Property ColumnName As String
        Public Property DataType As String

        Public Overrides Function ToString() As String
            Return DisplayText
        End Function
    End Class

    Private Class FunctionItem
        Public Property Name As String
        Public Property Template As String
        Public Property Description As String

        Public Sub New(name As String, template As String, description As String)
            Me.Name = name
            Me.Template = template
            Me.Description = description
        End Sub

        Public Overrides Function ToString() As String
            Return $"{Name} - {Description}"
        End Function
    End Class
End Class