/*!
 *
 * Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved.
 * \copyright
 * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN
 * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER.
 *
 * \file    SettingsExportLogs.qml
 * \author  (last)      Behrouz NematiPour
 * \date    (last)      04-Apr-2024
 * \author  (original)  Behrouz NematiPour
 * \date    (original)  27-Jun-2022
 *
 */

// Qt
import QtQuick                  2.12
import QtQuick.Controls         2.12
import Qt.labs.folderlistmodel  2.12


// TODO: Add the fileCopy function to have control over the copy
// TODO: Add cancel
// TODO: Add Service and Treatment log export and exit

// TODO: Add selecction export
// TODO: Add error display

// Project
import Gui.Actions 0.1

//  Qml imports
import "qrc:/"
import "qrc:/globals"
import "qrc:/components"

/*!
 * \brief   SettingsExportLogs is used to Export logs, and display the SD-Card and USB device informaiton and list of files.
 */
SettingsBase    { id: _root
    itemIndex       : SettingsStack.ExportLogs

    ////////////////////////////////////////////////////////////////////////////////
    // FIXME: The model being used here is the QML FileListModel.                 //
    //        This model is so limited and do not update well.                    //
    //        This model definitely has to be replaced with a C++ one,            //
    //        like the other MVC classes we have.                                 //
    ////////////////////////////////////////////////////////////////////////////////

    readonly property string sdcLabel                       : qsTr("SD-Card")
    readonly property string devUnit                        : "MB" // no translation
    readonly property string devUnitLabel                   : " (" + devUnit + ")\n" // no translation
    readonly property string usbLabel                       : qsTr("USB Drive")
    readonly property int    headetRowHight                 : 50

    readonly property int    typeIndexApplication           : 0
    readonly property int    typeIndexService               : 1
    readonly property int    typeIndexTreatment             : 2

    readonly property string typeLabelApplication           : qsTr("Application"                  )
    readonly property string typeLabelService               : qsTr("Service"                      )
    readonly property string typeLabelTreatment             : qsTr("Treatment"                    )

             property bool   isDevice                       : _GuiView.runOnDevice
    readonly property string typePathClr                    : ""
    readonly property string typePathPrefix                 : "file://"
    readonly property string typePathTxr                    : typePathPrefix + (isDevice ? "/mnt/data/configurations"    : "/home/denali/Desktop/sd-card" )
    readonly property string typePathSrc                    : typePathPrefix + (isDevice ? "/media/sd-card"         : "/home/denali/Desktop/sd-card" )
    readonly property string typePathDst                    : typePathPrefix + (isDevice ? "/media/usb"             : "/home/denali/Desktop/usb-disk")
    readonly property string typeFolderApplication          : "/log"
    readonly property string typeFolderService              : "/service"
    readonly property string typeFolderTreatment            : "/treatment"

    readonly property string typeFolderApplicationSrc       : typePathSrc + typeFolderApplication
    readonly property string typeFolderApplicationDst       : typePathDst + typeFolderApplication
    readonly property string typeFolderServiceSrc           : typePathSrc + typeFolderService
    readonly property string typeFolderServiceDst           : typePathDst + typeFolderService
    readonly property string typeFolderTreatmentSrc         : typePathTxr + typeFolderTreatment
    readonly property string typeFolderTreatmentDst         : typePathDst + typeFolderTreatment

    readonly property var    typeFilterAll                  : ["*"]
    readonly property var    typeFilterClr                  : []

    readonly property bool   horizontalLayout               : _GuiView.useLogLongName

    confirmVisible                                          : false
    notificationMargin                                      : Variables.notificationHeight

    function refreshModels() {
        _usbFolderColumn.clearModel()
        _usbFolderColumn.updateModel()
    }

    function doExport() {
        notificationText = _logTypeCombo.displayText + " " +
                           qsTr("log export to USB in progress ... ")
        refreshModels()

        switch (_logTypeCombo.currentIndex) {
        case typeIndexApplication:
            _GuiView.doExportLog()
            break
        case typeIndexService:
            _GuiView.doExportService()
            break
        case typeIndexTreatment:
            _GuiView.doExportTreatment()
            break
        }

        refreshModels()
    }

    onVisibleChanged: {
        if ( _root.visible ) {
            updatePanels( _logTypeCombo.currentIndex )
        }
    }

    property bool isUpdatePanels: false
    function updatePanels (vIndex) {
        isUpdatePanels = true

        _GuiView.doExportListRemove()
        _sdcFolderColumn.clearModel()
        _usbFolderColumn.clearModel()

        switch (vIndex) {
        case typeIndexApplication:
            _sdcFolderColumn.currentTypeFolderApplication = typeFolderApplicationSrc
            _usbFolderColumn.currentTypeFolderApplication = typeFolderApplicationDst
            break
        case typeIndexService:
            _sdcFolderColumn.currentTypeFolderApplication = typeFolderServiceSrc
            _usbFolderColumn.currentTypeFolderApplication = typeFolderServiceDst
            break
        case typeIndexTreatment:
            _sdcFolderColumn.currentTypeFolderApplication = typeFolderTreatmentSrc
            _usbFolderColumn.currentTypeFolderApplication = typeFolderTreatmentDst
            break
        }

        _sdcFolderColumn.updateModel()
        _usbFolderColumn.updateModel()

        isUpdatePanels = false
    }

    Connections { target: _logTypeCombo
        function onCurrentIndexChanged() {
            vLocalization.notification = ""
        }
    }

    Connections { target: _GuiView
        function onSdIsReadyChanged     ( vValue                        ) { _root.updatePanels()                                        }
        function onDidExportStat        ( vIndex, vFileName, vPercent   ) { _sdcFolderView.positionViewAtIndex(vIndex, ListView.Center) }
        function onDidUSBDriveUmount    (                               ) { _usbFolderColumn. clearModel ( )                            }
        function onDidUSBDriveRemove    (                               ) { _usbFolderColumn. clearModel ( )                            }
        function onDidExportLog         ( vValue                        ) { _usbFolderColumn. clearModel ( )                            }
        function onDidUSBDriveMount     (                               ) { _usbFolderColumn.updateModel ( )                            }
        function onDidExport            (                               ) { _usbFolderColumn.updateModel ( )
                                                                            notificationText = _logTypeCombo.displayText + " " +
                                                                                               qsTr("log export to USB is complete")    }
    }

    BaseComboBox { id: _logTypeCombo
        anchors.top                 : _root.top
        anchors.topMargin           : Variables.headerButtonsMargin
        anchors.horizontalCenter    : parent.horizontalCenter
        height                      : Variables.contentHeight
        currentIndex                : 0
        model                       : [
            _root.typeLabelApplication          ,
            _root.typeLabelService              ,
            _root.typeLabelTreatment
        ]

        onActivated: updatePanels( _logTypeCombo.currentIndex )
    }

    USBButton                                               { id: _usbEjectButton
        width                                               : 150
        height                                              :  50
        anchors.right                                       : _root.right
        anchors.top                                         : _root.top
        anchors.margins                                     : Variables.headerButtonsMargin
        enabled                                             : _GuiView.usbIsReady && !_GuiView.exportRunning && ! isUpdatePanels
    }

    contentItem: Item    { id : _contentRect
        readonly property int columnWidthProgress           : 375
        readonly property int columnWidthFolder             : parent.width / 2.3
        readonly property int columnWidthFileName           : _root.horizontalLayout ? 685 : 575 // best combination
        readonly property int columnWidthFileSize           :  120
        readonly property int columnCellHeight              :  60

        anchors.fill: parent

        component Header:   Rectangle { id: _Header
            width       : parent.width
            height      : _contentRect.columnCellHeight
            color       : Colors.panelBackgroundColor
            radius      : 9

            border {
                width: 1
                color: Colors.panelBorderColor
            }

            Item {
                width                       : parent.width
                height                      :  _contentRect.columnCellHeight

                Row {   id  : _HeaderRow
                    anchors.fill                    : parent
                    height                          : parent.height
                    leftPadding                     : Variables.defaultMargin * 2
                    rightPadding                    : Variables.defaultMargin * 2

                    Text {  id  : _HeaderNameText
                        width                   : _contentRect.columnWidthFileName
                        height                  : parent.height
                        text                    : qsTr("Log Name:")
                        color                   : Colors.textMain
                        font.pixelSize          : Fonts.fontPixelTextRectExtra
                        verticalAlignment       : Text.AlignVCenter
                    }

                    Text {  id  : _HeaderSizeText
                        width                   : _contentRect.columnWidthFileSize
                        height                  : parent.height
                        text                    : qsTr("Size:")
                        color                   : Colors.textMain
                        font.pixelSize          : Fonts.fontPixelTextRectExtra
                        verticalAlignment       : Text.AlignVCenter
                    }
                }
            }
        }

        Column { id : _sdcFolderColumn
            property string currentTypeFolderApplication    : _root.typeFolderApplicationSrc

            anchors.left                                    : parent.left
            width                                           : _contentRect.columnWidthFolder
            height                                          : parent.height - ( Variables.notificationHeight + Variables.defaultMargin )

            // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there.
            function updateModel() {
                _sdcFolderModel.folder                      = currentTypeFolderApplication  // FIXME: there has to be a View for this which also get changed by log type.
                _sdcFolderModel.nameFilters                 = _root.typeFilterAll
            }

            function clearModel() {
                _sdcFolderModel.folder                      = _root.typePathClr
                _sdcFolderModel.nameFilters                 = _root.typeFilterClr
            }

            Label { id                                      : _sdcLabel
                text                                        : _root.sdcLabel + ": %1 files"/*, %2 %3"*/.arg(_sdcFolderModel.count) + (_GuiView.exportCount ? " [Selected: %1]".arg(_GuiView.exportCount ) : "") //.arg("__").arg(_root.dvcUnit)
                width                                       : parent.width
                height                                      : _root.headetRowHight
                verticalAlignment                           : Text.AlignVCenter
            }

            Rectangle { id                                  : _sdcFolderRectangle
                color                                       : Colors.panelBackgroundColor
                radius                                      : Variables.dialogRadius
                anchors.left                                : parent.left
                width                                       : parent.width
                height                                      : parent.height
                border {
                    width                                   : 1
                    color                                   : Colors.panelBorderColor
                }

                Column { id: _networkColumn
                    anchors.fill: parent

                    Header { id: _sdcHeader }

                    Item { id: _sdcListItem
                        width               : parent.width
                        height              : parent.height - _sdcHeader.height

                        ListView { id   : _sdcFolderView
                            enabled                                 : ! _GuiView.exportRunning && ! isUpdatePanels
                            clip                                    : true
                            width                                   : parent.width
                            height                                  : parent.height

                            model: FolderListModel { id : _sdcFolderModel
                                showDirs                            : false
                                sortField                           : FolderListModel.Time
                                folder                              : _sdcFolderColumn.currentTypeFolderApplication // FIXME: there has to be a View for this which also get changed by log type.
                            }

                            delegate: ProgressBar { id  : _sdcItemBackground
                                // *** IMPORTANT ***
                                // QML kills the items when they get out of the view port in regards to the cacheBuffer,
                                // and the next time it gets in the view port will be created with all the properties in their defaults.
                                property bool inExportList      :   _GuiView.exportList         [ index ]   // I couldn't make it work and this always returns undefined, but has to be used to trigger the change.
                                                                  ? _GuiView.exportList         [ index ]   // In case the issue fixes it should return true if it is true, obviously!
                                                                  : _GuiView.doExportListSelect ( index )   // otherwise for now, it calls the contains() function of the list in C++ backend.
                                property int    exportPercent   :   _GuiView.exportIndex === index
                                                                  ? _GuiView.exportPercent
                                                                  : 0
                                onExportPercentChanged          : console.log( "%", exportPercent)

                                property bool isShownInList     : ! _GuiView.isPathSymLink(_sdcFolderColumn.currentTypeFolderApplication.replace(typePathPrefix, "") + "/" + fileName)

                                //DEBUG: onInExportListChanged: console.debug(" * ", index, inExportList)
                                function exportListUpdate() {
                                    if (_GuiView.doExportListSelect( index ) ) {
                                        _GuiView.doExportListDelete( index )
                                    }
                                    else {
                                        _GuiView.doExportListInsert( index , fileName )
                                    }
                                }

                                MouseArea                       {
                                    anchors.fill                : parent
                                    onClicked                   : exportListUpdate()
                                }
                                progress.z                      : 0
                                minText.visible                 : false
                                maxText.visible                 : false
                                marker.visible                  : false
                                maximum                         : 100 // percent
                                value                           : maximum - exportPercent

                                // Setting height and width to 0 when the file is not shown in the list because
                                // it is a symlink or other conditions
                                width                           : isShownInList ? _sdcFolderView.width          : 0
                                height                          : isShownInList ? _contentRect.columnCellHeight : 0

                                progress.anchors.bottomMargin   : 5
                                progress.anchors.topMargin      : 5
                                progress.anchors.leftMargin     : Variables.defaultMargin
                                progress.width                  : width - progress.anchors.leftMargin * 2

                                bgColor                         : Colors.transparent
                                color                           : inExportList ? Colors.borderButton : Colors.transparent
                                radius                          : 5

                                Item {
                                    width                       : isShownInList ? parent.width                  : 0
                                    height                      : isShownInList ? _contentRect.columnCellHeight : 0

                                    Row {   id  : _sdcFileRow
                                        // Setting height and width to 0 when the file is not shown in the list because
                                        // it is a symlink or other conditions
                                        anchors.fill                    : parent
                                        height                          : parent.height
                                        leftPadding                     : Variables.defaultMargin * 2
                                        rightPadding                    : Variables.defaultMargin * 2

                                        Text {  id  : _sdcFileNameText
                                            clip                    : true
                                            width                   : isShownInList ? (_contentRect.columnWidthFileName - 2) : 0
                                            height                  : parent.height
                                            text                    : fileName
                                            color                   : Colors.textMain
                                            font.pixelSize          : Fonts.fontPixelTextRectExtra
                                            verticalAlignment       : Text.AlignVCenter
                                        }

                                        Text {  id  : _sdcFileSizeText
                                            clip                    : true
                                            width                   : isShownInList ? _contentRect.columnWidthFileSize : 0
                                            height                  : parent.height
                                            text                    : Variables.sizeConverted( fileSize, 1000, 3)
                                            color                   : Colors.textMain
                                            font.pixelSize          : Fonts.fontPixelTextRectExtra
                                            verticalAlignment       : Text.AlignVCenter
                                        }
                                    }

                                    Line { id: _sdcDivider
                                        color   : Colors.panelBorderColor
                                        visible : index !== _sdcFolderView.count - 1
                                        anchors {
                                            bottom      : parent.bottom
                                            left        : parent.left
                                            leftMargin  : Variables.defaultMargin * 2
                                            right       : parent.right
                                            rightMargin : Variables.defaultMargin * 2
                                        }
                                    }
                                }
                            }
                        }

                        ScrollBar {
                            anchors.fill                            : _sdcFolderView
                            flickable                               : _sdcFolderView
                            handleWidth                             : Variables.settingsExportLogsScrollBarWidth
                            scrollColor                             : Colors.scrollBarColor
                        }
                    }
                }
            }
        }

        ExportButton { id : _logTypeExportButton
            anchors.centerIn: parent
            width                                       : 100
            height                                      : Variables.touchRectHeight
            radius                                      : Variables.touchRectRadius
            border.width                                : Variables.borderWidth
            enabled                                     : _GuiView.usbIsReady && !_GuiView.exportRunning && ! isUpdatePanels
            onClicked                                   : doExport()
        }

        Column { id : _usbFolderColumn
            property string currentTypeFolderApplication    : _root.typeFolderApplicationDst

            anchors.right                                   : parent.right
            width                                           : _contentRect.columnWidthFolder
            height                                          : parent.height - ( Variables.notificationHeight + Variables.defaultMargin )

            // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there.
            function updateModel() {
                _usbFolderModel.folder                      = currentTypeFolderApplication  // FIXME: there has to be a View for this which also get changed by log type.
                _usbFolderModel.nameFilters                 = _root.typeFilterAll
            }

            function clearModel() {
                _usbFolderModel.folder                      = _root.typePathClr
                _usbFolderModel.nameFilters                 = _root.typeFilterClr
            }

            // FIXME: there has to be a View for this, and the timer should be removed and an event driven signal should be implemented there.
            Timer { id: _usbUpdate
                interval    : 500
                repeat      : true
                running     : _GuiView.exportRunning
                onRunningChanged: {
                    if(!running) {
                        // do one last update to get the correct file size else the USB file size is displayed
                        // as being smaller than the same file on SD card
                        _usbFolderColumn. clearModel()
                        _usbFolderColumn.updateModel()
                    }
                }

                onTriggered : {
                    _usbFolderColumn. clearModel()
                    _usbFolderColumn.updateModel()
                }
            }

            Label { id  : _usbLabel
                text                                        : _root.usbLabel + ": %1 files"/*", %2 %3"*/.arg(_usbFolderModel.count)//.arg("__").arg(_root.dvcUnit)
                width                                       : parent.width
                height                                      : _root.headetRowHight
                verticalAlignment                           : Text.AlignVCenter
            }

            Rectangle { id                                  : _usbFolderRectangle
                color                                       : Colors.panelBackgroundColor
                radius                                      : Variables.dialogRadius
                anchors.left                                : parent.left
                width                                       : parent.width
                height                                      : parent.height
                border {
                    width                                   : 1
                    color                                   : Colors.panelBorderColor
                }

                ScrollBar {
                    anchors.fill                            : _usbFolderView
                    flickable                               : _usbFolderView
                    handleWidth                             : Variables.settingsExportLogsScrollBarWidth
                    scrollColor                             : Colors.scrollBarColor
                }

                ListView { id                               : _usbFolderView
                    clip                                    : true
                    anchors.fill                            : parent

                    model: FolderListModel { id : _usbFolderModel // FIXME: I don't like this model, it's too lazy and I don't have control over it. There has to be a Model for this.
                        showDirs                            : false
                        sortField                           : FolderListModel.Time
                        folder                              : _usbFolderColumn.currentTypeFolderApplication
                    }

                    delegate :Item {  id: _usbDelegateItem
                        width                               : _usbFolderView.width
                        height                              : _contentRect.columnCellHeight

                        Row { id    : _usbFileRow
                            anchors.fill                    : parent
                            height                          : parent.height
                            leftPadding                     : Variables.defaultMargin * 2
                            rightPadding                    : Variables.defaultMargin * 2

                            Text { id   : _usbFileNameText
                                clip                        : true
                                width                       : _contentRect.columnWidthFileName
                                height                      : parent.height
                                text                        : fileName
                                color                       : Colors.textMain
                                font.pixelSize              : Fonts.fontPixelTextRectExtra
                                verticalAlignment           : Text.AlignVCenter
                            }

                            Text { id   : _usbFileSizeText
                                clip                        : true
                                width                       : _contentRect.columnWidthFileSize
                                height                      : parent.height
                                text                        : Variables.sizeConverted( fileSize, 1000, 3)
                                color                       : Colors.textMain
                                font.pixelSize              : Fonts.fontPixelTextRectExtra
                                verticalAlignment           : Text.AlignVCenter
                            }
                        }

                        Line { id: _usbDivider
                            color   : Colors.panelBorderColor
                            visible : index !== _usbFolderView.count - 1
                            anchors {
                                bottom      : parent.bottom
                                left        : parent.left
                                leftMargin  : Variables.defaultMargin * 2
                                right       : parent.right
                                rightMargin : Variables.defaultMargin * 2
                            }
                        }
                    }
                }
            }
        }

        Column { id : _progressColumn
            property int progressWidth                      : 170
            property int progressHeight                     : height - _logTypeCombo.height - _logTypeExportButton.height

            spacing                                         : 10
            width                                           : _contentRect.columnWidthProgress
            height                                          : parent.height

            Column {
                width                                       : _progressColumn.progressWidth
                height                                      : _progressColumn.progressHeight - 2 * _progressColumn.spacing
                Item { id                                   : _SDC_item
                    width                                   : _progressColumn.progressWidth
                    height                                  : parent.height / 2

                    SDCProgressItem                         { id: _SDC_progressItem
                        thickness                           : 10
                        displayInformation                  : false
                        anchors.fill                        : parent
                    }
                    Label {
                        anchors.left                        : _SDC_progressItem.right
                        anchors.leftMargin                  : _progressColumn.spacing
                        anchors.verticalCenter              : parent.verticalCenter
                        text                                : _root.sdcLabel + _root.devUnitLabel + ("Free : %1\nTotal: %2").arg( Variables.sizeConverted( _GuiView.sdAvail, 1000, 3) ).arg( Variables.sizeConverted( _GuiView.sdTotal, 1000, 3) )
                    }
                    Label {
                        anchors.fill                        : parent
                        verticalAlignment                   : Text.AlignVCenter
                        horizontalAlignment                 : Text.AlignHCenter
                        text                                : _SDC_progressItem.percent
                    }
                }

                Item { id                                   : _USB_item
                    width                                   : _progressColumn.progressWidth
                    height                                  : parent.height / 2

                    USBProgressItem                         { id: _USB_progressItem
                        thickness                           : 10
                        displayInformation                  : false
                        anchors.fill                        : parent
                    }
                    Label {
                        anchors.left                        : _USB_progressItem.right
                        anchors.leftMargin                  : _progressColumn.spacing
                        anchors.verticalCenter              : parent.verticalCenter
                        text                                : _root.usbLabel + _root.devUnitLabel + ("Free : %1\nTotal: %2").arg( Variables.sizeConverted( _GuiView.usbAvail, 1000, 3) ).arg( Variables.sizeConverted( _GuiView.usbTotal, 1000, 3) )
                    }
                    Label {
                        anchors.fill                        : parent
                        verticalAlignment                   : Text.AlignVCenter
                        horizontalAlignment                 : Text.AlignHCenter
                        text                                : _USB_progressItem.percent
                    }
                }
            }
        }
    }
}
