/*
 * Copyright (C) 2020 by Savoir-faire Linux
 * Author: Mingrui Zhang   <mingrui.zhang@savoirfairelinux.com>
 *
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * 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/>.
 */

#pragma once

#include "qmladapterbase.h"

#include <QObject>
#include <QSettings>
#include <QString>

#include "lrcinstance.h"
#include "utils.h"

class AccountAdapter final : public QmlAdapterBase
{
    Q_OBJECT

public:
    explicit AccountAdapter(QObject *parent = 0);
    ~AccountAdapter() = default;

protected:
    void safeInit() override;

public:
    //Singleton
    static AccountAdapter &instance();

    /*
     * Change to account corresponding to combox box index.
     */
    Q_INVOKABLE void accountChanged(int index);
    /*
     * Create normal Jami account, SIP account and JAMS accounts.
     */
    Q_INVOKABLE void createJamiAccount(QString registeredName,
                                       const QVariantMap &settings,
                                       QString photoBoothImgBase64,
                                       bool isCreating);
    Q_INVOKABLE void createSIPAccount(const QVariantMap &settings, QString photoBoothImgBase64);
    Q_INVOKABLE void createJAMSAccount(const QVariantMap &settings);
    /*
     * Delete current account
     */
    Q_INVOKABLE void deleteCurrentAccount();
    /*
     * Setting related
     */
    Q_INVOKABLE void passwordSetStatusMessageBox(bool success, QString title, QString infoToDisplay);
    /*
     * conf property
     */
    Q_INVOKABLE bool hasPassword();
    Q_INVOKABLE void setArchiveHasPassword(bool isHavePassword);
    Q_INVOKABLE bool exportToFile(const QString &accountId,
                                  const QString &path,
                                  const QString &password = {}) const;
    Q_INVOKABLE void setArchivePasswordAsync(const QString &accountID, const QString &password);
    /*
     * lrc instances functions wrappers
     */
    Q_INVOKABLE bool savePassword(QString accountId, QString oldPassword, QString newPassword);
    Q_INVOKABLE void startAudioMeter(bool async);
    Q_INVOKABLE void stopAudioMeter(bool async);
    Q_INVOKABLE void startPreviewing(bool force = false, bool async = true);
    Q_INVOKABLE void stopPreviewing(bool async = true);
    Q_INVOKABLE bool hasVideoCall();
    Q_INVOKABLE bool isPreviewing();
    Q_INVOKABLE void setCurrAccDisplayName(QString text);
    Q_INVOKABLE void setSelectedAccountId(QString accountId = {});
    Q_INVOKABLE void setSelectedConvId(QString accountId = {});

signals:

    /*
     * Trigger other components to reconnect account related signals.
     */
    void accountSignalsReconnect(const QString &accountId);
    void accountStatusChanged();
    void updateConversationForAddedContact();
    /*
     * send report failure to QML to make it show the right UI state .
     */
    void reportFailure();
    void accountAdded(bool showBackUp, int index);
    void navigateToWelcomePageRequested();

private:
    void setSelectedAccount(const QString &accountId);
    void backToWelcomePage();
    void deselectConversation();

    /*
     * Make account signal connections.
     */
    void connectAccount(const QString &accountId);
    /*
     * Implement what to do when creat accout fails.
     */
    void connectFailure();

    QMetaObject::Connection accountStatusChangedConnection_;
    QMetaObject::Connection contactAddedConnection_;
    QMetaObject::Connection addedToConferenceConnection_;
    QMetaObject::Connection accountProfileChangedConnection_;
};
Q_DECLARE_METATYPE(AccountAdapter *)
