"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var PdfService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.PdfService = void 0;
const common_1 = require("@nestjs/common");
const config_1 = require("@nestjs/config");
const setting_service_1 = require("../setting/setting.service");
const hcode_institutional_template_1 = require("./templates/hcode-institutional.template");
const hcode_theme_1 = require("./themes/hcode.theme");
// ─────────────────────────────────────────────────────────────────────────────
// Service
// ─────────────────────────────────────────────────────────────────────────────
let PdfService = PdfService_1 = class PdfService {
    constructor(settingService, configService) {
        this.settingService = settingService;
        this.configService = configService;
        this.logger = new common_1.Logger(PdfService_1.name);
    }
    // ── Theme config ─────────────────────────────────────────────────────────
    /**
     * Resolves the active PdfThemeConfig for the given area.
     * Reads admin-configured overrides from SettingService and falls back to
     * the hard-coded Design System v1.0 defaults.
     */
    async loadThemeConfig(area = 'consulting') {
        const defaults = hcode_theme_1.HCODE_DEFAULTS[area];
        try {
            const values = await this.settingService.getSettingValues([
                'pdf-company-name',
                'pdf-logo',
                `pdf-${area}-color`,
                'theme-primary-light', // system-wide brand color
                'image-url', // system logo
                'system-name', // system display name fallback
            ]);
            // Color priority:
            //   1. pdf-${area}-color if admin explicitly changed it from the DS default
            //   2. theme-primary-light (global brand color configured in Settings)
            //   3. DS hard-coded default for the area
            const areaSpecificColor = values[`pdf-${area}-color`];
            const primaryColor = (areaSpecificColor && areaSpecificColor !== defaults.primary)
                ? areaSpecificColor
                : values['theme-primary-light'] || defaults.primary;
            const areaDefault = primaryColor === defaults.primary
                ? defaults
                : Object.assign(Object.assign({}, defaults), { primary: primaryColor });
            // Use pdf-logo if set, otherwise fall back to the system image-url setting.
            // Relative paths (e.g. /logo.svg) are resolved to absolute so Playwright can fetch them.
            const rawLogoUrl = values['pdf-logo'] ||
                values['image-url'] ||
                '';
            const logoOverride = rawLogoUrl ? this.resolveUrl(rawLogoUrl) : '';
            return {
                area,
                companyName: values['pdf-company-name'] ||
                    values['system-name'] ||
                    'hcode',
                logoOverride,
                primaryColor: areaDefault.primary,
                darkColor: areaDefault.dark,
                lightColor: areaDefault.light,
            };
        }
        catch (_a) {
            this.logger.warn(`Could not load PDF settings from SettingService – using Design System defaults for area "${area}".`);
            return {
                area,
                companyName: 'hcode',
                logoOverride: '',
                primaryColor: defaults.primary,
                darkColor: defaults.dark,
                lightColor: defaults.light,
            };
        }
    }
    /**
     * Resolves a potentially relative URL (e.g. /logo.svg) to an absolute URL
     * using the API base URL derived from environment variables.
     */
    resolveUrl(url) {
        var _a, _b;
        if (!url)
            return '';
        if (url.startsWith('data:') ||
            url.startsWith('http://') ||
            url.startsWith('https://')) {
            return url;
        }
        const port = (_a = this.configService.get('PORT')) !== null && _a !== void 0 ? _a : 3100;
        const baseUrl = (_b = this.configService.get('API_URL')) !== null && _b !== void 0 ? _b : `http://localhost:${port}`;
        return (baseUrl.replace(/\/$/, '') +
            (url.startsWith('/') ? url : '/' + url));
    }
    // ── HTML → PDF ────────────────────────────────────────────────────────────
    /**
     * Renders an HTML string to a PDF buffer using Playwright/Chromium.
     *
     * Uses dynamic `import()` via `new Function` to remain compatible with
     * CommonJS bundle output (same pattern as operations.service.ts).
     */
    async generatePdfFromHtml(html, options = {}) {
        var _a, _b, _c, _d, _e;
        const executablePath = this.configService.get('CHROMIUM_EXECUTABLE_PATH');
        const noSandbox = this.configService.get('CHROMIUM_NO_SANDBOX') === 'true';
        const launchArgs = noSandbox
            ? ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage']
            : [];
        let browser = null;
        try {
            const importPlaywright = new Function('moduleName', 'return import(moduleName);');
            const playwright = await importPlaywright('playwright');
            browser = await playwright.chromium.launch(Object.assign(Object.assign({ headless: true }, (executablePath ? { executablePath } : {})), { args: launchArgs }));
            const page = await browser.newPage();
            // A4 viewport for proper page layout
            await page.setViewportSize({ width: 794, height: 1123 });
            await page.setContent(html, { waitUntil: 'networkidle' });
            const pdfBuffer = await page.pdf({
                format: (_a = options.format) !== null && _a !== void 0 ? _a : 'A4',
                printBackground: (_b = options.printBackground) !== null && _b !== void 0 ? _b : true,
                landscape: (_c = options.landscape) !== null && _c !== void 0 ? _c : false,
                margin: (_d = options.margin) !== null && _d !== void 0 ? _d : { top: '0', right: '0', bottom: '0', left: '0' },
            });
            return Buffer.from(pdfBuffer);
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            const errorStack = error instanceof Error ? ((_e = error.stack) !== null && _e !== void 0 ? _e : errorMessage) : String(error);
            const missingRuntime = /Cannot find package ['"]playwright['"]|Cannot find module ['"]playwright['"]|Executable doesn't exist|browserType\.launch|Failed to launch|Please run the following command/i.test(errorMessage);
            this.logger.error(`PDF generation failed. ${errorMessage}`, errorStack);
            if (missingRuntime) {
                throw new common_1.InternalServerErrorException('Playwright runtime is not available. Run `pnpm --filter api run playwright:install` in the API environment.');
            }
            throw new common_1.InternalServerErrorException(`PDF generation failed: ${errorMessage}`);
        }
        finally {
            if (browser) {
                try {
                    await browser.close();
                }
                catch (_f) {
                    // Ignore close errors
                }
            }
        }
    }
    // ── Template engine ───────────────────────────────────────────────────────
    /**
     * Generates a PDF from a named template and structured data.
     * The theme is resolved automatically from `data.area` via SettingService.
     */
    async generatePdfFromTemplate(templateName, data, options) {
        var _a;
        const area = (_a = data.area) !== null && _a !== void 0 ? _a : 'consulting';
        const themeConfig = await this.loadThemeConfig(area);
        let html;
        switch (templateName) {
            case 'hcode-institutional':
                html = (0, hcode_institutional_template_1.hcodeInstitutionalTemplate)(data, themeConfig);
                break;
            default:
                throw new common_1.InternalServerErrorException(`Unknown PDF template: "${templateName}". Available: hcode-institutional`);
        }
        return this.generatePdfFromHtml(html, options);
    }
};
exports.PdfService = PdfService;
exports.PdfService = PdfService = PdfService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => setting_service_1.SettingService))),
    __metadata("design:paramtypes", [setting_service_1.SettingService,
        config_1.ConfigService])
], PdfService);
//# sourceMappingURL=pdf.service.js.map