/*
    Copyright (c) 2010 Volker Krause <vkrause@kde.org>
    This file was part of KMail.
    Copyright (c) 2005 Cornelius Schumacher <schumacher@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 "recipientspicker.h"
#include "settings/messagecomposersettings.h"

#include <Akonadi/Contact/EmailAddressSelectionWidget>
#include <Akonadi/Contact/RecipientsPickerWidget>
#include <kcontacts/contactgroup.h>
#include <Libkdepim/LdapSearchDialog>

#include <KConfigGroup>
#include <KLocalizedString>
#include <KMessageBox>
#include <QLineEdit>
#include <QPushButton>
#include "messagecomposer_debug.h"

#include <QKeyEvent>
#include <QTreeView>
#include <QVBoxLayout>
#include <KSharedConfig>
#include <QDialogButtonBox>

using namespace MessageComposer;

RecipientsPicker::RecipientsPicker(QWidget *parent)
    : QDialog(parent)
{
    setObjectName(QStringLiteral("RecipientsPicker"));
    setWindowTitle(i18nc("@title:window", "Select Recipient"));

    QVBoxLayout *mainLayout = new QVBoxLayout(this);

    mView = new Akonadi::RecipientsPickerWidget(false, nullptr, this);
    mainLayout->addWidget(mView);
    mainLayout->setStretchFactor(mView, 1);

    connect(mView->view()->selectionModel(), &QItemSelectionModel::selectionChanged,
            this, &RecipientsPicker::slotSelectionChanged);
    connect(mView->view(), &QAbstractItemView::doubleClicked,
            this, &RecipientsPicker::slotPicked);

    QPushButton *searchLDAPButton = new QPushButton(i18n("Search &Directory Service"), this);
    connect(searchLDAPButton, &QPushButton::clicked, this, &RecipientsPicker::slotSearchLDAP);
    mainLayout->addWidget(searchLDAPButton);

    KConfig config(QStringLiteral("kabldaprc"));
    KConfigGroup group = config.group("LDAP");
    int numHosts = group.readEntry("NumSelectedHosts", 0);
    if (!numHosts) {
        searchLDAPButton->setVisible(false);
    }

    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
    mUser1Button = new QPushButton;
    buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole);
    mUser2Button = new QPushButton;
    buttonBox->addButton(mUser2Button, QDialogButtonBox::ActionRole);
    mUser3Button = new QPushButton;
    buttonBox->addButton(mUser3Button, QDialogButtonBox::ActionRole);
    mUser4Button = new QPushButton;
    buttonBox->addButton(mUser4Button, QDialogButtonBox::ActionRole);

    connect(buttonBox, &QDialogButtonBox::rejected, this, &RecipientsPicker::reject);
    mainLayout->addWidget(buttonBox);
    mUser4Button->setText(i18n("Add as &Reply-To"));
    mUser3Button->setText(i18n("Add as &To"));
    mUser2Button->setText(i18n("Add as CC"));
    mUser1Button->setText(i18n("Add as &BCC"));
    connect(mUser1Button, &QPushButton::clicked, this, &RecipientsPicker::slotBccClicked);
    connect(mUser2Button, &QPushButton::clicked, this, &RecipientsPicker::slotCcClicked);
    connect(mUser3Button, &QPushButton::clicked, this, &RecipientsPicker::slotToClicked);
    connect(mUser4Button, &QPushButton::clicked, this, &RecipientsPicker::slotReplyToClicked);

    mView->emailAddressSelectionWidget()->searchLineEdit()->setFocus();

    readConfig();

    slotSelectionChanged();
}

RecipientsPicker::~RecipientsPicker()
{
    writeConfig();
}

void RecipientsPicker::slotSelectionChanged()
{
    const bool hasSelection = !mView->emailAddressSelectionWidget()->selectedAddresses().isEmpty();
    mUser1Button->setEnabled(hasSelection);
    mUser2Button->setEnabled(hasSelection);
    mUser3Button->setEnabled(hasSelection);
    mUser4Button->setEnabled(hasSelection);
}

void RecipientsPicker::setRecipients(const Recipient::List &)
{
    mView->view()->selectionModel()->clear();
}

void RecipientsPicker::setDefaultType(Recipient::Type type)
{
    mDefaultType = type;
    mUser1Button->setDefault(type == Recipient::To);
    mUser2Button->setDefault(type == Recipient::Cc);
    mUser3Button->setDefault(type == Recipient::Bcc);
    mUser4Button->setDefault(type == Recipient::ReplyTo);
}

void RecipientsPicker::slotToClicked()
{
    pick(Recipient::To);
}

void RecipientsPicker::slotReplyToClicked()
{
    pick(Recipient::ReplyTo);
}

void RecipientsPicker::slotCcClicked()
{
    pick(Recipient::Cc);
}

void RecipientsPicker::slotBccClicked()
{
    pick(Recipient::Bcc);
}

void RecipientsPicker::slotPicked()
{
    pick(mDefaultType);
}

void RecipientsPicker::pick(Recipient::Type type)
{
    qCDebug(MESSAGECOMPOSER_LOG) << int(type);

    const Akonadi::EmailAddressSelection::List selections = mView->emailAddressSelectionWidget()->selectedAddresses();

    const int count = selections.count();
    if (count == 0) {
        return;
    }

    if (count > MessageComposerSettings::self()->maximumRecipients()) {
        KMessageBox::sorry(this,
                           i18np("You selected 1 recipient. The maximum supported number of "
                                 "recipients is %2. Please adapt the selection.",
                                 "You selected %1 recipients. The maximum supported number of "
                                 "recipients is %2. Please adapt the selection.", count,
                                 MessageComposerSettings::self()->maximumRecipients()));
        return;
    }

    bool tooManyAddress = false;
    for (const Akonadi::EmailAddressSelection &selection : selections) {
        Recipient recipient;
        recipient.setType(type);
        recipient.setEmail(selection.quotedEmail());

        Q_EMIT pickedRecipient(recipient, tooManyAddress);
        if (tooManyAddress) {
            break;
        }
    }
}

void RecipientsPicker::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape) {
        close();
    }

    QDialog::keyPressEvent(event);
}

void RecipientsPicker::readConfig()
{
    KSharedConfig::Ptr cfg = KSharedConfig::openConfig();
    KConfigGroup group(cfg, "RecipientsPicker");
    QSize size = group.readEntry("Size", QSize());
    if (!size.isEmpty()) {
        resize(size);
    }
}

void RecipientsPicker::writeConfig()
{
    KSharedConfig::Ptr cfg = KSharedConfig::openConfig();
    KConfigGroup group(cfg, "RecipientsPicker");
    group.writeEntry("Size", size());
}

void RecipientsPicker::slotSearchLDAP()
{
    if (!mLdapSearchDialog) {
        mLdapSearchDialog = new KLDAP::LdapSearchDialog(this);
        connect(mLdapSearchDialog, &KLDAP::LdapSearchDialog::contactsAdded, this, &RecipientsPicker::ldapSearchResult);
    }

    mLdapSearchDialog->setSearchText(mView->emailAddressSelectionWidget()->searchLineEdit()->text());
    mLdapSearchDialog->show();
}

void RecipientsPicker::ldapSearchResult()
{
    const KContacts::Addressee::List contacts = mLdapSearchDialog->selectedContacts();
    for (const KContacts::Addressee &contact : contacts) {
        bool tooManyAddress = false;
        Q_EMIT pickedRecipient(Recipient(contact.fullEmail(), Recipient::Undefined), tooManyAddress);
        if (tooManyAddress) {
            break;
        }
    }
}
