import Handlebars from 'handlebars';
import fs from 'fs';
import path from 'path';
import { getTemplateConfig } from './templates/templates.config.js';

// Template cache to avoid re-reading and re-compiling templates
const templateCache = new Map<string, HandlebarsTemplateDelegate>();

/**
 * Get the templates directory path
 */
const getTemplatesDir = (): string => {
    // Use __dirname for CommonJS compatibility
    return path.join(__dirname, 'templates');
};

/**
 * Load and compile a Handlebars template from file
 * @param templateKey - The template key (e.g., 'forgot-password')
 * @returns Compiled Handlebars template
 */
const loadTemplate = (templateKey: string): HandlebarsTemplateDelegate => {
    // Check cache first
    if (templateCache.has(templateKey)) {
        return templateCache.get(templateKey)!;
    }

    const templateConfig = getTemplateConfig(templateKey);
    if (!templateConfig) {
        throw new Error(`Template configuration not found for key: ${templateKey}`);
    }

    const templatesDir = getTemplatesDir();
    const templatePath = path.join(templatesDir, templateConfig.fileName);

    // Check if template file exists
    if (!fs.existsSync(templatePath)) {
        throw new Error(
            `Template file not found: ${templatePath}. Please create ${templateConfig.fileName} in the templates folder.`,
        );
    }

    // Read and compile template
    const templateSource = fs.readFileSync(templatePath, 'utf-8');
    const compiledTemplate = Handlebars.compile(templateSource);

    // Cache the compiled template
    templateCache.set(templateKey, compiledTemplate);

    return compiledTemplate;
};

/**
 * Render an email template with provided parameters
 * @param templateKey - The template key (e.g., 'forgot-password')
 * @param params - Template parameters
 * @returns Object with rendered HTML and subject
 */
export const renderEmailTemplate = (
    templateKey: string,
    params: Record<string, unknown>,
): { html: string; subject: string } => {
    try {
        const templateConfig = getTemplateConfig(templateKey);
        if (!templateConfig) {
            throw new Error(`Template configuration not found for key: ${templateKey}`);
        }

        const template = loadTemplate(templateKey);
        const html = template(params);

        return {
            html,
            subject: templateConfig.subject,
        };
    } catch (error) {
        console.error(`Error rendering template ${templateKey}:`, error);
        throw error;
    }
};

/**
 * Clear the template cache (useful for development/testing)
 */
export const clearTemplateCache = (): void => {
    templateCache.clear();
};

/**
 * Check if a template exists
 * @param templateKey - The template key to check
 * @returns true if template exists
 */
export const templateExists = (templateKey: string): boolean => {
    const templateConfig = getTemplateConfig(templateKey);
    if (!templateConfig) return false;

    const templatesDir = getTemplatesDir();
    const templatePath = path.join(templatesDir, templateConfig.fileName);
    return fs.existsSync(templatePath);
};
