/**
 * Canonical contact-record schema + (de)serialization helpers.
 *
 * The customer requested, per organization: company name, title of person,
 * email, phone, and company domain — grouped by state.
 *
 * The authoritative public-record source (NCES CCD LEA Directory) supplies the
 * organization name, full address, county, and a main phone number. It does NOT
 * publish a named contact, that person's title, an email address, or a web
 * domain. Those four fields are therefore carried in the schema but left EMPTY
 * and flagged as DISCLOSED SEAMS — never fabricated. See proof/LIMITATIONS.md.
 */
import { AGENCY_TYPE } from './fips.mjs';

/** Column order for CSV + display. Real (sourced) vs seam (empty) is explicit. */
export const COLUMNS = [
  'state',            // USPS code (grouping key)            REAL
  'stateName',        //                                     REAL
  'organizationName', // "company name"                      REAL
  'organizationType', //                                     REAL
  'contactTitle',     // "title of people"                   SEAM (empty)
  'contactName',      //                                     SEAM (empty)
  'email',            // "email address"                     SEAM (empty)
  'phone',            // "phone numbers"                     REAL
  'domain',           // "company domains" / website         SEAM (empty)
  'streetAddress',    //                                     REAL
  'city',             //                                     REAL
  'zip',              //                                     REAL
  'county',           //                                     REAL
  'enrollment',       //                                     REAL
  'schools',          //                                     REAL
  'leaid',            // NCES unique agency id                REAL
  'source',           // provenance                          REAL
  'sourceUrl',        // provenance (per-record dataset URL)  REAL
  'datasetYear',      // provenance                          REAL
  'retrievedAt',      // provenance                          REAL
];

/** Fields the customer asked for that this public source cannot supply. */
export const SEAM_FIELDS = ['contactTitle', 'contactName', 'email', 'domain'];

export const SOURCE_NAME = 'NCES Common Core of Data (CCD) — LEA Directory (via Urban Institute Education Data Portal)';

const clean = (v) => (v == null ? '' : String(v).trim());

function normalizePhone(raw) {
  const digits = clean(raw).replace(/[^0-9]/g, '');
  if (digits.length === 10) return `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6)}`;
  if (digits.length === 11 && digits[0] === '1') return `(${digits.slice(1, 4)}) ${digits.slice(4, 7)}-${digits.slice(7)}`;
  return clean(raw);
}

/**
 * Map one raw NCES CCD LEA record into a canonical contact record.
 * @param {object} r raw API result row
 * @param {{usps:string,name:string}} j jurisdiction
 * @param {string} sourceUrl the exact dataset URL this row came from
 * @param {number} year dataset year
 * @param {string} retrievedAt ISO timestamp
 */
export function toContact(r, j, sourceUrl, year, retrievedAt) {
  return {
    state: j.usps,
    stateName: j.name,
    organizationName: clean(r.lea_name),
    organizationType: AGENCY_TYPE[r.agency_type] || 'Public education agency',
    contactTitle: '',
    contactName: '',
    email: '',
    phone: normalizePhone(r.phone),
    domain: '',
    streetAddress: clean(r.street_location || r.street_mailing),
    city: clean(r.city_location || r.city_mailing),
    zip: clean(r.zip_location || r.zip_mailing),
    county: clean(r.county_name),
    enrollment: r.enrollment == null || r.enrollment < 0 ? '' : r.enrollment,
    schools: r.number_of_schools == null || r.number_of_schools < 0 ? '' : r.number_of_schools,
    leaid: clean(r.leaid),
    source: SOURCE_NAME,
    sourceUrl,
    datasetYear: year,
    retrievedAt,
  };
}

/* ----------------------------- CSV ----------------------------- */
export function csvCell(v) {
  const s = v == null ? '' : String(v);
  return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
}
export function toCsv(records, columns = COLUMNS) {
  const head = columns.join(',');
  const rows = records.map((rec) => columns.map((c) => csvCell(rec[c])).join(','));
  return head + '\n' + rows.join('\n') + '\n';
}

/* --------------------------- grouping --------------------------- */
/** Group records by USPS state code, deterministically sorted. */
export function groupByState(records) {
  const map = new Map();
  for (const rec of records) {
    if (!map.has(rec.state)) map.set(rec.state, []);
    map.get(rec.state).push(rec);
  }
  for (const list of map.values()) {
    list.sort((a, b) => a.organizationName.localeCompare(b.organizationName));
  }
  return new Map([...map.entries()].sort((a, b) => a[0].localeCompare(b[0])));
}
