#include "change-other-user-password-panel.h"
#include "../DialogManager/dialog-manager.h"
#include "../ModalOverlay/modal-overlay-manager.h"
#include "../PasswordLineEdit/password-line-edit.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolTip>

ChangeOtherUserPasswordPanel::ChangeOtherUserPasswordPanel(const QString &username, QWidget *parent)
    : OverlayPanelBase(":/plugin/change-other-user-password-panel.qss", parent), m_username(username)
{
    // Use base containers: contentLayout() and bottomLayout()
    auto *contentLayout = this->contentLayout();
    auto *bottomLayout = this->bottomLayout();
    auto *info = new QLabel(tr("Enter a new password for user: %1").arg(username));
    info->setObjectName("ChangeOtherUserPasswordInfoLabel");
    contentLayout->addWidget(info);

    auto *form = new QFormLayout(); form->setSpacing(12); form->setHorizontalSpacing(16); form->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
    QFont fieldFont; fieldFont.setPixelSize(14); fieldFont.setWeight(QFont::Normal);
    m_newPasswordEdit = new PasswordLineEdit(); m_newPasswordEdit->setPlaceholderText(tr("Enter")); m_newPasswordEdit->setFixedHeight(32); m_newPasswordEdit->setFont(fieldFont);
    form->addRow(tr("New Password"), m_newPasswordEdit);
    contentLayout->addLayout(form);

    // 使用基类创建统一的内联告警行：上下边距0，图标与文本间距6
    this->createInlineErrorRow(form, /*topBottomMargin=*/0, /*iconTextSpacing=*/8);

    auto *btnLayout = new QHBoxLayout(); btnLayout->addStretch();
    m_cancelButton = new DialogButton(tr("Cancel"), DialogButton::Cancel);
    m_confirmButton = new DialogButton(tr("Save"), DialogButton::Confirm); m_confirmButton->setEnabled(false);
    btnLayout->addWidget(m_cancelButton); btnLayout->addWidget(m_confirmButton); bottomLayout->addLayout(btnLayout);


    connect(m_cancelButton, &QToolButton::clicked, this, [this]{
        cleanupProcess();
        emit requestClose();
    });
    connect(m_confirmButton, &QToolButton::clicked, this, &ChangeOtherUserPasswordPanel::onConfirm);
    connect(m_newPasswordEdit, &QLineEdit::textChanged, this, &ChangeOtherUserPasswordPanel::validateInputs);

    form->setLabelAlignment(Qt::AlignRight | Qt::AlignVCenter);
    for (int r=0; r<form->rowCount(); ++r) {
        if (auto *item=form->itemAt(r,QFormLayout::LabelRole)) {
            if (auto *lbl=qobject_cast<QLabel*>(item->widget())) {
                lbl->setMinimumHeight(32); lbl->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
                QFont lf=lbl->font(); lf.setPixelSize(14); lf.setWeight(QFont::Normal); lbl->setFont(lf);
                lbl->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
            }
        }
    }

    m_newPasswordEdit->setFocus();
    // no bubble; using inline error label
}

ChangeOtherUserPasswordPanel::~ChangeOtherUserPasswordPanel() {
    cleanupProcess();
}

void ChangeOtherUserPasswordPanel::validateInputs() {
    m_lastError.clear();
    const QString pwd = m_newPasswordEdit->text();
    bool valid = !pwd.isEmpty() && pwd.length() >= 6;
    QWidget *errorField = nullptr;
    if (!pwd.isEmpty() && pwd.length() < 6) {
        m_lastError = tr("Password must be at least 6 characters.");
        valid = false; errorField = m_newPasswordEdit;
    }
    if (!valid && errorField) {
        showInlineError(m_lastError);
    } else {
        hideInlineError();
    }
    m_confirmButton->setEnabled(valid);
}

void ChangeOtherUserPasswordPanel::setInputsEnabled(bool en) {
    m_newPasswordEdit->setEnabled(en); m_confirmButton->setEnabled(en && m_confirmButton->isEnabled());
}

void ChangeOtherUserPasswordPanel::showPopupError(const QString &title, const QString &msg) {
    // Runtime / process errors: popup only (no inline duplication)
    hideInlineError();
    DialogManager::instance().showError(title, msg, this);
}

void ChangeOtherUserPasswordPanel::showFieldError(QWidget *field, const QString &msg) {
    if (!field) return;
    QPoint pos = field->mapToGlobal(QPoint(field->width()/2, field->height()));
    QToolTip::showText(pos, msg, field);
}

void ChangeOtherUserPasswordPanel::onConfirm() {
    if (!m_confirmButton->isEnabled()) return;
    setInputsEnabled(false);
    cleanupProcess();
    m_finished = false;
    m_process = new QProcess(this);
    connect(m_process, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus status){
        if (m_finished) return; // guard against late signals after finish
        if (status == QProcess::CrashExit) {
            showPopupError(tr("Change Password Failed"), tr("Process crashed"));
            emit passwordChangeFailed(tr("Process crashed"));
            setInputsEnabled(true);
            // Re-run validation to restore confirm button if inputs valid
            validateInputs();
            cleanupProcess();
            return;
        }
        if (exitCode==0) {
            m_finished = true;
            emit passwordChanged(m_username);
            cleanupProcess();
            emit requestClose();
        } else {
            QString err = QString::fromUtf8(m_process->readAllStandardError());
            QString out = QString::fromUtf8(m_process->readAllStandardOutput());
            QString full = (out+"\n"+err).trimmed();
            QString lowered = full.toLower();
            QString normalized;
            if (exitCode == 127 || lowered.contains("not authorized") || lowered.contains("permission")) {
                normalized = tr("Authentication failed");
            } else if (lowered.contains("weak")) {
                normalized = tr("Password too weak");
            } else if (lowered.contains("lock")) {
                normalized = tr("Account is locked");
            } else if (full.isEmpty()) {
                normalized = tr("Failed to change password (exit code %1)").arg(exitCode);
            } else {
                normalized = full;
            }
            QString msg = tr("Failed to change password: %1").arg(normalized);
            showPopupError(tr("Change Password Failed"), msg);
            emit passwordChangeFailed(msg);
            setInputsEnabled(true);
            // Re-enable confirm if password field remains valid
            validateInputs();
            cleanupProcess();
        }
    });
    QStringList args; args << "/usr/sbin/chpasswd"; m_process->start("pkexec", args);
    const QString input = m_username + ":" + m_newPasswordEdit->text() + "\n";
    m_process->write(input.toUtf8()); m_process->closeWriteChannel();
}

void ChangeOtherUserPasswordPanel::cleanupProcess() {
    if (!m_process) return;
    if (m_process->state() != QProcess::NotRunning) {
        m_process->terminate();
        if (!m_process->waitForFinished(150)) {
            m_process->kill();
            m_process->waitForFinished(150);
        }
    }
    m_process->deleteLater();
    m_process = nullptr;
}
