import { readFileSync } from "fs";
import { join } from "path";

export interface SalesTaxAddressInput {
  line1?: string | null;
  line2?: string | null;
  city?: string | null;
  state?: string | null;
  zip?: string | null;
  country?: string | null;
}

interface LocalJurisdiction {
  city: string;
  local_rate: number;
  combined_rate: number;
}

interface StateTaxRecord {
  state: string;
  abbreviation: string;
  state_rate: number;
  avg_local_rate: number;
  avg_combined_rate: number;
  has_local_tax: boolean;
  local_jurisdictions?: LocalJurisdiction[];
}

const TAX_DATA_FALLBACK_URL = new URL("./salesTaxRates.json", import.meta.url);

const TAX_DATA_CANDIDATE_PATHS: Array<string | URL> = [
  process.env.SALES_TAX_RATES_PATH ?? "",
  join(process.cwd(), "salesTaxRates.json"),
  TAX_DATA_FALLBACK_URL,
].filter(Boolean);

const parseTaxData = (): StateTaxRecord[] => {
  for (const source of TAX_DATA_CANDIDATE_PATHS) {
    try {
      const raw = readFileSync(source, "utf-8");
      const parsed = JSON.parse(raw) as StateTaxRecord[];
      if (Array.isArray(parsed)) return parsed;
    } catch {
      continue;
    }
  }

  return [];
};

const SALES_TAX_DATA = parseTaxData();

const normalizeToken = (value: string | null | undefined): string | null => {
  if (!value) return null;

  const normalized = value
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, " ")
    .replace(/\s+/g, " ")
    .trim();

  if (!normalized) return null;
  return normalized;
};

const normalizeState = (state: string | null | undefined): string | null => {
  const normalized = normalizeToken(state);
  if (!normalized) return null;

  const directCode = normalized.toUpperCase();
  if (directCode.length === 2) return directCode;

  const match = SALES_TAX_DATA.find(
    (record) => normalizeToken(record.state) === normalized,
  );
  if (!match) return null;

  return match.abbreviation.toUpperCase();
};

/**
 * Compute expected sales tax rate for an address.
 * Returns a decimal tax rate (e.g. 0.06 for 6%).
 */
export const getExpectedSalesTaxRate = (
  address: SalesTaxAddressInput | null | undefined,
): number => {
  const state = normalizeState(address?.state);
  if (!state) return 0;

  // Business rule: Tennessee remains explicitly hard-coded.
  if (state === "TN") return 0.0975;

  const stateRecord = SALES_TAX_DATA.find(
    (record) => record.abbreviation.toUpperCase() === state,
  );
  if (!stateRecord) return 0;

  const city = normalizeToken(address?.city);
  const cityMatch = stateRecord.local_jurisdictions?.find(
    (jurisdiction) => normalizeToken(jurisdiction.city) === city,
  );
  if (cityMatch) return cityMatch.combined_rate;

  return stateRecord.avg_combined_rate;
};
