// Shared prompt + structured-output schema for the "correct city" task.
// Every provider adapter uses these so the system prompt and the expected
// response shape stay identical across LLMs.

export const CORRECT_CITY_SCHEMA = {
  type: "object",
  properties: {
    correctedCityName: {
      type: ["string", "null"],
      description: "A name copied verbatim (case-sensitive) from the provided candidates list, or null if no candidate is a reasonable match.",
    },
    confidence: { type: "string", enum: ["high", "medium", "low"] },
    reasoning: { type: "string", maxLength: 200 },
  },
  required: ["correctedCityName", "confidence", "reasoning"],
};

export const CORRECT_CITY_SYSTEM = `You correct misspelled, abbreviated, or aliased US city/town names for a geocoder. The user passes a state code and an input string they typed. You return the closest match from a provided candidates list, or null.

Rules:
- correctedCityName MUST be one of the candidates, copied verbatim (case-sensitive). If nothing fits, return null.
- Handle obvious typos, common abbreviations (NYC, STL, LA, SF), and informal aliases (the Bronx, Big Apple) when they unambiguously map to a candidate.
- For NYC boroughs (Brooklyn, Bronx, Queens, Staten Island) when state is NY, prefer "New York" if present.
- Return null with confidence "low" when guessing. Never invent a name not in the list.
- Keep reasoning under 30 words.`;

export function buildUserMessage({ city, stateCode, candidates }) {
  return JSON.stringify({ userInput: city, state: stateCode, candidates });
}

export function emptyUsage() {
  return {
    input_tokens: 0,
    output_tokens: 0,
    cache_creation_input_tokens: 0,
    cache_read_input_tokens: 0,
  };
}

export function usageCostUsd(usage, pricing) {
  if (!usage || !pricing) return 0;
  const M = 1_000_000;
  return (
    (usage.input_tokens                || 0) * (pricing.inputUsdPerM      || 0) / M +
    (usage.output_tokens               || 0) * (pricing.outputUsdPerM     || 0) / M +
    (usage.cache_creation_input_tokens || 0) * (pricing.cacheWriteUsdPerM || 0) / M +
    (usage.cache_read_input_tokens     || 0) * (pricing.cacheReadUsdPerM  || 0) / M
  );
}
