import { colors, log } from "../../../deps.js";
import { deepEqual, selectRepository } from "../../utils/utils.js";
import { DEFAULT_SYNC_OPTIONS } from "../../core/conf.js";
import { GIT_SYNC_FIELDS } from "./types.js";
import { GitSyncSettingsConverter } from "./converter.js";
// Helper for consistent output handling between JSON and regular modes
export function outputResult(opts, result) {
    if (opts.jsonOutput) {
        console.log(JSON.stringify(result));
    }
    else if (result.success && result.message) {
        log.info(colors.green(result.message));
    }
    else if (!result.success && result.error) {
        log.error(colors.red(result.error));
    }
}
// Helper to normalize repository path by removing $res: prefix
export function normalizeRepoPath(path) {
    return path.replace(/^\$res:/, "");
}
// Helper to get or create branch configuration
export function getOrCreateBranchConfig(config, branchName) {
    if (!config.gitBranches) {
        config.gitBranches = {};
    }
    if (!config.gitBranches[branchName]) {
        config.gitBranches[branchName] = {};
    }
    return {
        config,
        branchKey: branchName
    };
}
// Helper to apply backend settings to branch configuration
export function applyBackendSettingsToBranch(config, branchName, backendSettings) {
    const { config: updatedConfig } = getOrCreateBranchConfig(config, branchName);
    // Get the base settings (top-level + defaults) to compare against
    const { gitBranches, ...topLevelSettings } = config;
    const baseSettings = { ...DEFAULT_SYNC_OPTIONS, ...topLevelSettings };
    // Only store fields that differ from the base settings
    Object.keys(backendSettings).forEach(key => {
        if (key !== 'gitBranches' && backendSettings[key] !== undefined) {
            const backendValue = backendSettings[key];
            const baseValue = baseSettings[key];
            // Only store if different from base
            const isDifferent = GitSyncSettingsConverter.isDifferent(backendValue, baseValue);
            if (isDifferent) {
                if (!updatedConfig.gitBranches[branchName].overrides) {
                    updatedConfig.gitBranches[branchName].overrides = {};
                }
                updatedConfig.gitBranches[branchName].overrides[key] = backendValue;
            }
        }
    });
    return updatedConfig;
}
// Select repository interactively if multiple exist
export async function selectAndLogRepository(repositories, repository, suppressLogs) {
    let selectedRepo;
    if (repository) {
        const found = repositories.find((r) => r.git_repo_resource_path === repository ||
            r.git_repo_resource_path === `$res:${repository}`);
        if (!found) {
            throw new Error(`Repository ${repository} not found`);
        }
        selectedRepo = found;
        const repoPath = selectedRepo.git_repo_resource_path.replace(/^\$res:/, "");
        if (!suppressLogs) {
            log.info(colors.cyan(`Using repository: ${colors.bold(repoPath)}`));
        }
    }
    else {
        selectedRepo = await selectRepository(repositories);
    }
    return selectedRepo;
}
// Generate structured diff showing field changes
export function generateStructuredDiff(current, backend) {
    const diff = {};
    // Get all unique keys from both objects
    const allKeys = new Set([...Object.keys(current), ...Object.keys(backend)]);
    for (const key of allKeys) {
        const currentValue = current[key];
        const backendValue = backend[key];
        if (!deepEqual(currentValue, backendValue)) {
            diff[key] = {
                from: currentValue,
                to: backendValue,
            };
        }
    }
    return diff;
}
// Helper to generate changes between two SyncOptions objects (normalizes automatically)
export function generateChanges(current, new_) {
    const changes = {};
    // Normalize both inputs for consistent comparison
    const normalizedCurrent = GitSyncSettingsConverter.normalize(current);
    const normalizedNew = GitSyncSettingsConverter.normalize(new_);
    for (const field of GIT_SYNC_FIELDS) {
        const currentValue = normalizedCurrent[field];
        const newValue = normalizedNew[field];
        if (!deepEqual(currentValue, newValue)) {
            changes[field] = {
                from: currentValue,
                to: newValue,
            };
        }
    }
    return changes;
}
// Helper to display changes in human-readable format
export function displayChanges(changes) {
    for (const [field, change] of Object.entries(changes)) {
        if (Array.isArray(change.from) ||
            Array.isArray(change.to)) {
            console.log(colors.yellow(`  ${field}:`));
            console.log(colors.red(`    - ${JSON.stringify(change.from)}`));
            console.log(colors.green(`    + ${JSON.stringify(change.to)}`));
        }
        else {
            console.log(colors.yellow(`  ${field}: `) +
                colors.red(`${change.from}`) +
                " → " +
                colors.green(`${change.to}`));
        }
    }
}
