#!/usr/bin/env node

import minimist from "minimist";

import { assessProperty } from "./assessment.js";
import { resolvePublicRecords } from "./public-records.js";
import { ReportValidationError, loadReportPayload, renderReportPdf } from "./report-pdf.js";

function usage(): void {
  process.stdout.write(`property-assessor\n
Commands:
  assess --address "<address>" --assessment-purpose "<purpose>" [--recipient-email "<email>"] [--output "<report.pdf>"] [--parcel-id "<id>"] [--listing-geo-id "<id>"] [--listing-source-url "<url>"]
  locate-public-records --address "<address>" [--parcel-id "<id>"] [--listing-geo-id "<id>"] [--listing-source-url "<url>"]
  render-report --input "<payload.json>" --output "<report.pdf>"
`);
}

async function main(): Promise<void> {
  const argv = minimist(process.argv.slice(2), {
    string: [
      "address",
      "assessment-purpose",
      "recipient-email",
      "parcel-id",
      "listing-geo-id",
      "listing-source-url",
      "input",
      "output"
    ],
    alias: {
      h: "help"
    }
  });
  const [command] = argv._;

  if (!command || argv.help) {
    usage();
    process.exit(0);
  }

  if (command === "assess") {
    if (!argv.address) {
      throw new Error("Missing required option: --address");
    }
    const payload = await assessProperty({
      address: argv.address,
      assessmentPurpose: argv["assessment-purpose"],
      recipientEmails: argv["recipient-email"],
      output: argv.output,
      parcelId: argv["parcel-id"],
      listingGeoId: argv["listing-geo-id"],
      listingSourceUrl: argv["listing-source-url"]
    });
    process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
    return;
  }

  if (command === "locate-public-records") {
    if (!argv.address) {
      throw new Error("Missing required option: --address");
    }
    const payload = await resolvePublicRecords(argv.address, {
      parcelId: argv["parcel-id"],
      listingGeoId: argv["listing-geo-id"],
      listingSourceUrl: argv["listing-source-url"]
    });
    process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
    return;
  }

  if (command === "render-report") {
    if (!argv.input || !argv.output) {
      throw new Error("Missing required options: --input and --output");
    }
    const payload = await loadReportPayload(argv.input);
    const outputPath = await renderReportPdf(payload, argv.output);
    process.stdout.write(`${JSON.stringify({ ok: true, outputPath }, null, 2)}\n`);
    return;
  }

  throw new Error(`Unknown command: ${command}`);
}

main().catch((error: unknown) => {
  const message =
    error instanceof ReportValidationError || error instanceof Error
      ? error.message
      : String(error);
  process.stderr.write(`${message}\n`);
  process.exit(1);
});
