import { readFile, writeFile } from 'node:fs/promises';
import path from 'node:path';
import {
  AUDIT_ARTIFACTS_DIR,
  buildAuditPayload,
  createSqlClient,
  summarizeIssues,
  writeAuditArtifact
} from './pdf-audit-utils.ts';

async function readReport<T>(fileName: string): Promise<T | null> {
  const filePath = path.resolve(AUDIT_ARTIFACTS_DIR, fileName);
  try {
    const raw = await readFile(filePath, 'utf8');
    return JSON.parse(raw) as T;
  } catch {
    return null;
  }
}

async function main() {
  const sql = createSqlClient();

  try {
    const payload = await buildAuditPayload(sql);
    const templateVersionReport = await readReport<Record<string, unknown>>(
      'template-version-report.json'
    );
    const placeholderReport = await readReport<Record<string, unknown>>(
      'placeholder-integrity-report.json'
    );
    const payloadReport = await readReport<Record<string, unknown>>('payload-parity-report.json');
    const runtimeReport = await readReport<Record<string, unknown>>('runtime-payload-report.json');
    const snapshotReport = await readReport<Record<string, unknown>>('signature-audit-report.json');
    const statuses = [
      String(templateVersionReport?.overallStatus ?? 'WARNING'),
      String(placeholderReport?.overallStatus ?? 'WARNING'),
      String(payloadReport?.overallStatus ?? 'WARNING'),
      String(runtimeReport?.overallStatus ?? 'WARNING'),
      String(snapshotReport?.overallStatus ?? 'WARNING')
    ] as Array<'PASS' | 'WARNING' | 'FAIL'>;
    const overallStatus = summarizeIssues(statuses);
    const topicRuntimeReport = {
      audit: 'topic-runtime',
      overallStatus: Object.keys(payload.topicInputs).length > 0 ? 'PASS' : 'FAIL',
      quotationCode: payload.quotationCode,
      topicCount: payload.quotationMetrics.topicCount,
      topicInputKeys: Object.keys(payload.topicInputs)
        .filter((key) => key.startsWith('topic_'))
        .sort(),
      itemTopicInputKeys: Object.keys(payload.topicInputs)
        .filter((key) => key.startsWith('item_topic_'))
        .sort(),
      duplicateKeys: Object.keys(payload.topicInputs).filter(
        (key, index, array) => array.indexOf(key) !== index
      ),
      emptySections: Object.entries(payload.topicInputs)
        .filter(([, value]) => !Array.isArray(value) || value.length === 0)
        .map(([key]) => key)
    };
    await writeAuditArtifact('topic-runtime-report.json', topicRuntimeReport);
    const summary = {
      generatedAt: new Date().toISOString(),
      overallStatus,
      quotationCode: payload.quotationCode,
      artifacts: {
        templateVersionReport: 'template-version-report.json',
        placeholderIntegrityReport: 'placeholder-integrity-report.json',
        runtimePayloadReport: 'runtime-payload-report.json',
        payloadParityReport: 'payload-parity-report.json',
        topicRuntimeReport: 'topic-runtime-report.json',
        signatureAuditReport: 'signature-audit-report.json'
      },
      statuses: {
        templateVersion: templateVersionReport?.overallStatus ?? 'WARNING',
        placeholderIntegrity: placeholderReport?.overallStatus ?? 'WARNING',
        runtimePayload: runtimeReport?.overallStatus ?? 'WARNING',
        payloadParity: payloadReport?.overallStatus ?? 'WARNING',
        topicRuntime: topicRuntimeReport.overallStatus,
        approvedSnapshotParity: snapshotReport?.overallStatus ?? 'WARNING',
        staticLabels: runtimeReport?.staticLabelsStatus ?? 'WARNING'
      },
      priceTable: {
        present: Boolean(payload.templateInput.quotation_price_data),
        rowCount: Array.isArray(payload.templateInput.quotation_price_data)
          ? payload.templateInput.quotation_price_data.length
          : 0,
        parity: payloadReport?.priceTableParity ?? false,
        status:
          Array.isArray(payload.templateInput.quotation_price_data) &&
          (payloadReport?.priceTableParity ?? false)
            ? 'PASS'
            : 'FAIL'
      }
    };
    const artifactPath = await writeAuditArtifact('summary.json', summary);
    const markdown = [
      '# PDF Integrity Summary',
      '',
      `- Generated At: ${summary.generatedAt}`,
      `- Overall Status: ${summary.overallStatus}`,
      `- Quotation Code: ${summary.quotationCode}`,
      '',
      '## Statuses',
      '',
      `- Template Version Integrity: ${summary.statuses.templateVersion}`,
      `- Placeholder Integrity: ${summary.statuses.placeholderIntegrity}`,
      `- Runtime Payload: ${summary.statuses.runtimePayload}`,
      `- Payload Parity: ${summary.statuses.payloadParity}`,
      `- Topic Runtime: ${summary.statuses.topicRuntime}`,
      `- Approved Snapshot Parity: ${summary.statuses.approvedSnapshotParity}`,
      `- Static Labels: ${summary.statuses.staticLabels}`,
      `- Price Table Present: ${summary.priceTable.present ? 'Yes' : 'No'}`,
      `- Price Table Status: ${summary.priceTable.status}`,
      `- Price Table Parity: ${summary.priceTable.parity ? 'Yes' : 'No'}`,
      '',
      '## Artifact Files',
      '',
      `- ${summary.artifacts.templateVersionReport}`,
      `- ${summary.artifacts.placeholderIntegrityReport}`,
      `- ${summary.artifacts.runtimePayloadReport}`,
      `- ${summary.artifacts.payloadParityReport}`,
      `- ${summary.artifacts.topicRuntimeReport}`,
      `- ${summary.artifacts.signatureAuditReport}`
    ].join('\n');
    const markdownPath = path.resolve(AUDIT_ARTIFACTS_DIR, 'summary.md');
    await writeFile(markdownPath, `${markdown}\n`, 'utf8');

    console.log(JSON.stringify({ ...summary, artifactPath, markdownPath }, null, 2));
  } finally {
    await sql.end({ timeout: 5 });
  }
}

main().catch((error) => {
  console.error(`[generate-pdf-integrity-report] ${error.message}`);
  process.exit(1);
});
