/**
 * Read company submission data directly from the SEC bulk submissions.zip.
 * Eliminates per-CIK API calls by reading the local ZIP file.
 *
 * The ZIP contains files like:
 *   CIK0000320193.json  — same format as https://data.sec.gov/submissions/CIK{padded}.json
 *   submissions-{CIK}-{sequence}.json — overflow filing history files
 */
import { execSync } from "node:child_process";
import { existsSync } from "node:fs";
import type { CompanyMeta } from "./edgar-client.ts";

export interface CompanyFiling {
  accessionNumber: string;
  filingDate: string;
  reportDate: string;
  form: string;
  primaryDocument: string;
  items: string;
}

interface SubmissionsJson {
  cik: string;
  entityType: string;
  sic: string;
  sicDescription: string;
  name: string;
  tickers: string[];
  exchanges: string[];
  stateOfIncorporation: string;
  filings: {
    recent: {
      accessionNumber: string[];
      filingDate: string[];
      reportDate: string[];
      form: string[];
      primaryDocument: string[];
      primaryDocDescription: string[];
      items: string[];
    };
    files: Array<{ name: string; filingCount: number }>;
  };
}

const ZIP_PATH = "../data/bulk/submissions.zip";

/** Check if the bulk submissions ZIP is available. */
export function hasBulkSubmissions(): boolean {
  return existsSync(ZIP_PATH);
}

/**
 * Read a single CIK's submissions data from the bulk ZIP.
 * Uses `unzip -p` to stream a single file from the ZIP without extracting everything.
 */
export function readBulkSubmissions(cik: string): { meta: CompanyMeta; filings: CompanyFiling[] } | null {
  const paddedCik = cik.replace(/^0+/, "").padStart(10, "0");
  const filename = `CIK${paddedCik}.json`;

  try {
    const json = execSync(`unzip -p "${ZIP_PATH}" "${filename}" 2>/dev/null`, {
      maxBuffer: 50 * 1024 * 1024, // 50MB — some large filers have big JSON
      encoding: "utf-8",
    });

    const data: SubmissionsJson = JSON.parse(json);
    const recent = data.filings.recent;
    const filings: CompanyFiling[] = [];

    for (let i = 0; i < recent.accessionNumber.length; i++) {
      filings.push({
        accessionNumber: recent.accessionNumber[i]!,
        filingDate: recent.filingDate[i]!,
        reportDate: recent.reportDate[i]!,
        form: recent.form[i]!,
        primaryDocument: recent.primaryDocument[i]!,
        items: recent.items[i]!,
      });
    }

    return {
      meta: {
        cik: data.cik,
        name: data.name,
        tickers: data.tickers,
        sic: data.sic,
        sicDescription: data.sicDescription,
        stateOfIncorporation: data.stateOfIncorporation,
      },
      filings,
    };
  } catch {
    return null;
  }
}
