// ProfilesSection.cpp — profile selector for multi-account / multi-env workflows.

#include "screens/settings/ProfilesSection.h"

#include "core/config/ProfileManager.h"
#include "screens/settings/SettingsRowHelpers.h"
#include "screens/settings/SettingsStyles.h"
#include "ui/theme/Theme.h"

#include <QCoreApplication>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QProcess>
#include <QPushButton>
#include <QRegularExpression>
#include <QScrollArea>
#include <QString>
#include <QStringList>
#include <QVBoxLayout>

namespace fincept::screens {

ProfilesSection::ProfilesSection(QWidget* parent) : QWidget(parent) {
    build_ui();
}

void ProfilesSection::build_ui() {
    host_layout_ = new QVBoxLayout(this);
    host_layout_->setContentsMargins(0, 0, 0, 0);
    host_layout_->setSpacing(0);
    rebuild();
}

void ProfilesSection::rebuild() {
    if (content_) {
        host_layout_->removeWidget(content_);
        content_->deleteLater();
    }
    content_ = build_content();
    host_layout_->addWidget(content_);
}

void ProfilesSection::changeEvent(QEvent* event) {
    if (event->type() == QEvent::LanguageChange)
        rebuild(); // re-runs every tr() lookup in build_content()
    QWidget::changeEvent(event);
}

QWidget* ProfilesSection::build_content() {
    using namespace settings_styles;
    using namespace settings_helpers;

    auto* scroll = new QScrollArea;
    scroll->setWidgetResizable(true);
    scroll->setFrameShape(QFrame::NoFrame);

    auto* page = new QWidget(this);
    auto* vl = new QVBoxLayout(page);
    vl->setContentsMargins(24, 20, 24, 20);
    vl->setSpacing(16);

    auto* title = new QLabel(tr("Profiles"));
    title->setStyleSheet(section_title_ss());
    vl->addWidget(title);

    auto* desc = new QLabel(tr("Each profile has its own isolated database, credentials, logs and workspaces.\n"
                               "Launch the terminal with  --profile <name>  to open a specific profile.\n"
                               "Different profiles can run simultaneously — useful for separate trading accounts."));
    desc->setWordWrap(true);
    desc->setStyleSheet(label_ss());
    vl->addWidget(desc);
    vl->addWidget(make_sep());

    auto& pm = ProfileManager::instance();
    auto* active_lbl = new QLabel(tr("Active profile:  <b>%1</b>").arg(pm.active()));
    active_lbl->setStyleSheet(label_ss());
    vl->addWidget(active_lbl);

    auto* list_title = new QLabel(tr("All profiles"));
    list_title->setStyleSheet(sub_title_ss());
    vl->addWidget(list_title);

    auto* list_widget = new QWidget(this);
    auto* list_vl = new QVBoxLayout(list_widget);
    list_vl->setContentsMargins(0, 0, 0, 0);
    list_vl->setSpacing(6);

    const QStringList profiles = pm.list_profiles();
    for (const QString& name : profiles) {
        auto* row = new QWidget(this);
        auto* hl = new QHBoxLayout(row);
        hl->setContentsMargins(0, 0, 0, 0);
        hl->setSpacing(8);

        auto* name_lbl = new QLabel(name);
        name_lbl->setStyleSheet(label_ss());
        hl->addWidget(name_lbl, 1);

        if (name == pm.active()) {
            auto* badge = new QLabel(tr("ACTIVE"));
            badge->setStyleSheet(
                QString("color:%1;font-weight:700;font-size:10px;background:transparent;").arg(ui::colors::AMBER()));
            hl->addWidget(badge);
        } else {
            auto* switch_btn = new QPushButton(tr("Switch"));
            switch_btn->setFixedWidth(72);
            switch_btn->setStyleSheet(btn_secondary_ss());
            switch_btn->setAccessibleName(tr("Switch to profile %1").arg(name));
            connect(switch_btn, &QPushButton::clicked, this, [this, name]() {
                // Switching relaunches the process and quits this one. That is
                // as destructive as closing the terminal, and it used to happen
                // on a single unconfirmed click.
                const auto reply = QMessageBox::question(
                    this, tr("Switch Profile"),
                    tr("Switch to profile \"%1\"?\n\nFincept Terminal will restart. Unsaved work in the "
                       "current session may be lost.")
                        .arg(name),
                    QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
                if (reply != QMessageBox::Yes)
                    return;
                const QString exe = QCoreApplication::applicationFilePath();
                QProcess::startDetached(exe, {"--profile", name});
                QCoreApplication::quit();
            });
            hl->addWidget(switch_btn);
        }
        list_vl->addWidget(row);
    }
    vl->addWidget(list_widget);
    vl->addWidget(make_sep());

    auto* new_title = new QLabel(tr("Create new profile"));
    new_title->setStyleSheet(sub_title_ss());
    vl->addWidget(new_title);

    auto* new_row = new QWidget(this);
    auto* new_hl = new QHBoxLayout(new_row);
    new_hl->setContentsMargins(0, 0, 0, 0);
    new_hl->setSpacing(8);

    auto* name_input = new QLineEdit;
    name_input->setPlaceholderText(tr("profile-name  (alphanumeric, - and _ only)"));
    name_input->setStyleSheet(input_ss());
    name_input->setMaxLength(32);
    name_input->setAccessibleName(tr("New profile name"));
    new_hl->addWidget(name_input, 1);

    auto* create_btn = new QPushButton(tr("Create & Switch"));
    create_btn->setStyleSheet(btn_primary_ss());
    create_btn->setAccessibleName(tr("Create profile and switch to it"));
    connect(name_input, &QLineEdit::returnPressed, create_btn, &QPushButton::click);
    connect(create_btn, &QPushButton::clicked, this, [this, name_input]() {
        const QString name = name_input->text().trimmed().toLower();
        // The placeholder advertised a character set that nothing enforced.
        // ProfileManager sanitises the name before using it as a directory, so
        // an unsanitised value silently landed the user in a *differently
        // named* profile than the one they typed.
        static const QRegularExpression kValidName(QStringLiteral("^[a-z0-9_-]{1,32}$"));
        if (name.isEmpty() || !kValidName.match(name).hasMatch()) {
            QMessageBox::warning(this, tr("Invalid Profile Name"),
                                 tr("Use 1-32 characters: lowercase letters, digits, hyphen or underscore."));
            return;
        }
        if (ProfileManager::instance().list_profiles().contains(name)) {
            QMessageBox::warning(this, tr("Profile Exists"), tr("A profile named \"%1\" already exists.").arg(name));
            return;
        }
        const auto reply =
            QMessageBox::question(this, tr("Create Profile"),
                                  tr("Create profile \"%1\" and switch to it?\n\nFincept Terminal will restart. "
                                     "Unsaved work in the current session may be lost.")
                                      .arg(name),
                                  QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
        if (reply != QMessageBox::Yes)
            return;

        ProfileManager::instance().create_profile(name);
        const QString exe = QCoreApplication::applicationFilePath();
        QProcess::startDetached(exe, {"--profile", name});
        QCoreApplication::quit();
    });
    new_hl->addWidget(create_btn);
    vl->addWidget(new_row);

    auto* hint = new QLabel(tr("Creating a profile sets up a fresh data directory. "
                               "The app will restart with the new profile active."));
    hint->setWordWrap(true);
    hint->setStyleSheet(label_ss());
    vl->addWidget(hint);

    vl->addStretch();
    scroll->setWidget(page);
    return scroll;
}

} // namespace fincept::screens
