// Copyright (c) 2020 Proton Technologies AG
//
// This file is part of ProtonMail Bridge.
//
// ProtonMail Bridge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ProtonMail Bridge is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with ProtonMail Bridge.  If not, see <https://www.gnu.org/licenses/>.

// Dialog with adding new user

import QtQuick 2.8
import ProtonUI 1.0


Dialog {
    id: root

    title : ""

    signal createAccount()

    property alias inputPassword : inputPassword
    property alias input2FAuth : input2FAuth
    property alias inputPasswMailbox : inputPasswMailbox
    //
    property alias username : inputUsername.text
    property alias usernameElided : usernameMetrics.elidedText

    isDialogBusy : currentIndex==waitingAuthIndex || currentIndex==addingAccIndex

    property bool isFirstAccount: false

    property color buttonOpaqueMain : "white"


    property int origin: 0
    property int nameAndPasswordIndex : 0
    property int waitingAuthIndex : 2
    property int twoFAIndex : 1
    property int mailboxIndex : 3
    property int addingAccIndex : 4
    property int newAccountIndex : 5


    signal cancel()
    signal okay()

    TextMetrics {
        id: usernameMetrics
        font: dialogWaitingAuthText.font
        elideWidth : Style.dialog.widthInput
        elide      : Qt.ElideMiddle
        text       : root.username
    }

    Column { // 0
        id: dialogNameAndPassword
        property int heightInputs : inputUsername.height + buttonRow.height + middleSep.height + inputPassword.height + middleSepPassw.height

        Rectangle {
            id: topSep
            color  : "transparent"
            width  : Style.main.dummy
            height : root.height/2 - (dialogNameAndPassword.heightInputs)/2
        }

        InputField {
            id: inputUsername
            iconText   : Style.fa.user_circle
            label      : qsTr("Username", "enter username to add account")
            onAccepted : inputPassword.focusInput = true
        }

        Rectangle { id: middleSepPassw; color : "transparent"; width : Style.main.dummy; height : Style.dialog.heightSeparator}

        InputField {
            id: inputPassword
            label      : qsTr("Password", "password entry field")
            iconText   : Style.fa.lock
            isPassword : true
            onAccepted : root.okay()
        }

        Rectangle { id: middleSep; color : "transparent"; width : Style.main.dummy; height : 2*Style.dialog.heightSeparator }

        Row {
            id: buttonRow
            anchors.horizontalCenter: parent.horizontalCenter
            spacing: Style.dialog.fontSize
            ButtonRounded {
                id:buttonCancel
                fa_icon    : Style.fa.times
                text       : qsTr("Cancel", "dismisses current action")
                color_main : Style.dialog.text
                onClicked  : root.cancel()
            }
            ButtonRounded {
                id: buttonNext
                fa_icon     : Style.fa.check
                text        : qsTr("Next", "navigate to next page in add account flow")
                color_main  : buttonOpaqueMain
                color_minor : Style.dialog.textBlue
                isOpaque    : true
                onClicked   : root.okay()
            }
        }

        Rectangle {
            color : "transparent"
            width : Style.main.dummy
            height : root.height - (topSep.height + dialogNameAndPassword.heightInputs + Style.main.bottomMargin + signUpForAccount.height)
        }

        ClickIconText {
            id: signUpForAccount
            anchors.horizontalCenter: parent.horizontalCenter
            fontSize      : Style.dialog.fontSize
            iconSize      : Style.dialog.fontSize
            iconText      : "+"
            text          : qsTr ("Sign Up for an Account", "takes user to web page where they can create a ProtonMail account")
            textBold      : true
            textUnderline : true
            textColor     : Style.dialog.text
            onClicked     : root.createAccount()
        }
    }

    Column { // 1
        id: dialog2FA
        property int heightInputs : buttonRowPassw.height  + middleSep2FA.height + input2FAuth.height

        Rectangle {
            color : "transparent"
            width : Style.main.dummy
            height : (root.height - dialog2FA.heightInputs)/2
        }

        InputField {
            id: input2FAuth
            label      : qsTr("Two Factor Code", "two factor code entry field")
            iconText   : Style.fa.lock
            onAccepted : root.okay()
        }

        Rectangle { id: middleSep2FA; color : "transparent"; width : Style.main.dummy; height : 2*Style.dialog.heightSeparator }

        Row {
            id: buttonRowPassw
            anchors.horizontalCenter: parent.horizontalCenter
            spacing: Style.dialog.fontSize
            ButtonRounded {
                id: buttonBack
                fa_icon: Style.fa.times
                text: qsTr("Back", "navigate back in add account flow")
                color_main: Style.dialog.text
                onClicked : root.cancel()
            }
            ButtonRounded {
                id: buttonNextTwo
                fa_icon: Style.fa.check
                text: qsTr("Next", "navigate to next page in add account flow")
                color_main: buttonOpaqueMain
                color_minor: Style.dialog.textBlue
                isOpaque: true
                onClicked : root.okay()
            }
        }
    }

    Column { // 2
        id: dialogWaitingAuth
        Rectangle { color : "transparent"; width : Style.main.dummy; height : (root.height-dialogWaitingAuthText.height) /2 }
        Text {
            id: dialogWaitingAuthText
            anchors.horizontalCenter: parent.horizontalCenter
            color: Style.dialog.text
            font.pointSize: Style.dialog.fontSize * Style.pt
            text : qsTr("Logging in") +"\n" + root.usernameElided
            horizontalAlignment: Text.AlignHCenter
        }
    }

    Column { // 3
        id: dialogMailboxPassword
        property int heightInputs : buttonRowMailbox.height + inputPasswMailbox.height + middleSepMailbox.height

        Rectangle { color : "transparent"; width : Style.main.dummy; height : (root.height - dialogMailboxPassword.heightInputs)/2}

        InputField {
            id: inputPasswMailbox
            label      : qsTr("Mailbox password for %1", "mailbox password entry field").arg(root.usernameElided)
            iconText   : Style.fa.lock
            isPassword : true
            onAccepted : root.okay()
        }

        Rectangle { id: middleSepMailbox; color : "transparent"; width : Style.main.dummy; height : 2*Style.dialog.heightSeparator }

        Row {
            id: buttonRowMailbox
            anchors.horizontalCenter: parent.horizontalCenter
            spacing: Style.dialog.fontSize
            ButtonRounded {
                id: buttonBackBack
                fa_icon: Style.fa.times
                text: qsTr("Back", "navigate back in add account flow")
                color_main: Style.dialog.text
                onClicked : root.cancel()
            }
            ButtonRounded {
                id: buttonLogin
                fa_icon: Style.fa.check
                text: qsTr("Next", "navigate to next page in add account flow")
                color_main: buttonOpaqueMain
                color_minor: Style.dialog.textBlue
                isOpaque: true
                onClicked : root.okay()
            }
        }
    }

    Column { // 4
        id: dialogWaitingAccount

        Rectangle { color : "transparent"; width : Style.main.dummy; height : (root.height - dialogWaitingAccountText.height )/2 }

        Text {
            id: dialogWaitingAccountText
            anchors.horizontalCenter: parent.horizontalCenter
            color: Style.dialog.text
            font {
                bold : true
                pointSize: Style.dialog.fontSize * Style.pt
            }
            text : qsTr("Adding account, please wait ...", "displayed after user has logged in, before new account is displayed")
            wrapMode: Text.Wrap
        }
    }

    Column { // 5
        id: dialogFirstUserAdded

        Rectangle { color : "transparent"; width : Style.main.dummy; height : (root.height - dialogWaitingAccountText.height - okButton.height*2 )/2 }

        Text {
            id: textFirstUser
            anchors.horizontalCenter: parent.horizontalCenter
            color: Style.dialog.text
            font {
                bold : false
                pointSize: Style.dialog.fontSize * Style.pt
            }
            width: 2*root.width/3
            horizontalAlignment: Text.AlignHCenter
            textFormat: Text.RichText
            text: "<html><style>a { font-weight: bold; text-decoration: none; color: white;}</style>"+
            qsTr("Now you need to configure your client(s) to use the Bridge. Instructions for configuring your client can be found at", "") +
            "<br/><a href=\"https://protonmail.com/bridge/clients\">https://protonmail.com/bridge/clients</a>.<html>"
            wrapMode: Text.Wrap
            onLinkActivated: {
                Qt.openUrlExternally(link)
            }
            MouseArea {
                anchors.fill: parent
                cursorShape: parent.hoveredLink=="" ? Qt.PointingHandCursor : Qt.WaitCursor
                acceptedButtons: Qt.NoButton
            }
        }

        Rectangle { color : "transparent"; width : Style.main.dummy; height : okButton.height}

        ButtonRounded{
            id: okButton
            anchors.horizontalCenter: parent.horizontalCenter
            color_main: buttonOpaqueMain
            color_minor: Style.main.textBlue
            isOpaque: true
            text: qsTr("Okay", "confirms and dismisses a notification")
            onClicked: root.hide()
        }
    }

    function clear_user() {
        inputUsername.text      = ""
        inputUsername.rightIcon = ""
    }

    function clear_passwd() {
        inputPassword.text    = ""
        inputPassword.rightIcon    = ""
        inputPassword.hidePasswordText()
    }


    function clear_2fa() {
        input2FAuth.text      = ""
        input2FAuth.rightIcon = ""
    }

    function clear_passwd_mailbox() {
        inputPasswMailbox.text  = ""
        inputPasswMailbox.rightIcon  = ""
        inputPasswMailbox.hidePasswordText()
    }

    onCancel : {
        root.warning.visible=false
        if (currentIndex==0) {
            root.hide()
        } else {
            clear_passwd()
            clear_passwd_mailbox()
            currentIndex=0
        }
    }


    function check_inputs() {
        var isOK = true
        switch (currentIndex) {
            case nameAndPasswordIndex :
            isOK &= inputUsername.checkNonEmpty()
            isOK &= inputPassword.checkNonEmpty()
            break
            case twoFAIndex :
            isOK &= input2FAuth.checkNonEmpty()
            break
            case mailboxIndex :
            isOK &= inputPasswMailbox.checkNonEmpty()
            break
        }
        if (isOK) {
            warning.visible = false
            warning.text= ""
        } else {
            setWarning(qsTr("Field required", "a field that must be filled in to submit form"),0)
        }
        return isOK
    }

    function setWarning(msg, changeIndex) {
        // show message
        root.warning.text = msg
        root.warning.visible = true
    }


    onOkay : {
        var isOK = check_inputs()
        if (isOK) {
            root.origin = root.currentIndex
            switch (root.currentIndex) {
                case nameAndPasswordIndex:
                case twoFAIndex:
                root.currentIndex = waitingAuthIndex
                break;
                case mailboxIndex:
                root.currentIndex = addingAccIndex
            }
            timer.start()
        }
    }

    onShow: {
        root.title = qsTr ("Log in to your ProtonMail account", "displayed on screen when user enters username to begin adding account")
        root.warning.visible = false
        inputUsername.forceFocus()
        root.isFirstAccount =  go.isFirstStart && accountsModel.count==0
    }

    function startAgain() {
        clear_passwd()
        clear_2fa()
        clear_passwd_mailbox()
        root.currentIndex = nameAndPasswordIndex
        root.inputPassword.focusInput = true
    }

    function finishLogin(){
        root.currentIndex = addingAccIndex
        var auth = go.addAccount(inputPasswMailbox.text)
        if (auth<0) {
            startAgain()
            return
        }
    }

    Connections {
        target: timer

        onTriggered : {
            timer.repeat = false
            switch (root.origin) {
                case nameAndPasswordIndex:
                var auth = go.login(inputUsername.text, inputPassword.text)
                if (auth < 0) {
                    startAgain()
                    break
                }
                if (auth == 1) {
                    root.currentIndex = twoFAIndex
                    root.input2FAuth.focusInput = true
                    break
                }
                if (auth == 2) {
                    root.currentIndex = mailboxIndex
                    root.inputPasswMailbox.focusInput = true
                    break
                }
                root.inputPasswMailbox.text = inputPassword.text
                root.finishLogin()
                break;
                case twoFAIndex:
                var auth = go.auth2FA(input2FAuth.text)
                if (auth < 0) {
                    startAgain()
                    break
                }
                if (auth == 1) {
                    root.currentIndex = mailboxIndex
                    root.inputPasswMailbox.focusInput = true
                    break
                }
                root.inputPasswMailbox.text = inputPassword.text
                root.finishLogin()
                break;
                case mailboxIndex:
                root.finishLogin()
                break;
            }
        }
    }

    onHide: {
        // because hide slot is conneceted to processFinished it will update
        // the list evertyime `go` obejcet is finished
        clear_passwd()
        clear_passwd_mailbox()
        clear_2fa()
        clear_user()
        go.loadAccounts()
        if (root.isFirstAccount && accountsModel.count==1) {
            root.isFirstAccount=false
            root.currentIndex=5
            root.show()
            root.title=qsTr("Success, Account Added!", "shown after successful account addition")
        }
    }

    Keys.onPressed: {
        if (event.key == Qt.Key_Enter) {
            root.okay()
        }
    }
}
