/**
 * Recipient timezone inference from a US phone handle's area code.
 *
 * The outbox scheduler needs the *recipient's* local time to pick a humane
 * send window. We infer it from the area code — coarse but good enough for
 * day-part decisions — and fall back to Eastern (where Quinn operates), per
 * Handoff 03's methodology.
 *
 * This is deliberately separate from `features/prospect`'s `metroFromHandle`:
 * that answers a marketing question (which of 4 metros), this answers a clock
 * question (which of the continental US zones). They share the idea, not a table.
 */

export const DEFAULT_TIMEZONE = 'America/New_York';

// IANA zones for the continental US. Hawaii/Alaska/territories fall back to ET;
// they are rare for this use and the day-part error is acceptable.
const PACIFIC = 'America/Los_Angeles';
const MOUNTAIN = 'America/Denver';
const CENTRAL = 'America/Chicago';
const EASTERN = 'America/New_York';

// Area code → zone. Covers the high-volume codes per zone; anything unlisted
// defaults to Eastern. Kept as a flat map so lookups are O(1) and the data is
// trivially auditable/extendable.
const AREA_CODE_ZONE: Readonly<Record<string, string>> = Object.freeze({
  // Pacific
  ...zone(PACIFIC, [
    '213', '310', '323', '424', '442', '562', '626', '657', '661', '714', '747', '760', '818', '909', '951', // LA/SoCal
    '415', '628', '408', '510', '650', '669', '925', '707', // Bay Area
    '206', '253', '360', '425', '564', // WA
    '503', '541', '971', // OR
    '702', '725', // NV
  ]),
  // Mountain
  ...zone(MOUNTAIN, [
    '303', '720', '970', '719', // CO
    '602', '480', '520', '623', '928', // AZ (no DST, close enough for day-parts)
    '801', '385', '435', // UT
    '505', '575', // NM
    '406', '208', '307', // MT/ID/WY
  ]),
  // Central
  ...zone(CENTRAL, [
    '312', '773', '872', '630', '847', '815', '779', '331', // Chicago
    '214', '469', '972', '512', '737', '713', '281', '832', '210', '726', // TX
    '612', '763', '952', '651', // MN
    '314', '816', '417', // MO
    '504', '225', '337', // LA
    '615', '629', '901', // TN (mostly Central)
    '414', '262', '608', // WI
  ]),
  // Eastern
  ...zone(EASTERN, [
    '212', '718', '917', '347', '646', '929', '516', '914', '631', '845', // NY
    '305', '786', '954', '561', '407', '321', '813', '727', '904', '850', // FL
    '404', '470', '678', '770', // GA
    '215', '267', '445', '412', '484', '610', // PA
    '202', '703', '571', '804', '757', // DC/VA
    '617', '857', '781', '339', '508', '774', // MA
    '313', '248', '734', '947', // MI (Eastern)
    '216', '614', '513', '440', // OH
    '704', '980', '919', '984', '252', // NC
  ]),
});

function zone(tz: string, codes: readonly string[]): Record<string, string> {
  return Object.fromEntries(codes.map((c) => [c, tz]));
}

/** Extract the 3-digit area code from a US handle, or null if not parseable. */
export function areaCodeFromHandle(handle: string): string | null {
  const digits = handle.replace(/\D/g, '');
  if (digits.length === 10) return digits.slice(0, 3);
  if (digits.length === 11 && digits[0] === '1') return digits.slice(1, 4);
  return null;
}

/** Best-effort IANA timezone for a handle; Eastern when unknown. */
export function timezoneForHandle(handle: string): string {
  const area = areaCodeFromHandle(handle);
  if (!area) return DEFAULT_TIMEZONE;
  return AREA_CODE_ZONE[area] ?? DEFAULT_TIMEZONE;
}
