/* Copyright (C) 2014-2016 Dan Chapman <dpniel@ubuntu.com>

   This file is part of Dekko email client for Ubuntu Devices/

   This program 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 2 of
   the License or (at your option) version 3

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.4
import QtQml.StateMachine 1.0 as DSM
import Ubuntu.Components.Popups 1.0
import Dekko.Accounts 0.2
import Dekko.Settings 0.2

Item {
    id: wizard
    anchors.fill: parent

    property alias account: account
    property alias identity: newIdentity
    property var currentComponent: Qt.createComponent(Qt.resolvedUrl("NewAccountPage.qml"))
    property var selectedPreset
    property int accountType: NewAccountType.IMAP
    property string tempPasswordStore: ""
    property string tempSmtpPasswordStore: ""
    property bool hasAccounts: true

    property int oaId: 0
    property bool oaCreatedLocally: false


    function appendAccount() {
        dekko.accountsManager.appendRow(account)
        dekko.setupWizardRunning = false
        rootPageStack.pop()
    }

    Account {
        id: account
        newAccount: true
    }

    Connections {
        target: account.imapSettings
        onPortChanged: console.log("PORT: ", account.imapSettings.port)
    }

    Loader {
        id: loader
        anchors.fill: parent
        sourceComponent: currentComponent
    }

    SenderIdentityModel {
        id: identityModel
        accountId: account.accountId ? account.accountId : ""
        onCountChanged: saveIdentites()
    }

    SenderIdentity {
        id: newIdentity
        useDefaultSignature: true
        Binding on name {
            when: identityInput.active
            value: loader.item.name
        }
        Binding on email {
            when: identityInput.active
            value: loader.item.email
        }
        Binding on organization {
            when: identityInput.active
            value: loader.item.organization
        }
    }

    // For now let's just create seperate ones
    // I didn't quite think about setting both imap&smtp at the same time here when i implemented it  :-/ .....
    // anyway this should work just fine as QSettings is re-entrant neither will block each other
    PasswordManager {
        id: imapPasswordManager
        accountId: account.accountId
        type: PasswordManager.IMAP
    }

    PasswordManager {
        id: smtpPasswordManager
        accountId: account.accountId
        type: PasswordManager.SMTP
    }

    DSM.StateMachine {

        initialState: accountType === NewAccountType.ONLINE_ACCOUNT ? onlineAccountsState : hasAccounts ? newAccount : noAccounts
        running: true

        NoAccountState {
            id: noAccounts
            backTargetState: finished
            nextTargetState: newAccount
        }

        NewAccountState {
            id: newAccount
            backTargetState: noAccounts
            nextTargetState: userInputState
            newOAState: onlineAccountsState
        }

        OnlineAccountSetupState {
            id: onlineAccountsState
            backTargetState: newAccount
            nextTargetState: identityInput
        }

        UserInputState {
            id: userInputState
            backTargetState: newAccount
            hasDomainTargetState: wizard.accountType === NewAccountType.PRESET ? validateCredentials : autoConfig
            noDomainTargetState: manualInput
        }

        AutoConfigState {
            id: autoConfig
            failedTargetState: manualInput
            successTargetState: wizard.accountType === NewAccountType.SMTP ? identityInput : validateCredentials
            smtpConfigFoundTargetState: includeSmtpConfig
        }

        SmtpConfigState {
            id: includeSmtpConfig
            succeedTargetState: validateCredentials
        }

        ServerInputState {
            id: manualInput
            backTargetState: userInputState
            nextTargetState: accountType === NewAccountType.SMTP ? identityInput : validateCredentials
        }

        ValidationState {
            id: validateCredentials
            failedTargetState: accountType === NewAccountType.PRESET ? userInputState : manualInput
            successTargetState: (accountType === NewAccountType.IMAP_WITH_ADDED_SMTP || accountType === NewAccountType.PRESET) ? identityInput : descriptionInput
        }

        IdentityInputState {
            id: identityInput
            backTargetState: (accountType === NewAccountType.ONLINE_ACCOUNT) ?
                                 newAccount : (accountType === NewAccountType.PRESET) ? userInputState : manualInput
            nextTargetState: descriptionInput
        }

        DetailsInputState {
            id: descriptionInput
            backTargetState: (accountType === NewAccountType.IMAP_WITH_ADDED_SMTP ||
                              accountType === NewAccountType.PRESET ||
                              accountType === NewAccountType.ONLINE_ACCOUNT) ?
                                 identityInput : manualInput
            nextTargetState: finished
        }

        DSM.FinalState {
            id: finished
        }

        onFinished: {
            account.save()
            identityModel.appendRow(identity)
            switch (accountType) {
            case NewAccountType.PRESET:
            case NewAccountType.IMAP_WITH_ADDED_SMTP:
                imapPasswordManager.setPassword(tempPasswordStore)
                if (tempSmtpPasswordStore) {
                    smtpPasswordManager.setPassword(tempSmtpPasswordStore)
                    account.smtpSettings.authenticationMethod = SmtpSettings.LOGIN
                } else {
                    account.smtpSettings.authenticationMethod = SmtpSettings.NONE
                    smtpPasswordManager.setPassword("")
                }

                account.accountType = Account.IMAP_SMTP
                break
            case NewAccountType.IMAP:
                imapPasswordManager.setPassword(tempPasswordStore)
                account.accountType = Account.IMAP
                break
            case NewAccountType.SMTP:
                if (tempSmtpPasswordStore) {
                    smtpPasswordManager.setPassword(tempSmtpPasswordStore)
                    account.smtpSettings.authenticationMethod = SmtpSettings.LOGIN
                } else {
                    account.smtpSettings.authenticationMethod = SmtpSettings.NONE
                    smtpPasswordManager.setPassword("")
                }
                account.accountType = Account.SMTP
                break
            case NewAccountType.ONLINE_ACCOUNT:
                account.accountType = Account.ONLINE_ACCOUNT
                break
            }
            if (GlobalSettings.preferences.defaultAccount === "INVALID") {
                GlobalSettings.preferences.defaultAccount = account.accountId
            }

            // We call save() a second time here to ensure the accountType is synced
            // with the conf file. The first was needed to ensure the settings structure
            // was written before calling the password managers
            account.save()

            if (account.accountType !== Account.SMTP) {
                // We delay adding this to the accountsmanager until the models
                // are ready, otherwise the connections will fail and it will scream out loudly
                account.modelsChanged.connect(appendAccount)
                account.openImapConnection()
            } else {
                appendAccount()
            }
        }
    }
}
