import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import * as Handlebars from 'handlebars';
import * as fs from 'fs/promises';
import * as path from 'path';

/**
 * Checklist email templates — same pattern as NcEmailTemplateService
 * (Handlebars .html files in ./email-templates, compiled once at boot).
 *
 * Uses an ISOLATED Handlebars instance so the partial names never clash
 * with the NC module's "nc-email-header" / "nc-email-footer".
 *
 * ⚠ nest-cli.json "assets" must copy these .html files into dist/
 *   (the existing "**\/*.html" glob used for the NC templates covers it).
 */
@Injectable()
export class ChecklistEmailTemplateService implements OnModuleInit {
  private readonly logger = new Logger(ChecklistEmailTemplateService.name);
  private readonly hb = Handlebars.create();

  private tplReadyClient: HandlebarsTemplateDelegate | null = null;
  private tplUploadedAuditor: HandlebarsTemplateDelegate | null = null;
  private tplSubmittedAuditor: HandlebarsTemplateDelegate | null = null;
  private tplReviewClient: HandlebarsTemplateDelegate | null = null;

  async onModuleInit(): Promise<void> {
    const dir = path.join(__dirname, 'email-templates');
    const read = (f: string) => fs.readFile(path.join(dir, f), 'utf8');

    try {
      const [open, close, header, footer, button, signature, ready, uploaded, submitted, review] =
        await Promise.all([
          read('_layout-open.partial.html'),
          read('_layout-close.partial.html'),
          read('_header.partial.html'),
          read('_footer.partial.html'),
          read('_button.partial.html'),
          read('_signature.partial.html'),
          read('checklist-ready-client.template.html'),
          read('checklist-doc-uploaded-auditor.template.html'),
          read('checklist-submitted-auditor.template.html'),
          read('checklist-review-result-client.template.html'),
        ]);

      this.hb.registerPartial('checklist-email-open', open);
      this.hb.registerPartial('checklist-email-close', close);
      this.hb.registerPartial('checklist-email-header', header);
      this.hb.registerPartial('checklist-email-footer', footer);
      this.hb.registerPartial('checklist-email-button', button);
      this.hb.registerPartial('checklist-email-signature', signature);

      this.tplReadyClient = this.hb.compile(ready);
      this.tplUploadedAuditor = this.hb.compile(uploaded);
      this.tplSubmittedAuditor = this.hb.compile(submitted);
      this.tplReviewClient = this.hb.compile(review);

      this.logger.log('[CHECKLIST-EMAIL-TPL] Templates compiled');
    } catch (err: any) {
      // Don't crash the app — ChecklistsService falls back to its inline HTML.
      this.logger.error(`[CHECKLIST-EMAIL-TPL] Could not load templates from ${dir}: ${err.message}`);
    }
  }

  private year(): number {
    return new Date().getFullYear();
  }

  renderChecklistReadyClient(ctx: {
    recipient_name: string;
    company_name: string;
    audit_code: string;
    standard_name?: string;
    item_count: number;
    due_date?: string | null;
    note?: string | null;
    items?: Array<{ index: number; text: string }>;
    portal_url?: string;
    sender_name?: string | null;
    sender_title?: string | null;
  }): string {
    if (!this.tplReadyClient) throw new Error('Checklist ready (client) template not compiled');
    return this.tplReadyClient({
      ...ctx,
      preheader: `Please provide ${ctx.item_count} document(s) for audit ${ctx.audit_code}.`,
      year: this.year(),
    });
  }

  renderDocUploadedAuditor(ctx: {
    recipient_name: string;
    company_name: string;
    audit_code: string;
    standard_name?: string;
    item_text: string;
    file_name: string;
    uploaded_count: number;
    total_count: number;
    due_date?: string | null;
    workspace_url?: string;
  }): string {
    if (!this.tplUploadedAuditor) throw new Error('Doc uploaded (auditor) template not compiled');
    return this.tplUploadedAuditor({
      ...ctx,
      preheader: `${ctx.company_name} uploaded "${ctx.file_name}" — ${ctx.uploaded_count} of ${ctx.total_count} received.`,
      year: this.year(),
    });
  }

  renderClientSubmittedAuditor(ctx: {
    recipient_name: string;
    company_name: string;
    audit_code: string;
    standard_name?: string;
    item_count: number;
    due_date?: string | null;
    submitted_at: string;
    workspace_url?: string;
  }): string {
    if (!this.tplSubmittedAuditor) throw new Error('Client submitted (auditor) template not compiled');
    return this.tplSubmittedAuditor({
      ...ctx,
      preheader: `${ctx.company_name} has submitted all ${ctx.item_count} document(s) for review.`,
      year: this.year(),
    });
  }

  renderReviewResultClient(ctx: {
    recipient_name: string;
    company_name: string;
    audit_code: string;
    standard_name?: string;
    all_approved: boolean;
    approved_count: number;
    rejected_count: number;
    total_count: number;
    due_date?: string | null;
    rejected?: Array<{ index: number; text: string; note: string | null }>;
    portal_url?: string;
    sender_name?: string | null;
    sender_title?: string | null;
  }): string {
    if (!this.tplReviewClient) throw new Error('Review result (client) template not compiled');
    return this.tplReviewClient({
      ...ctx,
      preheader: ctx.all_approved
        ? `All documents for audit ${ctx.audit_code} have been approved.`
        : `${ctx.rejected_count} document(s) require re-upload for audit ${ctx.audit_code}.`,
      year: this.year(),
    });
  }
}
