#include "user-list-panel.h"

#include <QFrame>
#include <QLabel>
#include <QFont>
#include <QHBoxLayout>
#include <QPushButton>
#include <QToolButton>
#include <QIcon>
#include <algorithm>

static QFrame* createHLine(QWidget* parent, int len = 0) {
    QFrame* line = new QFrame(parent);
    if (len == 0) {
        line->setMinimumSize(QSize(0, 1));
        line->setMaximumSize(QSize(QWIDGETSIZE_MAX, 1));
    } else {
        line->setMinimumSize(QSize(len, 1));
        line->setMaximumSize(QSize(len, 1));
    }
    line->setLineWidth(0);
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    // 轻量主题色：使用当前调色板的 mid 颜色并降低不透明度
    QColor c = line->palette().color(QPalette::Mid);
    c.setAlphaF(0.35); // 约 35% 透明度，接近上游的细分隔观感
    line->setStyleSheet(QString("background-color: rgba(%1,%2,%3,%4);")
                        .arg(c.red()).arg(c.green()).arg(c.blue()).arg(static_cast<int>(c.alphaF()*255)));
    return line;
}

static QWidget* createHeaderRow(QWidget* parent, bool showActions) {
    auto* w = new QWidget(parent);
    w->setObjectName("UserListHeaderRow");
    auto* lay = new QHBoxLayout(w);
    lay->setContentsMargins(12, 8, 12, 8);
    lay->setSpacing(8);

    auto mkLabel = [](const QString& txt, QWidget* p){
        auto* l = new QLabel(txt, p);
        QFont f = l->font();
        f.setBold(true);
        l->setFont(f);
        l->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
        return l;
    };

    auto* lId = mkLabel(QObject::tr("User ID"), w);
    auto* lUser = mkLabel(QObject::tr("Login"), w);
    auto* lFull = mkLabel(QObject::tr("Full Name"), w);

    // Match row widths proportionally
    lId->setFixedWidth(80);
    lUser->setMinimumWidth(130);
    lFull->setMinimumWidth(130);
    lUser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    lFull->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

    lay->addWidget(lId, 0);
    lay->addWidget(lUser, 1);
    lay->addWidget(lFull, 1);
    // 与数据行顺序保持一致：先添加 stretch，再是操作区域
    lay->addStretch();

    // Only add operations placeholder if actions are shown
    if (showActions) {
        QPushButton tmpPwd(QObject::tr("Change Password"));
        tmpPwd.setObjectName("changePasswordButton");
        QToolButton tmpDel; tmpDel.setIcon(QIcon::fromTheme("list-remove-symbolic", QIcon(QLatin1String(":/plugin/icons/delete.svg"))));
        const QSize szPwd = tmpPwd.sizeHint();
        const QSize szDel = tmpDel.sizeHint();
        const int gap = lay->spacing(); // 行布局两控件之间的间距
        const int opsWidth = szPwd.width() + gap + szDel.width();

        auto* opsPlaceholder = new QWidget(w);
        opsPlaceholder->setFixedWidth(opsWidth);
        opsPlaceholder->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
        lay->addWidget(opsPlaceholder, 0);
    }
    
    return w;
}

UserListPanel::UserListPanel(QWidget* parent)
    : QWidget(parent) {
    setObjectName("UserListPanel");
    auto* outer = new QVBoxLayout(this);
    outer->setContentsMargins(0, 0, 0, 0);
    outer->setSpacing(0);

    auto* container = new QWidget(this);
    m_layout = new QVBoxLayout(container);
    m_layout->setContentsMargins(12, 8, 12, 8);
    m_layout->setSpacing(4);
    m_layout->addStretch();

    outer->addWidget(container);
}

void UserListPanel::ensureHeader() {
    if (!m_layout) return;
    if (!m_header) {
        m_header = createHeaderRow(this, m_currentUserIsAdmin);
        m_layout->insertWidget(0, m_header);
        // 需求变更：表头与第一行之间不显示分隔线（等效于 0px 厚度）
    }
}

void UserListPanel::setUsers(const QList<UserRecord>& users) {
    if (!m_layout) return;

    // remove all except the trailing stretch
    while (m_layout->count() > 1) {
        QLayoutItem* it = m_layout->takeAt(0);
        if (QWidget* w = it->widget()) { w->deleteLater(); }
        delete it;
    }

    // 插入表头
    m_header.clear();
    ensureHeader();

    // Sort users by uid (ascending) to match原有行为
    QList<UserRecord> sortedUsers = users;
    std::sort(sortedUsers.begin(), sortedUsers.end(), [](const UserRecord& a, const UserRecord& b) {
        return a.uid < b.uid;
    });

    for (int i = 0; i < sortedUsers.size(); ++i) {
        const auto& u = sortedUsers.at(i);
        auto* row = new UserRowWidget(u, this, m_currentUserIsAdmin);
        connect(row, &UserRowWidget::changePasswordRequested, this, &UserListPanel::changePasswordRequested);
        connect(row, &UserRowWidget::deleteUserRequested, this, &UserListPanel::deleteUserRequested);
        m_layout->insertWidget(m_layout->count() - 1, row);

        // 非最后一行后面插入分隔线
        if (i != sortedUsers.size() - 1) {
            m_layout->insertWidget(m_layout->count() - 1, createHLine(this));
        }
    }
}

void UserListPanel::updateUser(const UserRecord& user) {
    if (!m_layout) return;
    for (int i = 0; i < m_layout->count(); ++i) {
        if (auto* row = qobject_cast<UserRowWidget*>(m_layout->itemAt(i)->widget())) {
            if (row->data().username == user.username) {
                row->updateData(user);
                break;
            }
        }
    }
}

void UserListPanel::addUser(const UserRecord& user) {
    if (!m_layout) return;
    ensureHeader();

    // De-dup: DBus UserAdded can race with manual refresh (setUsers).
    // If the username already exists, update the row instead of inserting a duplicate.
    for (int i = 0; i < m_layout->count(); ++i) {
        if (auto* row = qobject_cast<UserRowWidget*>(m_layout->itemAt(i)->widget())) {
            if (row->data().username == user.username) {
                row->updateData(user);
                return;
            }
        }
    }

    // Find correct insertion position based on uid (sorted ascending)
    int insertPos = -1;
    for (int i = 0; i < m_layout->count(); ++i) {
        if (auto* row = qobject_cast<UserRowWidget*>(m_layout->itemAt(i)->widget())) {
            int rowUid = row->data().uid;
            if (user.uid < rowUid) {
                // Insert before this row
                insertPos = i;
                break;
            }
        }
    }

    // If no position found, insert at end (before stretch)
    if (insertPos < 0) {
        // Find the stretch index (last item)
        for (int i = m_layout->count() - 1; i >= 0; --i) {
            if (!m_layout->itemAt(i)->widget()) {
                insertPos = i;
                break;
            }
        }
    }

    if (insertPos < 0) return;

    auto isSeparator = [](QWidget* w) {
        if (auto* f = qobject_cast<QFrame*>(w)) {
            return f->frameShape() == QFrame::HLine;
        }
        return false;
    };

    // Check if we need to add separator before this position
    if (insertPos > 0) {
        QWidget* prev = m_layout->itemAt(insertPos - 1)->widget();
        if (prev && qobject_cast<UserRowWidget*>(prev)) {
            // Insert separator before new row
            m_layout->insertWidget(insertPos, createHLine(this));
            ++insertPos;
        }
    }

    // Create and insert the new row
    auto* row = new UserRowWidget(user, this, m_currentUserIsAdmin);
    connect(row, &UserRowWidget::changePasswordRequested, this, &UserListPanel::changePasswordRequested);
    connect(row, &UserRowWidget::deleteUserRequested, this, &UserListPanel::deleteUserRequested);
    m_layout->insertWidget(insertPos, row);

    // Add separator after if next widget is a row
    if (insertPos + 1 < m_layout->count()) {
        QWidget* next = m_layout->itemAt(insertPos + 1)->widget();
        if (next && qobject_cast<UserRowWidget*>(next) && !isSeparator(m_layout->itemAt(insertPos + 1)->widget())) {
            m_layout->insertWidget(insertPos + 1, createHLine(this));
        }
    }
}

void UserListPanel::removeUser(const QString& username) {
    if (!m_layout) return;
    auto isSeparator = [](QWidget* w) {
        if (auto* f = qobject_cast<QFrame*>(w)) {
            return f->frameShape() == QFrame::HLine;
        }
        return false;
    };
    for (int i = 0; i < m_layout->count(); ++i) {
        if (auto* row = qobject_cast<UserRowWidget*>(m_layout->itemAt(i)->widget())) {
            if (row->data().username == username) {
                // Prefer remove the separator right after the row; else remove previous separator
                int after = i + 1;
                if (after < m_layout->count()) {
                    if (QWidget* w = m_layout->itemAt(after)->widget()) {
                        if (isSeparator(w)) { w->deleteLater(); delete m_layout->takeAt(after); }
                    }
                }
                // Remove the row
                row->deleteLater();
                delete m_layout->takeAt(i);

                // If there was no separator after (it was the last row), remove the separator before
                if (after >= m_layout->count()) {
                    int before = i - 1;
                    if (before >= 0) {
                        if (QWidget* w = m_layout->itemAt(before)->widget()) {
                            if (isSeparator(w)) { w->deleteLater(); delete m_layout->takeAt(before); }
                        }
                    }
                }
                break;
            }
        }
    }
}
