/**
 * White-label theming system for the Oversight Command Center.
 *
 * Enables per-tenant branding customization: logo, colors, domain,
 * company name, and custom CSS. Themes are stored per-tenant and
 * resolved at render time.
 *
 * @connexum/ai-governance
 */
import * as fs from 'fs';
import * as path from 'path';
const DEFAULT_THEME = {
    primaryColor: '#1a56db',
    secondaryColor: '#6b7280',
    accentColor: '#dc2626',
    backgroundColor: '#f9fafb',
    textColor: '#111827',
};
export class ThemeStore {
    themes = new Map();
    themeDir;
    constructor(config) {
        this.themeDir = config.themeDir;
        this.ensureDir(this.themeDir);
        this.loadThemes();
    }
    /**
     * Set or update a tenant's theme.
     */
    setTheme(config) {
        if (!config.tenantId || !config.companyName) {
            throw new Error('tenantId and companyName are required');
        }
        if (config.primaryColor && !this.isValidHex(config.primaryColor)) {
            throw new Error(`Invalid primaryColor hex: ${config.primaryColor}`);
        }
        const theme = { ...DEFAULT_THEME, ...config };
        this.themes.set(theme.tenantId, theme);
        this.saveTheme(theme);
        return this.resolveTheme(theme);
    }
    /**
     * Get a tenant's resolved theme.
     */
    getTheme(tenantId) {
        const config = this.themes.get(tenantId);
        if (!config)
            return null;
        return this.resolveTheme(config);
    }
    /**
     * Delete a tenant's theme.
     */
    deleteTheme(tenantId) {
        const existed = this.themes.delete(tenantId);
        if (existed) {
            const filePath = path.join(this.themeDir, `${tenantId}.json`);
            if (fs.existsSync(filePath)) {
                fs.unlinkSync(filePath);
            }
        }
        return existed;
    }
    /**
     * List all registered themes.
     */
    listThemes() {
        return Array.from(this.themes.values());
    }
    /**
     * Get a default theme for unbranded tenants.
     */
    getDefaultTheme(tenantId, companyName) {
        return this.resolveTheme({
            tenantId,
            companyName,
            ...DEFAULT_THEME,
            primaryColor: DEFAULT_THEME.primaryColor,
        });
    }
    /**
     * Get the number of stored themes.
     */
    get themeCount() {
        return this.themes.size;
    }
    // ---- Private helpers ----
    resolveTheme(config) {
        const cssVariables = {
            '--gov-primary': config.primaryColor,
            '--gov-secondary': config.secondaryColor || DEFAULT_THEME.secondaryColor,
            '--gov-accent': config.accentColor || DEFAULT_THEME.accentColor,
            '--gov-bg': config.backgroundColor || DEFAULT_THEME.backgroundColor,
            '--gov-text': config.textColor || DEFAULT_THEME.textColor,
        };
        const variablesCss = Object.entries(cssVariables)
            .map(([k, v]) => `  ${k}: ${v};`)
            .join('\n');
        const css = `:root {\n${variablesCss}\n}${config.customCss ? '\n' + config.customCss : ''}`;
        return {
            ...config,
            cssVariables,
            css,
        };
    }
    isValidHex(color) {
        return /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(color);
    }
    saveTheme(config) {
        const filePath = path.join(this.themeDir, `${config.tenantId}.json`);
        fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
    }
    loadThemes() {
        if (!fs.existsSync(this.themeDir))
            return;
        const files = fs.readdirSync(this.themeDir).filter(f => f.endsWith('.json'));
        for (const file of files) {
            try {
                const data = JSON.parse(fs.readFileSync(path.join(this.themeDir, file), 'utf-8'));
                if (data.tenantId) {
                    this.themes.set(data.tenantId, data);
                }
            }
            catch {
                // Skip corrupted theme files
            }
        }
    }
    ensureDir(dir) {
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
    }
}
//# sourceMappingURL=theme.js.map