// src/inquiry/draft-generator.service.ts
import { Injectable } from '@nestjs/common';
import * as fs from 'fs';
import * as path from 'path';
import * as https from 'https';
import * as http from 'http';
import * as puppeteer from 'puppeteer';
import {
  Document,
  Packer,
  Paragraph,
  TextRun,
  AlignmentType,
  SectionType,
  ImageRun,
  WidthType,
  Table,
  TableRow,
  TableCell,
  BorderStyle,
  VerticalAlign,
  LevelFormat,
} from 'docx';
import { Inquiry } from './entities/inquiry.entity';

@Injectable()
export class DraftGeneratorService {
  // ── Format date to "15 MAY 2026" ─────────────────────────────
  private formatDate(dateStr: string | Date | null | undefined): string {
    if (!dateStr) return 'N/A';
    const months = [
      'JAN',
      'FEB',
      'MAR',
      'APR',
      'MAY',
      'JUN',
      'JUL',
      'AUG',
      'SEP',
      'OCT',
      'NOV',
      'DEC',
    ];
    const d = new Date(dateStr);
    if (isNaN(d.getTime())) return String(dateStr);
    return `${d.getDate()} ${months[d.getMonth()]} ${d.getFullYear()}`;
  }

  // ✅ NEW — small helper to safely uppercase any string-ish value
  private uc(value: string | null | undefined): string {
    if (!value) return '';
    return String(value).toUpperCase();
  }

  // ✅ FIXED — much smarter scope splitting (matches certificate draft logic)
  // Splits on: newlines, commas, semicolons, "&", "•", "▪", arrows, em-dashes, multiple spaces, bullets
  // Trims, deduplicates, drops fragments < 3 chars (which are usually noise)
  private getScopeItems(scopeOfWork?: string): string[] {
    if (!scopeOfWork) return [];

    // Strip any existing bullets/arrows that may already be in the source text
    const cleaned = scopeOfWork
      .replace(/[➤➢►▶◆●◦◯○▪■□☐»]/g, '\n')        // common bullets → newline
      .replace(/[\u2022\u25BA\u25B6\u25CF\u00BB]/g, '\n') // unicode bullets → newline
      .replace(/[—–]/g, '\n');                     // em/en dash → newline

    // Split on the major delimiters
    const parts = cleaned
      .split(/\r?\n|;|&|\|/)                         // newlines, semicolons, &, pipes
      .flatMap((s) => s.split(/,(?![^()]*\))/))      // commas (but not inside parens)
      .map((s) => s.trim())
      .filter((s) => s.length >= 3);                 // drop empty / 1–2 char garbage

    // Dedupe while preserving order
    const seen = new Set<string>();
    const out: string[] = [];
    for (const item of parts) {
      const key = item.toUpperCase();
      if (!seen.has(key)) {
        seen.add(key);
        out.push(item);
      }
    }
    return out;
  }

  // ── Ensure uploads/drafts folder ─────────────────────────────
  private ensureDraftFolder(): string {
    const folder = path.join(process.cwd(), 'uploads', 'drafts');
    if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
    return folder;
  }

  // ── Load signature — local file FIRST then fallbacks ─────────
  private async loadSignature(): Promise<Buffer | null> {
    const localPaths = [
      path.join(process.cwd(), 'src', 'static', 'sign-remove.png'),
      path.join(process.cwd(), 'static', 'sign-remove.png'),
      path.join(process.cwd(), 'public', 'static', 'sign-remove.png'),
      path.join(process.cwd(), 'assets', 'sign-remove.png'),
      path.join(process.cwd(), 'src', 'assets', 'sign-remove.png'),
    ];

    for (const p of localPaths) {
      if (fs.existsSync(p)) {
        console.log('✅ Signature loaded from local path:', p);
        return fs.readFileSync(p);
      }
    }

    try {
      const buf = await this.downloadBuffer(
        'http://localhost:3000/static/sign-remove.png',
      );
      if (buf && buf.length > 100) {
        console.log('✅ Signature loaded via localhost HTTP');
        return buf;
      }
    } catch {
      /* continue */
    }

    try {
      const buf = await this.downloadBuffer(
        'https://scheme.qrs.ae/static/sign-remove.png',
      );
      if (buf && buf.length > 100) {
        console.log('✅ Signature loaded via HTTPS URL');
        return buf;
      }
    } catch {
      /* continue */
    }

    console.warn('⚠️ Signature image not found — proceeding without it');
    return null;
  }

  // ── Generic buffer downloader ─────────────────────────────────
  private downloadBuffer(url: string): Promise<Buffer> {
    return new Promise((resolve, reject) => {
      const client = url.startsWith('https') ? https : http;
      const req = client.get(url, { timeout: 5000 }, (res) => {
        if (res.statusCode !== 200) {
          reject(new Error(`HTTP ${res.statusCode}`));
          return;
        }
        const chunks: Buffer[] = [];
        res.on('data', (c) => chunks.push(c));
        res.on('end', () => resolve(Buffer.concat(chunks)));
        res.on('error', reject);
      });
      req.on('error', reject);
      req.on('timeout', () => {
        req.destroy();
        reject(new Error('timeout'));
      });
    });
  }

  // ── No border helper ─────────────────────────────────────────
  private noBorder() {
    return {
      top: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
      bottom: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
      left: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
      right: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
    };
  }

  // ═══════════════════════════════════════════════════════════════
  // PDF — A4 size, DRAFT watermark always visible (NO QR code)
  // Matches certificate draft style: UPPERCASE name/address,
  // » double-chevron bullets, each scope item on its own line.
  // ═══════════════════════════════════════════════════════════════
  private buildPageHtml(inquiry: Inquiry, standard: any): string {
    const scopeItems = this.getScopeItems(inquiry.scope_of_work);

    // ✅ CHANGED — same » double chevron arrow as certificate draft
    const scopeHtml = scopeItems
      .map(
        (item) => `
        <li style="
          margin: 4px 0;
          padding: 0;
          line-height: 1.5;
          display: flex;
          align-items: flex-start;
        ">
          <span style="
            display: inline-block;
            width: 18px;
            color: #000;
            font-weight: bold;
            flex-shrink: 0;
          ">&#10146;</span>
          <span style="flex: 1;">${item}</span>
        </li>`,
      )
      .join('');

    // ✅ NEW — UPPERCASE company name, address, country
    const companyNameUpper = this.uc(inquiry.company?.name);
    const addressUpper = this.uc(inquiry.company?.address);
    // Try common country fields if your Inquiry/company has one — safe optional access
    const countryUpper = this.uc(
      (inquiry.company as any)?.country?.name ??
        (inquiry.company as any)?.country ??
        (inquiry as any)?.country,
    );
    const fullAddressUpper =
      addressUpper + (countryUpper ? ', ' + countryUpper : '');

    return `
      <div style="
        width:210mm; min-height:297mm; position:relative;
        font-family:'Calibri',sans-serif; background:#fff;
        page-break-after:always; overflow:hidden;
      ">
        <!-- DRAFT watermark — always visible -->
        <div style="
          position:fixed; top:50%; left:50%;
          transform:translate(-50%,-50%) rotate(-30deg);
          font-size:140px; font-weight:900; letter-spacing:10px;
          color:rgba(180,180,180,0.18); pointer-events:none;
          white-space:nowrap; z-index:0;
        ">DRAFT</div>

        <!-- Content -->
        <div style="
          position:relative; z-index:1;
          padding:40px 45px 40px; text-align:center;
        ">
          <!-- ✅ Company name — UPPERCASE, regular weight, MORE space from top -->
          <h2 style="
            font-size:27px; font-weight:400;
            margin:80px auto 6px; max-width:90%; line-height:1.1em;
          ">${companyNameUpper}</h2>

          <p style="font-size:13px; margin:4px 0 2px;">at</p>

          <!-- ✅ Address + Country — UPPERCASE -->
          <p style="
            font-size:13px; margin:2px auto 10px; max-width:90%;
            word-break:break-word; line-height:1.35;
          ">${fullAddressUpper}</p>

          <p style="
            font-size:0.9em; line-height:1.35; text-align:center;
            margin:2px auto 10px; max-width:90%;
          ">
            Quality Registrar Systems certify that the management system of the
            above organization has been audited and found to be in compliance with
            the QRS &amp; ISO standard requirements for registration of the
            management system standard detailed below:
          </p>

          <!-- ✅ Standard — BOLD (matches certificate draft) -->
          <h3 style="
            font-size:1.8em; font-weight:700;
            margin:0; line-height:1.1em;
          ">${standard.name ?? ''}</h3>
          <p style="font-size:0.9em; margin:0; padding-top:2px; line-height:1.1em;">
            ${standard.title ?? ''}
          </p>

          <!-- ✅ Scope — each item on its own line, » double chevron -->
          <div style="width:90%; margin:14px auto 22px; text-align:left;">
            <p style="
              font-weight:normal;
              text-align:center;
              margin-bottom:8px;
              font-size:0.95em;
            ">Scope of work</p>
            <ul style="
              list-style:none;
              padding-left:1.4em;
              margin:0;
              font-size:0.85em;
              line-height:1.5;
            ">
              ${scopeHtml}
            </ul>
          </div>

          <!-- 2 columns — Dates LEFT | Signature RIGHT (NO QR) -->
          <div style="
            display:grid;
            grid-template-columns:1.5fr 1fr;
            gap: 12px;
            width:95%;
            margin:0 auto;
            text-align:left;
          ">
            <!-- LEFT COLUMN: Dates -->
            <div>
              <p style="margin:2px 0; font-size:0.85em;">
                EA &nbsp;&nbsp;${inquiry.company?.accreditation ?? ''}
              </p>
              <p style="margin:2px 0; font-size:0.85em;">
                Certificate No: ${inquiry.certificate_number ?? ''}
              </p>
              <p style="margin:2px 0; font-size:0.85em;">
                Originally Registered: ${this.formatDate(inquiry.audit_date)}
              </p>
              <p style="margin:2px 0; font-size:0.85em;">
                Latest Issue: ${this.formatDate(inquiry.issue_date)}
              </p>
              <p style="margin:2px 0; font-size:0.85em;">
                Valid up-to: ${this.formatDate(inquiry.expiry_date)}
              </p>
            </div>

            <!-- RIGHT COLUMN: Signature only (NO QR) -->
            <div style="text-align:center; margin-top:-20px;">
              <img
                src="https://scheme.qrs.ae/static/sign-remove.png"
                style="width:160px; display:block; margin:0 auto;"
                alt="Signature"
              />
              <div style="
                width:174px; height:1px; background:#000;
                margin:1px auto 5px;
              "></div>
              <p style="font-size:0.85em; font-weight:600; margin-top:3px;">
                Quality Registrar Systems
              </p>
            </div>
          </div>

        </div>
      </div>
    `;
  }

  async generateDraftPdf(inquiry: Inquiry): Promise<string> {
    const standards = inquiry.standards ?? [];
    if (!standards.length) throw new Error('No standards on inquiry');

    const pages = standards.map((std) => this.buildPageHtml(inquiry, std));
    const fullHtml = `
      <!DOCTYPE html><html>
      <head>
        <meta charset="UTF-8">
        <style>
          * { box-sizing:border-box; margin:0; padding:0; }
          @page { size:A4; margin:0; }
          body { margin:0; padding:0; background:#fff; }
        </style>
      </head>
      <body>${pages.join('')}</body>
      </html>
    `;

    const browser = await puppeteer.launch({
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox'],
    });

    try {
      const page = await browser.newPage();
     await page.setContent(fullHtml, { waitUntil: 'domcontentloaded' });
      await page.evaluateHandle('document.fonts.ready');

      // Wait for signature image to load
      await page.evaluate(async () => {
        const images = Array.from(document.images);
        await Promise.all(
          images.map((img) => {
            if (img.complete) return;
            return new Promise<void>((resolve) => {
              img.onload = () => resolve();
              img.onerror = () => resolve();
            });
          }),
        );
      });

      const pdfBuffer = await page.pdf({
        format: 'A4',
        printBackground: true,
        margin: { top: '0mm', right: '0mm', bottom: '0mm', left: '0mm' },
      });

      const folder = this.ensureDraftFolder();
      const fileName = `${inquiry.inquiry_ref}_DRAFT.pdf`;
      fs.writeFileSync(path.join(folder, fileName), Buffer.from(pdfBuffer));
      return `uploads/drafts/${fileName}`;
    } finally {
      await browser.close();
    }
  }

  // ═══════════════════════════════════════════════════════════════
  // WORD — A4, NO watermark, NO QR code
  //   ✅ Calibri body, » double-chevron bullets via native list
  //   ✅ UPPERCASE company name, address, country
  //   ✅ Fully editable — no content controls, no locked sections
  //   ✅ Multi-standard support preserved (one section per standard)
  // ═══════════════════════════════════════════════════════════════
  async generateDraftDocx(inquiry: Inquiry): Promise<string> {
    const standards = inquiry.standards ?? [];
    if (!standards.length) throw new Error('No standards on inquiry');

    const scopeItems = this.getScopeItems(inquiry.scope_of_work);

    // Load signature locally first
    const signatureBuffer = await this.loadSignature();

    // ✅ NEW — UPPERCASE company name, address, country
    const companyNameUpper = this.uc(inquiry.company?.name);
    const addressUpper = this.uc(inquiry.company?.address);
    const countryUpper = this.uc(
      (inquiry.company as any)?.country?.name ??
        (inquiry.company as any)?.country ??
        (inquiry as any)?.country,
    );
    const fullAddressUpper =
      addressUpper + (countryUpper ? ', ' + countryUpper : '');

    // ✅ Native bullet numbering — using ➢ arrow (matches certificate draft)
    // This makes each scope item a real list item, so the user can hit Enter
    // in Word and get a new bullet automatically (fully editable).
    const numberingConfig = {
      config: [
        {
          reference: 'scopeBullets',
          levels: [
            {
              level: 0,
              format: LevelFormat.BULLET,
              text: '\u27A2', // ➢ standard Word arrow bullet (matches draft)
              alignment: AlignmentType.LEFT,
              style: {
                paragraph: { indent: { left: 720, hanging: 360 } },
                run: { font: 'Calibri', size: 20 },
              },
            },
          ],
        },
      ],
    };

    const sections = standards.map((standard, index) => ({
      properties: {
        type: index === 0 ? SectionType.CONTINUOUS : SectionType.NEXT_PAGE,
        page: {
          size: { width: 11906, height: 16838 }, // A4
          margin: { top: 720, bottom: 720, left: 900, right: 900 },
        },
      },

      children: [
        // ✅ Top spacer — extra space from top
        new Paragraph({ spacing: { before: 600, after: 0 } }),

        // ── ✅ Company Name — UPPERCASE, regular weight (Calibri Body)
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 280, after: 80 },
          children: [
            new TextRun({
              text: companyNameUpper,
              size: 54,
              bold: false,
            }),
          ],
        }),

        // ── "at" ──────────────────────────────────────────────
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 40, after: 40 },
          children: [new TextRun({ text: 'at', size: 24 })],
        }),

        // ── ✅ Address + Country — UPPERCASE ──────────────────
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 40, after: 100 },
          children: [
            new TextRun({
              text: fullAddressUpper,
              size: 22,
            }),
          ],
        }),

        // ── Compliance Text ───────────────────────────────────
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 80, after: 80 },
          children: [
            new TextRun({
              text:
                'Quality Registrar Systems certify that the management system of the above ' +
                'organization has been audited and found to be in compliance with the QRS & ISO ' +
                'standard requirements for registration of the management system standard detailed below:',
              size: 22,
            }),
          ],
        }),

        // ── Standard Name — regular weight (Calibri Body)
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 60, after: 40 },
          children: [
            new TextRun({
              text: standard.name ?? '',
              size: 56,
              bold: false,
            }),
          ],
        }),

        // ── Standard Title ────────────────────────────────────
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 40, after: 100 },
          children: [
            new TextRun({
              text: standard.title ?? '',
              size: 24,
            }),
          ],
        }),

        // ── Scope of Work Title ───────────────────────────────
        new Paragraph({
          alignment: AlignmentType.CENTER,
          spacing: { before: 60, after: 80 },
          children: [
            new TextRun({ text: 'Scope of work', size: 24 }),
          ],
        }),

        // ── ✅ Scope Items — native bullet list with ➢ arrow
        //    Tight spacing to match draft. Fully editable: pressing
        //    Enter in Word adds a new bullet automatically.
        ...scopeItems.map(
          (item) =>
            new Paragraph({
              numbering: { reference: 'scopeBullets', level: 0 },
              spacing: { before: 0, after: 0, line: 260 },
              children: [
                new TextRun({
                  text: item,
                  size: 20,
                }),
              ],
            }),
        ),

        // ── Spacer ────────────────────────────────────────────
        new Paragraph({ spacing: { before: 280, after: 0 } }),

        // ── 2-column TABLE: Dates LEFT | Signature RIGHT (NO QR)
        //
        //   ┌────────────────────────┬────────────────────────────────┐
        //   │ EA 17                  │                                │
        //   │ Certificate No: ...    │       [signature image]        │
        //   │ Originally Reg: ...    │       _______________          │
        //   │ Latest Issue: ...      │   Quality Registrar Systems    │
        //   │ Valid up-to: ...       │                                │
        //   └────────────────────────┴────────────────────────────────┘
        //
        // Fully editable in Word — user can click any cell, edit text,
        // add new lines, drag the table, etc.
        new Table({
          width: { size: 9200, type: WidthType.DXA },
          // ✅ Match certificate draft column widths exactly
          columnWidths: [4500, 4700],
          borders: {
            top: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
            bottom: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
            left: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
            right: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
            insideHorizontal: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
            insideVertical: { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' },
          },
          rows: [
            new TableRow({
              children: [
                // ── LEFT: Dates ───────────────────────────────
                new TableCell({
                  borders: this.noBorder(),
                  verticalAlign: VerticalAlign.TOP,
                  // ✅ Match cert: 4500 width, right margin 80
                  width: { size: 4500, type: WidthType.DXA },
                  margins: { top: 80, bottom: 80, left: 0, right: 80 },
                  children: [
                    new Paragraph({
                      spacing: { before: 20, after: 20 },
                      children: [
                        new TextRun({
                          text: `EA   ${inquiry.company?.accreditation ?? ''}`,
                          size: 20,
                        }),
                      ],
                    }),
                    new Paragraph({
                      spacing: { before: 20, after: 20 },
                      children: [
                        new TextRun({
                          text: `Certificate No: ${inquiry.certificate_number ?? 'UAE-XYZ'}`,
                          size: 20,
                        }),
                      ],
                    }),
                    new Paragraph({
                      spacing: { before: 20, after: 20 },
                      children: [
                        new TextRun({
                          text: `Originally Registered: ${this.formatDate(inquiry.audit_date)}`,
                          size: 20,
                        }),
                      ],
                    }),
                    new Paragraph({
                      spacing: { before: 20, after: 20 },
                      children: [
                        new TextRun({
                          text: `Latest Issue: ${this.formatDate(inquiry.issue_date)}`,
                          size: 20,
                        }),
                      ],
                    }),
                    new Paragraph({
                      spacing: { before: 20, after: 20 },
                      children: [
                        new TextRun({
                          text: `Valid up-to: ${this.formatDate(inquiry.expiry_date)}`,
                          size: 20,
                        }),
                      ],
                    }),
                  ],
                }),

                // ── RIGHT: Signature only (NO QR) ──────────────
                new TableCell({
                  borders: this.noBorder(),
                  verticalAlign: VerticalAlign.TOP,
                  // ✅ Match cert: 4700 width, left margin 80
                  width: { size: 4700, type: WidthType.DXA },
                  margins: { top: 200, bottom: 80, left: 80, right: 0 },
                  children: [
                    // Signature image (centered)
                    new Paragraph({
                      alignment: AlignmentType.CENTER,
                      spacing: { before: 0, after: 20 },
                      children: signatureBuffer
                        ? [
                            new ImageRun({
                              data: signatureBuffer,
                              transformation: { width: 160, height: 60 },
                              type: 'png',
                            }),
                          ]
                        : [new TextRun({ text: ' ', size: 40 })],
                    }),

                    // Signature line (paragraph border bottom)
                    new Paragraph({
                      alignment: AlignmentType.CENTER,
                      spacing: { before: 0, after: 40 },
                      // ✅ Match cert exactly — gives the same visible line width
                      indent: { left: 800, right: 800 },
                      border: {
                        bottom: {
                          style: BorderStyle.SINGLE,
                          size: 6,
                          color: '000000',
                          space: 1,
                        },
                      },
                      children: [new TextRun({ text: ' ', size: 4 })],
                    }),

                    // "Quality Registrar Systems" caption
                    new Paragraph({
                      alignment: AlignmentType.CENTER,
                      // ✅ Match cert spacing exactly
                      spacing: { before: 40, after: 100 },
                      children: [
                        new TextRun({
                          text: 'Quality Registrar Systems',
                          size: 20,
                          // ✅ Explicit Calibri on signature label (user request)
                          font: 'Calibri',
                        }),
                      ],
                    }),
                    // ❌ NO QR code — removed as requested
                  ],
                }),
              ],
            }),
          ],
        }),
      ],
    }));

    // ✅ Document-level Calibri default + native » bullet numbering
    const doc = new Document({
      styles: {
        default: {
          document: { run: { font: 'Calibri', size: 22 } },
        },
      },
      numbering: numberingConfig,
      sections,
    });

    const docxBuffer = await Packer.toBuffer(doc);
    const folder = this.ensureDraftFolder();
    const fileName = `${inquiry.inquiry_ref}_DRAFT.docx`;

    fs.writeFileSync(path.join(folder, fileName), docxBuffer);
    return `uploads/drafts/${fileName}`;
  }
}