// Squawk messenger. 
// Copyright (C) 2019  Yury Gubich <blue@macaw.me>
// 
// 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/>.

#include "contactcontacts.h"
#include "ui_contactcontacts.h"

UI::ContactContacts::ContactContacts(QWidget* parent):
    QWidget(parent),
    m_ui(new Ui::ContactContacts),
    contextMenu(new QMenu()),
    emails(),
    phones(),
    roleDelegate(new ComboboxDelegate()),
    phoneTypeDelegate(new ComboboxDelegate()),
    editable(false)
{
    m_ui->setupUi(this);

    m_ui->jabberID->setReadOnly(true);

    initializeDelegates();
    initializeViews();
}

UI::ContactContacts::~ContactContacts() {
    contextMenu->deleteLater();
}

void UI::ContactContacts::setVCard(const QString& jid, const Shared::VCard& card, bool p_editable) {
    editable = p_editable;
    m_ui->jabberID->setText(jid);
    m_ui->url->setText(card.getUrl());
    m_ui->url->setReadOnly(!p_editable);

    emails.setEditable(editable);
    phones.setEditable(editable);
    emails.setEmails(card.getEmails());
    phones.setPhones(card.getPhones());
}

void UI::ContactContacts::initializeDelegates() {
    roleDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Email::roleNames[0].toStdString().c_str()));
    roleDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Email::roleNames[1].toStdString().c_str()));
    roleDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Email::roleNames[2].toStdString().c_str()));

    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[0].toStdString().c_str()));
    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[1].toStdString().c_str()));
    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[2].toStdString().c_str()));
    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[3].toStdString().c_str()));
    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[4].toStdString().c_str()));
    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[5].toStdString().c_str()));
    phoneTypeDelegate->addEntry(QCoreApplication::translate("Global", Shared::VCard::Phone::typeNames[6].toStdString().c_str()));
}

void UI::ContactContacts::initializeViews() {
    m_ui->emailsView->setContextMenuPolicy(Qt::CustomContextMenu);
    m_ui->emailsView->setModel(&emails);
    m_ui->emailsView->setItemDelegateForColumn(1, roleDelegate);
    m_ui->emailsView->setColumnWidth(2, 25);
    m_ui->emailsView->horizontalHeader()->setStretchLastSection(false);
    m_ui->emailsView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);

    m_ui->phonesView->setContextMenuPolicy(Qt::CustomContextMenu);
    m_ui->phonesView->setModel(&phones);
    m_ui->phonesView->setItemDelegateForColumn(1, roleDelegate);
    m_ui->phonesView->setItemDelegateForColumn(2, phoneTypeDelegate);
    m_ui->phonesView->setColumnWidth(3, 25);
    m_ui->phonesView->horizontalHeader()->setStretchLastSection(false);
    m_ui->phonesView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);

    connect(m_ui->phonesView, &QWidget::customContextMenuRequested, this, &UI::ContactContacts::onContextMenu);
    connect(m_ui->emailsView, &QWidget::customContextMenuRequested, this, &UI::ContactContacts::onContextMenu);
}

void UI::ContactContacts::onContextMenu(const QPoint& point) {
    contextMenu->clear();
    bool hasMenu = false;
    QAbstractItemView* snd = static_cast<QAbstractItemView*>(sender());
    if (snd == m_ui->emailsView) {
        hasMenu = true;
        if (editable) {
            QAction* add = contextMenu->addAction(Shared::icon("list-add"), tr("Add email address"));
            connect(add, &QAction::triggered, this, &UI::ContactContacts::onAddEmail);

            QItemSelectionModel* sm = m_ui->emailsView->selectionModel();
            int selectionSize = sm->selectedRows().size();

            if (selectionSize > 0) {
                if (selectionSize == 1) {
                    int row = sm->selectedRows().at(0).row();
                    if (emails.isPreferred(row)) {
                        QAction* rev = contextMenu->addAction(Shared::icon("unfavorite"), tr("Unset this email as preferred"));
                        connect(rev, &QAction::triggered, std::bind(&Models::EMails::revertPreferred, &emails, row));
                    } else {
                        QAction* rev = contextMenu->addAction(Shared::icon("favorite"), tr("Set this email as preferred"));
                        connect(rev, &QAction::triggered, std::bind(&Models::EMails::revertPreferred, &emails, row));
                    }
                }

                QAction* del = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove selected email addresses"));
                connect(del, &QAction::triggered, this, &UI::ContactContacts::onRemoveEmail);
            }
        }

        QAction* cp = contextMenu->addAction(Shared::icon("edit-copy"), tr("Copy selected emails to clipboard"));
        connect(cp, &QAction::triggered, this, &UI::ContactContacts::onCopyEmail);
    } else if (snd == m_ui->phonesView) {
        hasMenu = true;
        if (editable) {
            QAction* add = contextMenu->addAction(Shared::icon("list-add"), tr("Add phone number"));
            connect(add, &QAction::triggered, this, &UI::ContactContacts::onAddPhone);

            QItemSelectionModel* sm = m_ui->phonesView->selectionModel();
            int selectionSize = sm->selectedRows().size();

            if (selectionSize > 0) {
                if (selectionSize == 1) {
                    int row = sm->selectedRows().at(0).row();
                    if (phones.isPreferred(row)) {
                        QAction* rev = contextMenu->addAction(Shared::icon("view-media-favorite"), tr("Unset this phone as preferred"));
                        connect(rev, &QAction::triggered, std::bind(&Models::Phones::revertPreferred, &phones, row));
                    } else {
                        QAction* rev = contextMenu->addAction(Shared::icon("favorite"), tr("Set this phone as preferred"));
                        connect(rev, &QAction::triggered, std::bind(&Models::Phones::revertPreferred, &phones, row));
                    }
                }

                QAction* del = contextMenu->addAction(Shared::icon("edit-delete"), tr("Remove selected phone numbers"));
                connect(del, &QAction::triggered, this, &UI::ContactContacts::onRemovePhone);
            }
        }

        QAction* cp = contextMenu->addAction(Shared::icon("edit-copy"), tr("Copy selected phones to clipboard"));
        connect(cp, &QAction::triggered, this, &UI::ContactContacts::onCopyPhone);
    }

    if (hasMenu) {
        contextMenu->popup(snd->viewport()->mapToGlobal(point));
    }
}

void UI::ContactContacts::onAddEmail() {
    QModelIndex index = emails.addNewEmptyLine();
    m_ui->emailsView->setCurrentIndex(index);
    m_ui->emailsView->edit(index);
}

void UI::ContactContacts::onAddAddress() {}     //TODO
void UI::ContactContacts::onAddPhone() {
    QModelIndex index = phones.addNewEmptyLine();
    m_ui->phonesView->setCurrentIndex(index);
    m_ui->phonesView->edit(index);
}
void UI::ContactContacts::onRemoveAddress() {}  //TODO
void UI::ContactContacts::onRemoveEmail() {
    QItemSelection selection(m_ui->emailsView->selectionModel()->selection());

    QList<int> rows;
    for (const QModelIndex& index : selection.indexes()) {
        rows.append(index.row());
    }

    std::sort(rows.begin(), rows.end());

    int prev = -1;
    for (int i = rows.count() - 1; i >= 0; i -= 1) {
        int current = rows[i];
        if (current != prev) {
            emails.removeLines(current, 1);
            prev = current;
        }
    }
}

void UI::ContactContacts::onRemovePhone() {
    QItemSelection selection(m_ui->phonesView->selectionModel()->selection());

    QList<int> rows;
    for (const QModelIndex& index : selection.indexes()) {
        rows.append(index.row());
    }

    std::sort(rows.begin(), rows.end());

    int prev = -1;
    for (int i = rows.count() - 1; i >= 0; i -= 1) {
        int current = rows[i];
        if (current != prev) {
            phones.removeLines(current, 1);
            prev = current;
        }
    }
}

void UI::ContactContacts::onCopyEmail() {
    QList<QModelIndex> selection(m_ui->emailsView->selectionModel()->selectedRows());

    QList<QString> addrs;
    for (const QModelIndex& index : selection) {
        addrs.push_back(emails.getEmail(index.row()));
    }

    QString list = addrs.join("\n");

    QClipboard* cb = QApplication::clipboard();
    cb->setText(list);
}

void UI::ContactContacts::onCopyPhone() {
    QList<QModelIndex> selection(m_ui->phonesView->selectionModel()->selectedRows());

    QList<QString> phs;
    for (const QModelIndex& index : selection) {
        phs.push_back(phones.getPhone(index.row()));
    }

    QString list = phs.join("\n");

    QClipboard* cb = QApplication::clipboard();
    cb->setText(list);
}

QString UI::ContactContacts::title() const {
    return m_ui->contactHeading->text();
}

void UI::ContactContacts::fillVCard(Shared::VCard& card) const {
    card.setUrl(m_ui->url->text());

    emails.getEmails(card.getEmails());
    phones.getPhones(card.getPhones());
}