Imports System.Data.SqlClient
Imports System.Data.OracleClient
Imports System.IO
Imports WINDREAMLib
Imports DevExpress.Utils.CommonDialogs
Imports System.Runtime.InteropServices

Public Class ClassAllgemeineFunktionen
    Public Shared Function GUI_LANGUAGE_INFO(pTITLE As String)
        Try
            Dim oFilteredDatatable As DataTable = BASEDATA_DT_GUI_LANGUAGE_PHRASES.Clone()
            Dim oExpression = $"LANGUAGE ='{USER_LANGUAGE}' AND TITLE = '{pTITLE}'"
            BASEDATA_DT_GUI_LANGUAGE_PHRASES.Select(oExpression).CopyToDataTable(oFilteredDatatable, LoadOption.PreserveChanges)
            If oFilteredDatatable.Rows.Count = 1 Then
                If oFilteredDatatable.Rows(0).Item("CAPT_TYPE") = "MsgBox" Or oFilteredDatatable.Rows(0).Item("CAPT_TYPE") = "MsgboxResult" Then
                    Return oFilteredDatatable
                Else
                    If oFilteredDatatable.Rows(0).Item("STRING2") <> String.Empty Then
                        Return oFilteredDatatable
                    Else
                        Return oFilteredDatatable.Rows(0).Item("STRING1")
                    End If

                End If

            Else
                If oFilteredDatatable.Rows.Count = 0 Then 'KEIN EINTRAG FÜR SPRACHE
                    oExpression = $"LANGUAGE ='de-DE' AND TITLE = '{pTITLE}'"
                    BASEDATA_DT_GUI_LANGUAGE_PHRASES.Select(oExpression).CopyToDataTable(oFilteredDatatable, LoadOption.PreserveChanges)
                    Try
                        Return oFilteredDatatable.Rows(0).Item("STRING1")
                    Catch ex As Exception
                        Return $"ERR-LANG(NoTranslationFor [{oExpression}]"
                    End Try

                Else
                    Return oFilteredDatatable
                End If

            End If
        Catch ex As Exception
            LOGGER.Info($"Unexpected error in GUI_LANGUAGE_INFO FOR [{pTITLE}]...")
            LOGGER.Error(ex)
        End Try

    End Function
    Public Shared Function GUI_LANGUAGE_MSGBOX(pTITLE As String)
        Try
            Dim oFilteredDatatable As DataTable = BASEDATA_DT_GUI_LANGUAGE_PHRASES.Clone()
            Dim oExpression = $"LANGUAGE = '{USER_LANGUAGE}' AND TITLE = '{pTITLE}'"
            BASEDATA_DT_GUI_LANGUAGE_PHRASES.Select(oExpression).CopyToDataTable(oFilteredDatatable, LoadOption.PreserveChanges)
            If oFilteredDatatable.Rows.Count = 1 Then
                Return oFilteredDatatable.Rows(0)
            Else
                Return ""
            End If
        Catch ex As Exception
            LOGGER.Info($"Unexpected error in GUI_LANGUAGE_MSGBOX FOR [{pTITLE}]...")
            LOGGER.Error(ex)
        End Try

    End Function
    Public Shared Function LoginOut(LoginorOut As String) As Boolean
        Try
            If USER_EXISTS = False Then
                Return False
            End If
            Dim oSql As String
            If LoginorOut = "LOGIN" Then
                oSql = String.Format($"INSERT INTO TBDD_USER_MODULE_LOG_IN (USER_ID,CLIENT_ID,MODULE,VERSION_CLIENT,MACHINE_NAME,LANGUAGE_OVERRIDE) VALUES 
                    ({USER_ID},1,'{MODULE_PM}','{My.Application.Info.Version.ToString}','{Environment.MachineName}','')")
            Else
                If INACTIVITYRecognized = True Then
                    oSql = $"UPDATE TBDD_USER_LOGIN_OUT SET COMMENT = 'Inactivity Detected',LOGOUT = GETDATE() WHERE USER_ID = {USER_ID} AND MODULE = '{MODULE_PM}' AND LOGOUT IS NULL"
                    If DatabaseFallback.ExecuteNonQueryECM(oSql) = True Then

                    End If
                End If

                oSql = $"DELETE FROM TBDD_USER_MODULE_LOG_IN WHERE USER_ID = {USER_ID} AND MODULE = '{MODULE_PM}'"
            End If
            If DatabaseFallback.ExecuteNonQueryECM(oSql) = True Then
                LOGGER.Debug($"{LoginorOut} of User successfully!")
                Return True
            Else
                LOGGER.Info("User could not be logged in/out....")
                Return False
            End If
        Catch ex As Exception
            LOGGER.Error(ex)
            LOGGER.Info("Error in LoginOut: " & ex.Message)
            Return False
        End Try
    End Function

    Public Function ExecuteonMSSQL(ByVal sqlcommand As String, ConString As String)
        Try
            ' die nötigen Variablen definieren
            Dim Connection As SqlConnection

            Dim Command As SqlCommand = Nothing
            Dim DataAdapter As SqlDataAdapter = Nothing

            ' ConnectionString aufbauen (aus Settings auslesen)
            Connection = New SqlConnection(ConString)


            ' Verbindung zur Datenbank aufbauen
            Try
                Connection.Open()
            Catch ex As Exception
                LOGGER.Error(ex)
                ' DB-Connection schliessen
                Me.CloseMssqlDb(Connection)
                LOGGER.Debug("ExecuteonMSSQL.Connection definieren - Error: " & ex.Message, True)
                Return "ExecuteonMSSQL.Connection definieren - Error: " & ex.Message
            End Try


            ' SQL-Abfrage definieren
            Try
                Command = New SqlCommand(sqlcommand, Connection)
            Catch ex As Exception
                LOGGER.Error(ex)
                LOGGER.Debug("ExecuteonMSSQL.sqlcommand definieren - Error: " & ex.Message, True)
                ' DB-Connection schliessen
                Me.CloseMssqlDb(Connection)
                Return "ExecuteonMSSQL.sqlcommand definieren - Error: " & ex.Message
            End Try

            ' *** Ausführen des Command ***
            If Command IsNot Nothing Then

                Try
                    Command.ExecuteNonQuery()
                    ' DB-Connection schliessen
                    Me.CloseMssqlDb(Connection)
                    Return ""
                Catch ex As Exception
                    LOGGER.Error(ex)
                    'bei einem Fehler einen Eintrag in der Logdatei erzeugen
                    LOGGER.Info("ExecuteonMSSQL.Execute Command - Error: " & ex.Message, True)
                    LOGGER.Info("Command-Befehl: " & Command.CommandText, True)
                    ' DB-Connection schliessen
                    Me.CloseMssqlDb(Connection)
                    Return "ExecuteonMSSQL.Execute Command - Error: " & ex.Message

                End Try
            Else
                ' kann eintreten, wenn entweder die SQL-Anweisung falsch ist oder wenn die DataConnection nicht richtig aufgebaut werden konnte
                ' Eintrag in Logdatei machen
                LOGGER.Info("ExecuteonMSSQL.SQL-Command ist ungültig. Command-Objekt konnte nicht erstellt werden")
                Return "ExecuteonMSSQL.SQL-Command ist ungültig. Command-Objekt konnte nicht erstellt werden"
            End If
        Catch ex As Exception
            LOGGER.Error(ex)
            ' an dieser Stelle sollte jeder unvorhergesehene Fehler der Funktion abgefangen werden
            LOGGER.Info("ExecuteonMSSQL.Ein unbekannter Fehler in ExecuteonMSSQL - Error: " & ex.Message, True)
            Return "ExecuteonMSSQL.Ein unbekannter Fehler in ExecuteonMSSQL - Error: " & ex.Message
        End Try

    End Function
    Private Sub CloseMssqlDb(ByRef Connection As SqlConnection)
        ' wenn eine Datenbank-Connection aufgebaut ist
        If Connection IsNot Nothing Then
            ' diese schliessen
            Connection.Close()
            Connection = Nothing
        End If

    End Sub
    Public Function Move2Folder(ByVal vMove_File As String, ByVal vZiel_Pfad As String, Profile_ID As Integer, clsWD As ClassWindream_allgemein)
        Try

            Dim extension As String = IO.Path.GetExtension(vMove_File)
            Dim Filename As String = IO.Path.GetFileName(vMove_File)
            Dim path As String = IO.Path.GetDirectoryName(vMove_File)
            Dim _Ziel As String
            _Ziel = vZiel_Pfad & "\" & Filename
            Dim version As Integer = 1
            If vZiel_Pfad <> path Then
                Dim Stammname As String = IO.Path.GetFileNameWithoutExtension(vMove_File)
                Do While Check_File_exists(_Ziel, clsWD) = True
                    Dim neuername As String = Stammname & "~" & version & extension
                    _Ziel = neuername
                    version += 1
                Loop
                My.Computer.FileSystem.MoveFile(vMove_File, _Ziel)
                LOGGER.Info("Datei erfolgreich verschoben - Ziel: " & _Ziel)
            Else
                LOGGER.Info("Ziel und Quellpfad sind identisch!")
            End If

            Return ""
        Catch ex As Exception
            LOGGER.Error(ex)
            LOGGER.Info("Fehler bei Move2Folder", True)
            LOGGER.Info("Fehlermeldung")
            LOGGER.Info(ex.Message)
            Return ex.Message
        End Try
    End Function
    Public Function Check_File_exists(ByVal _file As String, clsWD As ClassWindream_allgemein)
        Try
            Return clsWD.CheckFileExists(_file)
        Catch ex As Exception
            LOGGER.Error(ex)
            LOGGER.Info("Fehler in Funktion file_exists - Fehler: ", ex.Message)
            Return False
        End Try
    End Function
    Public Function CheckValue_Exists(sqlbefehl As String, Replace_value As String, Check_value As String, Typ As String, connString As String, profilid As Integer)
        Try
            Dim sql As String
            Dim CONNTYPE As String
            If connString <> "" Then
                If connString.StartsWith("%MS") Then
                    CONNTYPE = "MS-SQL"
                    connString = connString.Replace("%MS", "")
                ElseIf connString.StartsWith("%OR") Then
                    CONNTYPE = "ORACLE"
                    connString = connString.Replace("%OR", "")
                End If

                Dim sqlscalar = sqlbefehl
                Select Case Typ
                    Case "INTEGER"
                        '@manValue
                        sqlscalar = sqlscalar.ToString.Replace(Replace_value, Check_value)
                    Case Else
                        sqlscalar = sqlscalar.ToString.Replace(Replace_value, "'" & Check_value & "'")
                End Select

                sql = sqlscalar
                Dim ergebnis As Integer
                If CONNTYPE = "ORACLE" Then
                    ergebnis = Execute_Scalar_Oracle(sql, connString, True)
                Else
                    ergebnis = Execute_Scalar_SQLServer(sql, connString, True)
                End If

                Select Case ergebnis
                    Case 1
                        Return True
                    Case Else
                        Return False
                End Select
            End If
        Catch ex As Exception
            LOGGER.Error(ex)
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Unexpected error checkValue_Exists:")
            LOGGER.Info(" - Unvorhergesehener Fehler bei checkValue_Exists - Fehler: " & vbNewLine & ex.Message)
            Return False
        End Try
    End Function

    Function Execute_Scalar_SQLServer(vsql_statement As String, vconnectionString As String, check As Boolean)
        Try
            Dim cnn As SqlConnection
            cnn = New SqlConnection(vconnectionString)
            Dim cmd As SqlCommand
            cnn.Open()
            cmd = New SqlCommand(vsql_statement, cnn)
            If check = True Then
                'ERgebnis muss immer 1 oder mehr ergeben
                Dim count As Int32 = Convert.ToInt32(cmd.ExecuteScalar())
                If count = 1 Then
                    cmd.Dispose()
                    cnn.Close()
                    Return 1
                Else
                    cmd.Dispose()
                    cnn.Close()
                    Return 2
                End If
            Else
                'Ergebnis 
                Dim ergebnis As String = cmd.ExecuteScalar()
                Return ergebnis
            End If

        Catch ex As Exception
            LOGGER.Error(ex)
            MsgBox("Unexpected error Execute_Scalar_SQLServer" & vbNewLine & "Automatic Index (j/n): " & check.ToString & vbNewLine & "ERROR:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Unexpected error Execute_Scalar_SQL sql:")
            LOGGER.Info(" - Unvorhergesehener Fehler bei Execute_Scalar_SQLServer" & vbNewLine & "Automatischer Index (j/n): " & check.ToString & vbNewLine & "Fehler: " & vbNewLine & ex.Message)
            LOGGER.Info(" - SQL: " & vsql_statement)
            LOGGER.Info(" - Connection: " & vconnectionString)
            Return 99
        End Try
    End Function
    Function Execute_Scalar_Oracle(vsql_statement As String, vconnectionString As String, check As Boolean)
        Try
            Dim cnn As System.Data.OleDb.OleDbConnection
            cnn = New System.Data.OleDb.OleDbConnection(vconnectionString)
            Dim cmd As System.Data.OleDb.OleDbCommand
            cnn.Open()
            cmd = New System.Data.OleDb.OleDbCommand(vsql_statement, cnn)

            If check = True Then
                'Ergebnis muss immer 1 oder mehr ergeben
                Dim count As Int32 = Convert.ToInt32(cmd.ExecuteScalar())
                If count = 1 Then
                    Return 1
                Else
                    Return 2
                End If
            Else
                'Ergebnis 
                Dim ergebnis As String = cmd.ExecuteScalar()
                Return ergebnis
            End If

            cmd.Dispose()
            cnn.Close()
        Catch ex As Exception
            LOGGER.Error(ex)
            MsgBox("Unexpected error Execute_Scalar_Oracle" & vbNewLine & "Automatic Index (y/n): " & check.ToString & vbNewLine & "Error:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Unexpected error Execute_Scalar_oracle sql:")
            LOGGER.Info(" - Unvorhergesehener Fehler bei Execute_Scalar_Oracle" & vbNewLine & "Automatischer Index (j/n): " & check.ToString & vbNewLine & "Fehler: " & vbNewLine & ex.Message)
            LOGGER.Info(" - SQL: " & vsql_statement)
            LOGGER.Info(" - Connection: " & vconnectionString)
            Return 99
        End Try
    End Function
    Public Shared Sub Save_Logfiles()
        Try
            Dim saveFileDialog1 As New SaveFileDialog()
            If File.Exists(LOGCONFIG.LogFile) Then
                saveFileDialog1.Filter = "log file|*.log"
                saveFileDialog1.FileName = Path.GetFileName(LOGCONFIG.LogFile)
                If saveFileDialog1.ShowDialog() = DialogResult.OK Then
                    If File.Exists(saveFileDialog1.FileName) Then
                        File.Delete(saveFileDialog1.FileName)
                    End If
                    File.Copy(LOGCONFIG.LogFile, saveFileDialog1.FileName)
                End If
            End If

            If DEBUG = True Then
                Dim oDebuglogFilename_only = Path.GetFileNameWithoutExtension(LOGCONFIG.LogFile) + "-Debug.log"
                Dim oDebuglogFilename = LOGCONFIG.LogDirectory + "\" + oDebuglogFilename_only
                If File.Exists(oDebuglogFilename) Then
                    saveFileDialog1.Filter = "log file|*.log"
                    saveFileDialog1.FileName = oDebuglogFilename_only
                    If saveFileDialog1.ShowDialog() = DialogResult.OK Then
                        If File.Exists(saveFileDialog1.FileName) Then
                            File.Delete(saveFileDialog1.FileName)
                        End If
                        File.Copy(oDebuglogFilename, saveFileDialog1.FileName)
                    End If
                End If
            End If
            Dim oErrorlogFilename_only = Path.GetFileNameWithoutExtension(LOGCONFIG.LogFile) + "-Error.log"
            Dim oErrorlogFilename = LOGCONFIG.LogDirectory + "\" + oErrorlogFilename_only
            If File.Exists(oErrorlogFilename) Then
                saveFileDialog1.Filter = "log file|*.log"
                saveFileDialog1.FileName = oErrorlogFilename_only
                If saveFileDialog1.ShowDialog() = DialogResult.OK Then
                    If File.Exists(saveFileDialog1.FileName) Then
                        File.Delete(saveFileDialog1.FileName)
                    End If
                    File.Copy(oErrorlogFilename, saveFileDialog1.FileName)
                End If
            End If
            Dim oMSG = ClassAllgemeineFunktionen.GUI_LANGUAGE_INFO("ExportLogFiles_Result")
            MsgBox(oMSG, MsgBoxStyle.Information, ADDITIONAL_TITLE)
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Error saving log file")
        End Try
    End Sub
    Public Shared Function NotNull(Of T)(value As Object, defaultValue As T) As T
        If value Is Nothing OrElse Convert.IsDBNull(value) Then
            Return defaultValue
        End If

        ' Versuche den Wert in den gewünschten Typ zu konvertieren
        Try
            Return CType(value, T)
        Catch ex As InvalidCastException
            ' Falls die Konvertierung fehlschlägt, gib den Default zurück
            Return defaultValue
        End Try
    End Function
    Public Shared Function NotNullNullable(Of T As Structure)(value As Object, defaultValue As Nullable(Of T)) As Nullable(Of T)
        If value Is Nothing OrElse Convert.IsDBNull(value) Then
            Return defaultValue
        End If
        Try
            ' Direkte Casts sind robust, wandeln aber DBNull nicht – das ist bereits oben abgefangen.
            Return DirectCast(value, Nullable(Of T))
        Catch
            Try
                ' Fallback: in T casten und zu Nullable machen
                Return New Nullable(Of T)(DirectCast(value, T))
            Catch
                Return defaultValue
            End Try
        End Try
    End Function
    Public Shared Function NotNullString(value As Object, defaultValue As Object) As String
        If value Is Nothing OrElse Convert.IsDBNull(value) Then Return defaultValue
        Return CStr(value)
    End Function

    Public Shared Function NotNullDate(value As Object, defaultValue As DateTime) As DateTime?
        If value Is Nothing OrElse Convert.IsDBNull(value) Then Return defaultValue
        Return DirectCast(value, DateTime)
    End Function
    Public Shared Function NewShortGuid() As String
        ' Neue GUID erzeugen
        Dim g As Guid = Guid.NewGuid()

        ' In Base64 umwandeln
        Dim b64 As String = Convert.ToBase64String(g.ToByteArray())

        ' Unerwünschte Zeichen ersetzen/entfernen
        b64 = b64.Replace("=", "").Replace("+", "-").Replace("/", "_")

        ' Ergebnis zurückgeben
        Return b64
    End Function
End Class
