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

Public Class frmObjectPropertyDialog
    Private _LogConfig As LogConfig
    Private _Logger As Logger
    Private _Environment As Environment
    Private ReadOnly _Client As Client
    Private _ObjectId As Int64
    Private _Db As MSSQLServer
    Private _Controls As PropertyControls

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

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
        _LogConfig = LogConfig
        _Logger = LogConfig.GetLogger()
        _Environment = Environment
        _Client = Client
        _ObjectId = ObjectId
        _Db = _Environment.DatabaseIDB
        _Controls = New PropertyControls(_LogConfig, _Db)
    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 oHistoryDataTable = Await GetValueHistoryForObjectId(_ObjectId)
            Dim oObjectProperties = Await GetPropertiesForObjectId(_ObjectId)
            Dim oCombobox As RepositoryItemComboBox = DirectCast(cmbBusinessEntity.Edit, RepositoryItemComboBox)
            oCombobox.Items.AddRange(oEntityIds)

            ShowAttributeHistory(oHistoryDataTable)
            ShowObjectProperties(oObjectProperties)

            'If oEntityIds.Count = 1 Then
            '    cmbBusinessEntity.EditValue = oEntityIds.First()
            'End If
            cmbBusinessEntity.EditValue = oEntityIds.First()
        Catch ex As ApplicationException
            _Logger.Error(ex)
            MessageBox.Show(ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error)
        Catch ex As Exception
            _Logger.Error(ex)
            MessageBox.Show("Unhandled exception occurred. Please check the log." & vbNewLine & ex.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        Finally
            If oHandle IsNot Nothing
                SplashScreenManager.CloseOverlayForm(oHandle)
            End If
        End Try
    End Sub

    Private Async Function GetAttributesForBusinessEntity(EntityId As Long) As Task(Of List(Of Attribute))
        Try
            Dim oSQL = $"SELECT * FROM VWIDB_BE_ATTRIBUTE WHERE BE_ID = {EntityId}"
            Dim oResult = Await _Client.GetDatatableFromIDBAsync(oSQL)

            If oResult.OK = False Then
                Throw New ApplicationException($"Attributes for Business Entity {EntityId} could not be retrieved!")

            ElseIf oResult.Table.Rows.Count = 0 Then
                Throw New ApplicationException($"BusinessEntity {EntityId} does not have any attributes!")

            Else
                Dim oAttributes As New List(Of Attribute)

                For Each oRow As DataRow In oResult.Table.Rows
                    oAttributes.Add(New Attribute() With {
                        .ID = oRow.Item("ATTR_ID"),
                        .Title = oRow.Item("ATTR_TITLE"),
                        .TypeID = oRow.Item("TYPE_ID"),
                        .TypeName = oRow.Item("TYPE_NAME")
                    })
                Next

                Return oAttributes
            End If
        Catch ex As Exception
            _Logger.Error(ex)
            Return New List(Of Attribute)
        End Try
    End Function

    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} ORDER BY ChangeID 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 Async Function GetAttributeValue(AttributeName As String, ObjectId As Long, Optional LanguageCode As String = "de-DE", Optional IsForeign As Boolean = False) As Task(Of Object)
        Dim oIsForeign = IIf(IsForeign, 1, 0)
        Dim oSQL = $"SELECT TERM_VALUE FROM [dbo].[FNIDB_PM_GET_VARIABLE_VALUE] ({ObjectId}, '{AttributeName}', '{LanguageCode}', {oIsForeign})"
        Dim oResult = Await _Client.GetScalarValueFromIDBAsync(oSQL)

        Return oResult.Scalar
    End Function

    Private Async Function GetAttributeValueAsTable(AttributeName As String, ObjectId As Long, Optional LanguageCode As String = "de-DE", Optional IsForeign As Boolean = False) As Task(Of DataTable)
        Dim oIsForeign = IIf(IsForeign, 1, 0)
        Dim oSQL = $"SELECT TERM_VALUE FROM [dbo].[FNIDB_PM_GET_VARIABLE_VALUE] ({ObjectId}, '{AttributeName}', '{LanguageCode}', {oIsForeign})"
        Dim oResult = Await _Client.GetDatatableFromIDBAsync(oSQL)

        Return oResult.Table
    End Function

    Private Async 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 GetAttributesForBusinessEntity(oEntityId)

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

            For Each oAttribute As Attribute In oAttributes
                Dim oControl = _Controls.GetControlForAttribute(oAttribute, True)
                Dim oItem As LayoutControlItem = AttributeLayout.AddItem()

                oItem.Text = oAttribute.Title
                oItem.Name = oAttribute.Title
                oItem.Control = oControl
            Next

            For Each oItem As LayoutControlItem In AttributeLayout.Items
                If TypeOf oItem.Control Is BaseEdit Then
                    Dim oValue = Await GetAttributeValue(oItem.Name, _ObjectId)
                    Dim oEdit = DirectCast(oItem.Control, BaseEdit)
                    oEdit.EditValue = oValue
                ElseIf TypeOf oItem.Control Is GridControl Then
                    Dim oValueTable = Await GetAttributeValueAsTable(oItem.Name, _ObjectId)
                    Dim oGrid = DirectCast(oItem.Control, GridControl)
                    oGrid.DataSource = oValueTable

                End If
            Next
        Catch ex As Exception
            _Logger.Error(ex)
        End Try

    End Sub
    Private Function ShowAttributeHistory(pDatatable As DataTable) As Boolean
        Try
            If pDatatable.Rows.Count > 0
                GridValueHistory.DataSource = pDatatable
            Else
                TabPageHistory.Visible = False
            End If

            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 Sub TabFormControl1_Click(sender As Object, e As EventArgs) Handles TabFormControl1.Click

    End Sub
End Class