Imports System.IO
Imports DigitalData.Modules.Logging
''' <summary>
''' Zentrale Klasse für Dokumentenpfad-Verwaltung mit optionalem Laufwerks-Mapping und Temp-Kopie
''' </summary>
Public Class DocumentPathHandler

    Private ReadOnly _Logger As Logger
    Private ReadOnly _LogConfig As LogConfig
    Private _mappedDrive As String = ""
    Private _clsmapDrive As Map_Drive

    Public Sub New(LogConfig As LogConfig)
        _LogConfig = LogConfig
        _Logger = LogConfig.GetLogger()
        _clsmapDrive = New Map_Drive(LogConfig)
    End Sub

    Private Function EnsureTempFolder(ByRef tempFolder As String, ByRef errorMessage As String) As Boolean
        Try
            _Logger.Debug($"📂 Überprüfe Temp-Ordner: [{tempFolder}]")
            If String.IsNullOrWhiteSpace(tempFolder) Then
                _Logger.Debug("⚠️ Temp-Ordner nicht konfiguriert, verwende TEMP_DOCUMENT_FOLDER aus AppSettings")
                tempFolder = TEMP_DOCUMENT_FOLDER
            End If

            ' Fallback, falls global nichts konfiguriert ist
            If String.IsNullOrWhiteSpace(tempFolder) Then
                tempFolder = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                "Digital Data",
                "taskFLOW",
                "DocumentViewer",
                "Temp")
                _Logger.Info($"⚠️ TEMP_DOCUMENT_FOLDER war leer - verwende Fallback: [{tempFolder}]")
                TEMP_DOCUMENT_FOLDER = tempFolder
            End If

            If Not Directory.Exists(tempFolder) Then
                Directory.CreateDirectory(tempFolder)
                _Logger.Info($"📁 Temp-Ordner erstellt: [{tempFolder}]")
            End If

            If Not Directory.Exists(tempFolder) Then
                errorMessage = $"Temp-Ordner konnte nicht erstellt werden: [{tempFolder}]"
                Return False
            End If

            Return True

        Catch ex As Exception
            errorMessage = $"Fehler bei Temp-Ordner-Initialisierung: {ex.Message}"
            _Logger.Error($"❌ {errorMessage}")
            _Logger.Error(ex)
            Return False
        End Try
    End Function
    Public Sub CleanupTempFolder()
        Try
            If String.IsNullOrEmpty(TEMP_DOCUMENT_FOLDER) Then
                _Logger.Debug("TEMP_DOCUMENT_FOLDER ist nicht gesetzt → Kein Cleanup erforderlich")
                Return
            End If

            If Not System.IO.Directory.Exists(TEMP_DOCUMENT_FOLDER) Then
                _Logger.Debug($"Temp-Ordner [{TEMP_DOCUMENT_FOLDER}] existiert nicht → Kein Cleanup erforderlich")
                Return
            End If

            ' Alle Dateien im Ordner ermitteln
            Dim files As String() = System.IO.Directory.GetFiles(TEMP_DOCUMENT_FOLDER)

            If files.Length = 0 Then
                _Logger.Debug($"Temp-Ordner [{TEMP_DOCUMENT_FOLDER}] ist bereits leer")
                Return
            End If

            ' Alle Dateien löschen
            Dim deletedCount As Integer = 0
            Dim errorCount As Integer = 0

            For Each filePath As String In files
                Try
                    System.IO.File.Delete(filePath)
                    deletedCount += 1
                    _Logger.Debug($"Datei gelöscht: [{System.IO.Path.GetFileName(filePath)}]")
                Catch fileEx As Exception
                    errorCount += 1
                    _Logger.Warn($"⚠️ Datei konnte nicht gelöscht werden: [{System.IO.Path.GetFileName(filePath)}] - {fileEx.Message}")
                End Try
            Next

            If errorCount = 0 Then
                _Logger.Debug($"✓ Temp-Ordner bereinigt: {deletedCount} Datei(en) gelöscht")
            Else
                _Logger.Warn($"⚠️ Temp-Ordner teilweise bereinigt: {deletedCount} gelöscht, {errorCount} Fehler")
            End If

        Catch ex As Exception
            _Logger.Error($"❌ Fehler beim Bereinigen des Temp-Ordners: {ex.Message}")
            _Logger.Error(ex)
        End Try
    End Sub
    ''' <summary>
    ''' Verarbeitet einen Dokumentenpfad: Optional Mapping, dann Temp-Kopie
    ''' </summary>
    ''' <param name="sourcePath">Quell-Pfad der Datei (UNC oder lokal)</param>
    ''' <param name="options">Optionen für die Verarbeitung</param>
    ''' <returns>DocumentPathResult mit finalem Pfad und Mapping-Info</returns>
    Public Function ProcessDocumentPath(sourcePath As String, options As DocumentPathOptions) As DocumentPathResult
        Dim result As New DocumentPathResult With {
            .SourcePath = sourcePath,
            .FinalPath = sourcePath,
            .Success = False,
            .WasMapped = False,
            .WasCopiedToTemp = False
        }

        Try
            ' Validierung
            If String.IsNullOrEmpty(sourcePath) Then
                result.ErrorMessage = "Quell-Pfad ist leer"
                _Logger.Error("❌ ProcessDocumentPath: Quell-Pfad ist leer")
                Return result
            End If

            Dim workingPath As String = sourcePath

            ' ========== SCHRITT 1: OPTIONALES LAUFWERKS-MAPPING ==========
            If options.EnableMapping AndAlso Not String.IsNullOrEmpty(options.WMSuffix) Then
                Dim mappingResult = TryMapNetworkDrive(sourcePath, options)
                If mappingResult.Success Then
                    workingPath = mappingResult.MappedPath
                    _mappedDrive = mappingResult.DriveLetter
                    result.WasMapped = True
                    result.MappedDrive = _mappedDrive
                    _Logger.Info($"✓ Laufwerk gemappt: {_mappedDrive}")
                Else
                    _Logger.Warn("⚠️ Laufwerks-Mapping fehlgeschlagen - verwende Original-UNC-Pfad")
                    workingPath = sourcePath
                End If
            End If

            ' ========== SCHRITT 2: PRÜFEN OB DATEI EXISTIERT ==========
            If Not File.Exists(workingPath) Then
                result.ErrorMessage = $"Datei nicht gefunden: [{workingPath}]"
                _Logger.Error($"❌ {result.ErrorMessage}")

                ' Cleanup bei Fehler
                If result.WasMapped Then
                    UnmapDrive()
                End If

                Return result
            End If

            ' ========== SCHRITT 3: OPTIONALE TEMP-KOPIE ==========
            If options.CopyToTemp Then
                _Logger.Debug($"📂 Starte Temp-Kopie für: [{workingPath}]")
                Dim tempResult = CopyToTempFolder(workingPath, options.TempFolder)
                If tempResult.Success Then
                    result.FinalPath = tempResult.TempPath
                    result.WasCopiedToTemp = True
                    result.TempPath = tempResult.TempPath
                    _Logger.Info($"✓ Datei in Temp kopiert: [{Path.GetFileName(tempResult.TempPath)}]")

                    ' Laufwerk unmappen nach erfolgreicher Kopie
                    If result.WasMapped AndAlso options.UnmapAfterCopy Then
                        UnmapDrive()
                        result.WasMapped = False
                    End If
                Else
                    _Logger.Warn($"⚠️ Temp-Kopie fehlgeschlagen: {tempResult.ErrorMessage}")

                    ' WICHTIG: Nicht den gemappten Pfad behalten, wenn danach ungemappt wird.
                    ' Fallback immer auf stabilen Originalpfad (UNC).
                    result.FinalPath = sourcePath
                    result.WasCopiedToTemp = False
                    result.TempPath = String.Empty

                    If result.WasMapped Then
                        UnmapDrive()
                        result.WasMapped = False
                    End If
                End If
            Else
                result.FinalPath = workingPath
                _Logger.Debug($"📄 Verwende Pfad ohne Temp-Kopie: [{workingPath}]")
            End If

            result.Success = True
            Return result

        Catch ex As Exception
            result.ErrorMessage = $"Unerwarteter Fehler: {ex.Message}"
            _Logger.Error($"❌ ProcessDocumentPath: {ex.Message}")
            _Logger.Error(ex)

            ' Cleanup bei Exception
            If result.WasMapped Then
                UnmapDrive()
            End If

            Return result
        End Try
    End Function

    ''' <summary>
    ''' Versucht ein Netzlaufwerk zu mappen
    ''' </summary>
    Private Function TryMapNetworkDrive(sourcePath As String, options As DocumentPathOptions) As MappingResult
        Dim result As New MappingResult With {.Success = False}

        Try
            ' Prüfen ob Pfad mit WMSUFFIX beginnt
            If Not sourcePath.StartsWith(options.WMSuffix, StringComparison.OrdinalIgnoreCase) Then
                _Logger.Debug($"📄 Pfad beginnt nicht mit WMSUFFIX - kein Mapping erforderlich")
                Return result
            End If

            _Logger.Debug($"📂 WMSUFFIX erkannt - starte Laufwerks-Mapping")

            ' Laufwerk mappen
            Dim mappedDrive As String = ""

            If Not String.IsNullOrEmpty(options.SpecificDrive) AndAlso options.SpecificDrive.Length = 1 Then
                ' Spezifisches Laufwerk
                If _clsmapDrive.MapSpecificDrive(options.SpecificDrive, options.DriveBlacklist, options.WMSuffix) Then
                    mappedDrive = options.SpecificDrive & ":"
                End If
            Else
                ' Automatisches Mapping
                mappedDrive = _clsmapDrive.MapDriveAutomatic(options.DriveBlacklist, options.WMSuffix)
            End If

            If String.IsNullOrEmpty(mappedDrive) Then
                _Logger.Warn("⚠️ Kein Laufwerk gemappt")
                Return result
            End If

            ' Pfad umschreiben
            Dim relativePath As String = sourcePath.Substring(options.WMSuffix.Length)
            If relativePath.StartsWith("\") Then
                relativePath = relativePath.Substring(1)
            End If

            Dim mappedPath As String = mappedDrive.TrimEnd(":"c, "\"c) & ":\" & relativePath

            _Logger.Debug($"📄 Original: [{sourcePath}]")
            _Logger.Debug($"📄 Gemappt:  [{mappedPath}]")

            result.Success = True
            result.DriveLetter = mappedDrive
            result.MappedPath = mappedPath
            Return result

        Catch ex As Exception
            _Logger.Error($"Fehler beim Mapping: {ex.Message}")
            _Logger.Error(ex)
            Return result
        End Try
    End Function

    Private Function CopyToTempFolder(sourcePath As String, tempFolder As String) As TempCopyResult
        Dim result As New TempCopyResult With {.Success = False}

        Try
            Dim configuredTempFolder As String = tempFolder
            Dim globalTempFolder As String = TEMP_DOCUMENT_FOLDER

            ' Temp-Ordner validieren/initialisieren (kann tempFolder per ByRef setzen)
            If Not EnsureTempFolder(tempFolder, result.ErrorMessage) Then
                _Logger.Warn($"⚠️ {result.ErrorMessage}")
                _Logger.Warn($"[TempCopy] InputTemp=[{If(String.IsNullOrWhiteSpace(configuredTempFolder), "<leer>", configuredTempFolder)}], GlobalTemp=[{If(String.IsNullOrWhiteSpace(globalTempFolder), "<leer>", globalTempFolder)}]")
                Return result
            End If

            ' NEU: Effektiven Zielordner immer transparent loggen
            _Logger.Info($"[TempCopy] Effektiver Temp-Ordner: [{tempFolder}]")
            _Logger.Debug($"[TempCopy] InputTemp=[{If(String.IsNullOrWhiteSpace(configuredTempFolder), "<leer>", configuredTempFolder)}], GlobalTemp=[{If(String.IsNullOrWhiteSpace(globalTempFolder), "<leer>", globalTempFolder)}]")

            ' Eindeutigen Dateinamen generieren
            Dim originalFileName As String = Path.GetFileName(sourcePath)
            Dim fileNameWithoutExt As String = Path.GetFileNameWithoutExtension(originalFileName)
            Dim extension As String = Path.GetExtension(originalFileName)
            Dim timestamp As String = DateTime.Now.ToString("yyyyMMdd_HHmmss_fff")
            Dim uniqueFileName As String = $"{fileNameWithoutExt}_{timestamp}{extension}"
            Dim targetPath As String = Path.Combine(tempFolder, uniqueFileName)

            _Logger.Debug($"📄 Kopiere nach Temp:")
            _Logger.Debug($"   Von:  [{sourcePath}]")
            _Logger.Debug($"   Nach: [{targetPath}]")

            File.Copy(sourcePath, targetPath, overwrite:=True)

            result.Success = True
            result.TempPath = targetPath
            result.TempFileName = uniqueFileName
            Return result

        Catch ex As Exception
            result.ErrorMessage = $"Fehler beim Kopieren: {ex.Message}"
            _Logger.Error($"❌ {result.ErrorMessage}")
            _Logger.Error(ex)
            Return result
        End Try
    End Function

    ''' <summary>
    ''' Trennt das gemappte Laufwerk
    ''' </summary>
    Public Sub UnmapDrive()
        If Not String.IsNullOrEmpty(_mappedDrive) Then
            Try
                If _clsmapDrive.DisconnectNetworkDrive(_mappedDrive, force:=True) Then
                    _Logger.Info($"🔌 Laufwerk {_mappedDrive} getrennt")
                Else
                    _Logger.Warn($"⚠️ Warnung beim Trennen von {_mappedDrive}")
                End If
            Catch ex As Exception
                _Logger.Debug($"Fehler beim Trennen von {_mappedDrive}: {ex.Message}")
            Finally
                _mappedDrive = ""
            End Try
        End If
    End Sub

    ''' <summary>
    ''' Cleanup-Methode (z.B. beim Schließen des Forms)
    ''' </summary>
    Public Sub Cleanup()
        UnmapDrive()
    End Sub

#Region "Nested Classes für Optionen und Ergebnisse"

    ''' <summary>
    ''' Optionen für die Dokumentenpfad-Verarbeitung
    ''' </summary>
    Public Class DocumentPathOptions
        ''' <summary>Soll Laufwerks-Mapping versucht werden?</summary>
        Public Property EnableMapping As Boolean = False

        ''' <summary>WMSUFFIX für Mapping-Erkennung (z.B. "\\windream\objects")</summary>
        Public Property WMSuffix As String = ""

        ''' <summary>Spezifischer Laufwerksbuchstabe (z.B. "V") oder leer für automatisch</summary>
        Public Property SpecificDrive As String = ""

        ''' <summary>Blacklist für Laufwerksbuchstaben (z.B. "Y,M,V")</summary>
        Public Property DriveBlacklist As String = ""

        ''' <summary>Soll Datei in Temp kopiert werden?</summary>
        Public Property CopyToTemp As Boolean = False

        ''' <summary>Temp-Ordner-Pfad</summary>
        Public Property TempFolder As String = ""

        ''' <summary>Laufwerk nach erfolgreicher Temp-Kopie unmappen?</summary>
        Public Property UnmapAfterCopy As Boolean = True
    End Class

    ''' <summary>
    ''' Ergebnis der Dokumentenpfad-Verarbeitung
    ''' </summary>
    Public Class DocumentPathResult
        Public Property Success As Boolean
        Public Property SourcePath As String
        Public Property FinalPath As String
        Public Property ErrorMessage As String
        Public Property WasMapped As Boolean
        Public Property MappedDrive As String
        Public Property WasCopiedToTemp As Boolean
        Public Property TempPath As String
    End Class

    Private Class MappingResult
        Public Property Success As Boolean
        Public Property DriveLetter As String
        Public Property MappedPath As String
    End Class

    Private Class TempCopyResult
        Public Property Success As Boolean
        Public Property TempPath As String
        Public Property TempFileName As String
        Public Property ErrorMessage As String
    End Class

#End Region

End Class
