Imports System.Windows.Forms
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.Repository
Imports DevExpress.XtraLayout
Imports DevExpress.XtraSplashScreen
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.ZooFlow
Imports DigitalData.Modules.Language
Imports DevExpress.XtraGrid
Imports DigitalData.Modules.EDMI.API
Imports DigitalData.GUIs.Common.Base
Imports DigitalData.Modules.Base

Public Class frmObjectPropertyDialog
    Implements IBaseForm

    Private ReadOnly Environment As Environment
    Private ReadOnly Client As Client
    Private ReadOnly ObjectId As Int64
    Private ReadOnly DatabaseIDB As MSSQLServer
    Private ReadOnly ControlManager As AttributeControls
    Private Property FormHelper As FormHelper

    Private ReadOnly Property LogConfig As LogConfig Implements IBaseForm.LogConfig
    Private ReadOnly Property Logger As Logger Implements IBaseForm.Logger

    Private ReadOnly Changes As New Dictionary(Of String, Object)

    Public Sub New(pLogConfig As LogConfig, pEnvironment As Environment, pClient As Client, pObjectId As Long)
        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
        LogConfig = pLogConfig
        Logger = pLogConfig.GetLogger()
        Environment = pEnvironment
        Client = pClient
        ObjectId = pObjectId
        DatabaseIDB = Environment.DatabaseIDB
        ControlManager = New AttributeControls(LogConfig, Environment, pClient)
        AddHandler ControlManager.EditValueChanged, AddressOf BaseEdit_EditValueChanged

    End Sub

    Private Async Sub frmObjectPropertyDialog_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim oHandle As IOverlaySplashScreenHandle = Nothing

        Try
            oHandle = SplashScreenManager.ShowOverlayForm(Me)

            If IsNothing(ObjectId) Then
                Throw New ApplicationException("No valid Object Id supplied!")
            End If

            Dim oEntityIds = Await GetBusinessEntitiesForObjectId(ObjectId)
            Dim oValueHistoryTable = Await GetValueHistoryForObjectId(ObjectId)
            Dim oObjectHistoryTable = Await GetObjectHistoryForObjectID(ObjectId)

            Dim oObjectProperties = Await GetPropertiesForObjectId(ObjectId)
            Dim oCombobox As RepositoryItemComboBox = DirectCast(cmbBusinessEntity.Edit, RepositoryItemComboBox)
            oCombobox.Items.AddRange(oEntityIds)

            ShowAttributeHistory(oValueHistoryTable)
            ShowObjectHistory(oObjectHistoryTable)
            ShowObjectProperties(oObjectProperties)

            cmbBusinessEntity.EditValue = oEntityIds.First()
        Catch ex As Exception
            FormHelper.ShowErrorMessage(ex, "frmObjectPropertyDialog_Load")
        Finally
            If oHandle IsNot Nothing Then
                SplashScreenManager.CloseOverlayForm(oHandle)
            End If
        End Try
    End Sub



    Private Async Function GetBusinessEntitiesForObjectId(ObjectId As Long) As Task(Of List(Of Long))
        Try
            Dim oSQL = $"SELECT BE_ID FROM TBIDB_OBJECT_BE WHERE IDB_OBJ_ID = {ObjectId}"
            Dim oResult = Await Client.GetDatatableFromIDBAsync(oSQL)

            If oResult.OK = False Then
                Throw New ApplicationException($"Business Entities could not be retrieved!")

            ElseIf oResult.Table.Rows.Count = 0 Then
                Throw New ApplicationException($"ObjectId {ObjectId} is not assigned to any business entity!")

            Else
                Dim oEntities As New List(Of Long)

                For Each oRow In oResult.Table.Rows
                    oEntities.Add(oRow.item("BE_ID"))
                Next

                Return oEntities
            End If
        Catch ex As Exception
            Logger.Error(ex)
            Return New List(Of Long)
        End Try
    End Function

    Private Async Function GetValueHistoryForObjectId(ObjectId As Long) As Task(Of DataTable)
        Dim oSQL As String = $"
            SELECT * FROM VWIDB_CHANGE_LOG 
            WHERE IDB_OBJ_ID = {ObjectId} AND 
            ORDER BY ChangeID DESC
        "
        Dim oResult = Await Client.GetDatatableFromIDBAsync(oSQL)

        Return oResult.Table
    End Function

    Private Async Function GetObjectHistoryForObjectId(ObjectId As Long) As Task(Of DataTable)
        Dim oSQL As String = $"
            SELECT * FROM VWIDB_DOC_STATES 
            WHERE IDB_OBJ_ID = {ObjectId} AND LANG_CODE = '{Environment.User.Language}'
            ORDER BY ADDED_WHEN DESC
        "
        Dim oResult = Await Client.GetDatatableFromIDBAsync(oSQL)

        Return oResult.Table
    End Function

    Private Async Function GetPropertiesForObjectId(ObjectId As Long) As Task(Of DataTable)
        Dim oSQL As String = $"SELECT * FROM TBIDB_OBJECT WHERE IDB_OBJ_ID = {ObjectId}"
        Dim oResult = Await Client.GetDatatableFromIDBAsync(oSQL)

        Return oResult.Table
    End Function

    Private Sub cmbBusinessEntity_EditValueChanged(sender As Object, e As EventArgs) Handles cmbBusinessEntity.EditValueChanged
        Load_Attributes()
    End Sub
    Private Async Sub Load_Attributes()
        Try
            Dim oEntityId As Long

            If Long.TryParse(cmbBusinessEntity.EditValue, oEntityId) = False Then
                _Logger.Warn("Could not Parse Entity from cmbBusinessEntity")
                Exit Sub
            End If

            Dim oAttributes = Await ControlManager.GetAttributesForBusinessEntity(oEntityId)

            If oAttributes.Count = 0 Then
                MsgBox($"Es konnten keine Attribute für das Objekt '{ObjectId}' geladen werden!", MsgBoxStyle.Critical, Text)
            End If

            ControlManager.LoadControlsForAttributes(oAttributes, AttributeLayout)
            Await ControlManager.LoadControlValuesForAttributes(ObjectId, AttributeLayout)
        Catch ex As Exception
            Logger.Error(ex)
        End Try
    End Sub

    Private Sub BaseEdit_EditValueChanged(sender As Object, e As EventArgs)
        Dim oControl As BaseEdit = sender
        Dim oAttribute As Attribute = oControl.Tag
        Dim oValue = oControl.EditValue
        Dim oKey = oAttribute.Title

        If Changes.ContainsKey(oKey) Then
            Changes.Item(oKey) = oValue
        Else
            Changes.Add(oAttribute.Title, oValue)

        End If
    End Sub

    Private Function ShowAttributeHistory(pDatatable As DataTable) As Boolean
        Try
            GridValueHistory.DataSource = pDatatable

            Return True
        Catch ex As Exception
            Logger.Error(ex)
            Return False
        End Try
    End Function

    Private Function ShowObjectHistory(pDatatable As DataTable) As Boolean
        Try
            GridObjectHistory.DataSource = pDatatable

            Return True
        Catch ex As Exception
            Logger.Error(ex)
            Return False
        End Try
    End Function

    Private Function ShowObjectProperties(pDatatable As DataTable) As Boolean
        Try
            Dim oRow As DataRow = pDatatable.Rows.Item(0)
            txtObjectId.Text = oRow.Item("IDB_OBJ_ID")
            txtCreatedWhen.Text = oRow.Item("ADDED_WHEN")
            txtCreatedWho.Text = oRow.Item("ADDED_WHO")
            txtChangedWhen.Text = Utils.NotNull(oRow.Item("CHANGED_WHEN"), String.Empty)
            txtChangedWho.Text = Utils.NotNull(oRow.Item("CHANGED_WHO"), String.Empty)

            lbLifecycleStart.Text = DirectCast(oRow.Item("ADDED_WHEN"), Date).ToShortDateString
            lbLifecycleEnd.Text = Date.MaxValue.ToShortDateString
            progressLifecycle.Position = 30

            Return True
        Catch ex As Exception
            Logger.Error(ex)
            Return False
        End Try
    End Function

    Private Async Sub btnSave_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles btnSave.ItemClick
        Try
            For Each oChange As KeyValuePair(Of String, Object) In Changes
                Logger.Info("Updating Attribute [{0}] with value [{1}]", oChange.Key, oChange.Value.ToString)

                Await Client.SetAttributeValueAsync(ObjectId, oChange.Key, oChange.Value, New Options.SetAttributeValueOptions With {
                    .Language = Environment.User.Language,
                    .Username = Environment.User.UserName
                })
            Next

            FormHelper.ShowInfoMessage($"{Changes.Count} Änderungen gespeichert!", "btnSave_ItemClick")
            Changes.Clear()
        Catch ex As Exception
            FormHelper.ShowErrorMessage(ex, "btnSave_ItemClick")
        End Try
    End Sub

    Private Sub TabFormControl1_Click(sender As Object, e As EventArgs) Handles TabFormControl1.Click

    End Sub
End Class