/*
    Copyright (c) 2013-2020 Laurent Montel <montel@kde.org>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library 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 Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "mergecontactwidget.h"
#include "mergecontactwidgetlist.h"

#include <KLocalizedString>
#include <QSplitter>

#include <AkonadiWidgets/CollectionComboBox>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <widgets/mergecontactinfowidget.h>
#include <widgets/mergecontactloseinformationwarning.h>
#include <job/mergecontacts.h>
#include <job/mergecontactsjob.h>

namespace KABMergeContacts {
KADDRESSBOOKMERGELIB_EXPORT QAbstractItemModel *_k_mergeStubModel = nullptr;
}

using namespace KABMergeContacts;
MergeContactWidget::MergeContactWidget(QWidget *parent)
    : QWidget(parent)
    , mConflictTypes(MergeContacts::None)
{
    QVBoxLayout *lay = new QVBoxLayout(this);
    lay->setContentsMargins(0, 0, 0, 0);

    QSplitter *splitter = new QSplitter;
    splitter->setObjectName(QStringLiteral("splitter"));
    splitter->setChildrenCollapsible(false);
    lay->addWidget(splitter);

    QWidget *selectContactWidget = new QWidget(this);
    selectContactWidget->setObjectName(QStringLiteral("selectcontactwidget"));
    QVBoxLayout *vbox = new QVBoxLayout;
    selectContactWidget->setLayout(vbox);
    QLabel *lab = new QLabel(i18n("Select contacts that you really want to merge:"));
    vbox->addWidget(lab);
    mListWidget = new MergeContactWidgetList;
    mListWidget->setObjectName(QStringLiteral("listcontact"));
    mListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    vbox->addWidget(mListWidget);
    connect(mListWidget, &MergeContactWidgetList::itemSelectionChanged, this, &MergeContactWidget::slotUpdateMergeButton);
    connect(mListWidget, &MergeContactWidgetList::itemChanged, this, &MergeContactWidget::slotUpdateMergeButton);
    splitter->addWidget(selectContactWidget);

    mMergeContactInfoWidget = new MergeContactInfoWidget;
    mMergeContactInfoWidget->setObjectName(QStringLiteral("mergecontactinfowidget"));
    splitter->addWidget(mMergeContactInfoWidget);

    mMergeContactWarning = new MergeContactLoseInformationWarning;
    mMergeContactWarning->setObjectName(QStringLiteral("mergecontactwarning"));
    connect(mMergeContactWarning, &MergeContactLoseInformationWarning::continueMerging, this, &MergeContactWidget::slotAutomaticMerging);
    connect(mMergeContactWarning, &MergeContactLoseInformationWarning::customizeMergingContacts, this, &MergeContactWidget::slotCustomizeMergingContacts);
    lay->addWidget(mMergeContactWarning);

    QHBoxLayout *hbox = new QHBoxLayout;
    hbox->addStretch();

    lab = new QLabel(i18n("Select the addressbook in which to store merged contacts:"));
    hbox->addWidget(lab);

    mCollectionCombobox = new Akonadi::CollectionComboBox(_k_mergeStubModel);
    mCollectionCombobox->setAccessRightsFilter(Akonadi::Collection::CanCreateItem);
    mCollectionCombobox->setMinimumWidth(250);
    mCollectionCombobox->setMimeTypeFilter(QStringList() << KContacts::Addressee::mimeType());
    mCollectionCombobox->setObjectName(QStringLiteral("akonadicombobox"));
    connect(mCollectionCombobox, qOverload<int>(&Akonadi::CollectionComboBox::currentIndexChanged), this, &MergeContactWidget::slotUpdateMergeButton);
    connect(mCollectionCombobox, qOverload<int>(&Akonadi::CollectionComboBox::activated), this, &MergeContactWidget::slotUpdateMergeButton);

    hbox->addWidget(mCollectionCombobox);

    lay->addLayout(hbox);

    mMergeButton = new QPushButton(i18n("merge"));
    mMergeButton->setObjectName(QStringLiteral("mergebutton"));
    hbox->addWidget(mMergeButton);
    mMergeButton->setEnabled(false);

    connect(mMergeButton, &QPushButton::clicked, this, &MergeContactWidget::slotMergeContacts);
}

MergeContactWidget::~MergeContactWidget()
{
}

void MergeContactWidget::setContacts(const Akonadi::Item::List &items)
{
    mItems = items;
    mListWidget->fillListContact(mItems);
}

Akonadi::Item::List MergeContactWidget::listSelectedContacts() const
{
    return mListWidget->listSelectedContacts();
}

Akonadi::Item MergeContactWidget::currentItem() const
{
    return mListWidget->currentAkonadiItem();
}

void MergeContactWidget::slotUpdateMergeButton()
{
    const Akonadi::Item::List listCheckedItems = listSelectedContacts();
    Akonadi::Item item = currentItem();
    mMergeContactInfoWidget->setContact(item);
    mMergeButton->setEnabled((listCheckedItems.count() >= 2) && mCollectionCombobox->currentCollection().isValid());
}

void MergeContactWidget::slotMergeContacts()
{
    mSelectedItems = listSelectedContacts();
    const Akonadi::Collection col = mCollectionCombobox->currentCollection();

    KABMergeContacts::MergeContacts mergeContacts;
    mergeContacts.setItems(mSelectedItems);
    mConflictTypes = mergeContacts.requiresManualSelectionOfInformation();
    if (mConflictTypes != MergeContacts::None) {
        mMergeContactWarning->animatedShow();
    } else {
        slotAutomaticMerging();
    }
}

void MergeContactWidget::slotAutomaticMerging()
{
    KABMergeContacts::MergeContactsJob *job = new KABMergeContacts::MergeContactsJob(this);
    job->setListItem(mSelectedItems);
    job->setDestination(mCollectionCombobox->currentCollection());
    connect(job, &MergeContactsJob::finished, this, &MergeContactWidget::slotMergeDone);
    job->start();
}

void MergeContactWidget::slotCustomizeMergingContacts()
{
    Q_EMIT customizeMergeContact(mSelectedItems, mConflictTypes, mCollectionCombobox->currentCollection());
}

void MergeContactWidget::slotMergeDone(const Akonadi::Item &item)
{
    Q_EMIT contactMerged(item);
}
