import sys

filename = 'mainmainwindow.cpp'
with open(filename, 'r') as f:
    lines = f.readlines()

# 1. Modify onFolderSelected function
# Find the start of onFolderSelected
on_folder_start = None
for i, line in enumerate(lines):
    if line.strip().startswith('void MainMainWindow::onFolderSelected(const QModelIndex &index)'):
        on_folder_start = i
        break
if on_folder_start is None:
    print('Could not find onFolderSelected')
    sys.exit(1)

# Find the end of the function (look for a line that is just '}' after the function start)
# We'll assume the function ends at the next line that starts with 'void ' or '}' at indentation 0? Safer: find the matching brace.
brace_count = 0
in_function = False
on_folder_end = None
for i in range(on_folder_start, len(lines)):
    line = lines[i]
    for ch in line:
        if ch == '{':
            brace_count += 1
            in_function = True
        elif ch == '}':
            brace_count -= 1
            if brace_count == 0 and in_function:
                on_folder_end = i
                break
    if on_folder_end is not None:
        break
if on_folder_end is None:
    print('Could not find end of onFolderSelected')
    sys.exit(1)

# Now we need to replace the content between on_folder_start+1 and on_folder_end with new implementation.
# Let's first extract the current function to see what we have.
# We'll replace from line after the opening brace? Actually we want to keep the signature and the opening brace.
# We'll replace lines from on_folder_start+1 to on_folder_end-1 with new body.
# But we need to keep the opening brace line (which is at on_folder_start? Actually the signature line is on_folder_start, the opening brace is on the same line or next?
# Look at the signature line: it ends with '{'? Let's check.

# Let's just replace the whole block from on_folder_start to on_folder_end with new function.
new_on_folder = '''void MainMainWindow::onFolderSelected(const QModelIndex &index)
{
    if (!index.isValid()) return;

    int itemType = index.data(FolderListModel::ItemTypeRole).toInt();
    if (itemType == FolderTreeItem::FolderNode) {
        m_currentFolderId = index.data(FolderListModel::FolderIdRole).toInt();
        m_emailModel->setFolderId(m_currentFolderId);
        // Fetch mails for this folder
        std::optional<Folder> optFolder = FolderDao::findById(m_currentFolderId);
        if (optFolder.has_value()) {
            Folder folder = optFolder.value();
            Account* account = m_accountService->findAccountById(folder.accountId());
            if (account) {
                QString accountId = QString::number(account->id());
                QString folderId = QString::number(m_currentFolderId);
                // Fetch mails asynchronously to avoid blocking UI
                QMetaObject::invokeMethod(m_mailService, "fetchMails", Qt::QueuedConnection,
                    Q_ARG(QString, accountId), Q_ARG(QString, folderId));
            }
        }
    } else if (itemType == FolderTreeItem::AccountNode) {
        // When an account node is selected, select its first folder (if any)
        int childCount = m_folderModel->rowCount(index);
        if (childCount > 0) {
            QModelIndex firstChildIdx = m_folderModel->index(0, 0, index);
            m_folderTree->setCurrentIndex(firstChildIdx);
            onFolderSelected(firstChildIdx); // recursive call to handle folder selection
        } else {
            // No folders yet; clear email list
            m_currentFolderId = -1;
            m_emailModel->setFolderId(m_currentFolderId);
            m_emailModel->refresh();
        }
    }
}
'''

# Replace lines
lines = lines[:on_folder_start] + [new_on_folder] + lines[on_folder_end+1:]

# 2. Modify syncAction slot
# Find the createToolBox function? Actually we need to find the connect(syncAction, ...) line.
# Let's search for 'connect(syncAction, &QAction::triggered'
sync_connect_line = None
for i, line in enumerate(lines):
    if 'connect(syncAction, &QAction::triggered' in line:
        sync_connect_line = i
        break
if sync_connect_line is None:
    print('Could not find syncAction connect')
    sys.exit(1)

# Find the end of that lambda (the matching '});' after that line)
brace_count = 0
in_lambda = False
sync_end = None
for i in range(sync_connect_line, len(lines)):
    line = lines[i]
    for ch in line:
        if ch == '{':
            brace_count += 1
            in_lambda = True
        elif ch == '}':
            brace_count -= 1
            if brace_count == 0 and in_lambda:
                # Check if the line contains '});' (the end of the lambda)
                if '});' in line:
                    sync_end = i
                    break
    if sync_end is not None:
        break
if sync_end is None:
    print('Could not find end of syncAction lambda')
    sys.exit(1)

# Replace the lambda body with new implementation
new_sync_lambda = '''    connect(syncAction, &QAction::triggered, [this]() {
        if (m_currentFolderId >= 0) {
            statusBar()->showMessage(tr(\"Syncing...\"), 0); // 0 means until cleared
            std::optional<Folder> optFolder = FolderDao::findById(m_currentFolderId);
            if (optFolder.has_value()) {
                Folder folder = optFolder.value();
                Account* account = m_accountService->findAccountById(folder.accountId());
                if (account) {
                    QString accountId = QString::number(account->id());
                    QString folderId = QString::number(m_currentFolderId);
                    // Disconnect previous connections to avoid multiple slots? We'll just call directly via queued connection.
                    QMetaObject::invokeMethod(m_mailService, \"fetchMails\", Qt::QueuedConnection,
                        Q_ARG(QString, accountId), Q_ARG(QString, folderId));
                }
            }
        }
    });'''

# Replace lines from sync_connect_line to sync_end inclusive
lines = lines[:sync_connect_line] + [new_sync_lambda] + lines[sync_end+1:]

# 3. Update mailFetched and mailFetchError lambdas in connectModels
# Find the connectModels function
connect_models_start = None
for i, line in enumerate(lines):
    if line.strip().startswith('void MainMainWindow::connectModels()'):
        connect_models_start = i
        break
if connect_models_start is None:
    print('Could not find connectModels')
    sys.exit(1)

# Find end of connectModels
brace_count = 0
in_func = False
connect_models_end = None
for i in range(connect_models_start, len(lines)):
    line = lines[i]
    for ch in line:
        if ch == '{':
            brace_count += 1
            in_func = True
        elif ch == '}':
            brace_count -= 1
            if brace_count == 0 and in_func:
                connect_models_end = i
                break
    if connect_models_end is not None:
        break
if connect_models_end is None:
    print('Could not find end of connectModels')
    sys.exit(1)

# Within this function, we need to find the two lambdas: mailFetched and mailFetchError.
# We'll replace the whole function with a new version? That's risky.
# Instead, we'll replace the specific lambda bodies.
# Let's find the line numbers for the mailFetched connect and mailFetchError connect.
mail_fetched_line = None
mail_fetch_error_line = None
for i in range(connect_models_start, connect_models_end+1):
    if 'connect(m_mailService, &MailService::mailFetched' in lines[i]:
        mail_fetched_line = i
    if 'connect(m_mailService, &MailService::mailFetchError' in lines[i]:
        mail_fetch_error_line = i

# For each, find the end of the lambda (the '});' line)
def find_lambda_end(start_line):
    brace_count = 0
    in_lambda = False
    for i in range(start_line, len(lines)):
        line = lines[i]
        for ch in line:
            if ch == '{':
                brace_count += 1
                in_lambda = True
            elif ch == '}':
                brace_count -= 1
                if brace_count == 0 and in_lambda:
                    # Check if line ends with '});'
                    if '});' in line:
                        return i
    return None

mfe_end = None
mfer_end = None
if mail_fetched_line is not None:
    mfe_end = find_lambda_end(mail_fetched_line)
if mail_fetch_error_line is not None:
    mfer_end = find_lambda_end(mail_fetch_error_line)

if mfe_end is None or mfer_end is None:
    print('Could not find lambda ends')
    sys.exit(1)

# New lambda bodies
new_mfe_lambda = '''    connect(m_mailService, &MailService::mailFetched, this, [this](const QString &accountId, const QString &folderId, const QVector<MailItem> &items) {
        int fid = folderId.toInt();
        if (m_currentFolderId == fid || m_currentFolderId == -1) {
            m_emailModel->refresh();
        }
        statusBar()->showMessage(tr(\"Synced %1 message(s)\").arg(items.size()), 3000);
    });'''

new_mfer_lambda = '''    connect(m_mailService, &MailService::mailFetchError, this, [this](const QString &accountId, const QString &folderId, const QString &error) {
        qWarning() << \"[MailFetchError]\" << error;
        statusBar()->showMessage(tr(\"Error fetching mail: %1\").arg(error), 5000);
    });'''

# Replace the lambdas
lines = lines[:mail_fetched_line] + [new_mfe_lambda] + lines[mfe_end+1:mail_fetch_error_line] + [new_mfer_lambda] + lines[mfer_end+1:]

# Write back
with open(filename, 'w') as f:
    f.writelines(lines)

print('Updated mainmainwindow.cpp')
