/**
 * ARES (Administrativní registr ekonomických subjektů) lookups — the public
 * MFČR REST API for Czech company data. No auth required. Used by the
 * customer/supplier modals to prefill company data from IČO or name.
 *
 * Docs: https://ares.gov.cz/swagger-ui (REST v3, ekonomicke-subjekty).
 * The browser cannot call ares.gov.cz directly (CORS + our CSP connect-src),
 * so these run server-side behind /api/admin/ares.
 */

const ARES_BASE = "https://ares.gov.cz/ekonomicke-subjekty-v-be/rest";
const FETCH_TIMEOUT_MS = 8000;

/** Normalized subject shape consumed by the frontend prefill. */
export interface AresSubject {
  ico: string;
  dic: string | null;
  name: string;
  street: string;
  city: string;
  postal_code: string;
  country: string;
}

interface AresSidlo {
  nazevStatu?: string;
  nazevObce?: string;
  nazevCastiObce?: string;
  nazevUlice?: string;
  cisloDomovni?: number;
  cisloOrientacni?: number;
  cisloOrientacniPismeno?: string;
  psc?: number;
  textovaAdresa?: string;
}

interface AresEkonomickySubjekt {
  ico?: string;
  obchodniJmeno?: string;
  dic?: string;
  sidlo?: AresSidlo;
}

/** "51101" → "511 01" (Czech postal code display format). */
function formatPsc(psc: number | undefined): string {
  if (!psc) return "";
  const s = String(psc);
  return s.length === 5 ? `${s.slice(0, 3)} ${s.slice(3)}` : s;
}

/**
 * Street line from the registered office: "Nádražní 485", Prague-style
 * orientation numbers become "Ulice 485/12a". Villages without street names
 * fall back to the municipality part name, then the municipality itself
 * (matching how ARES itself builds textovaAdresa).
 */
function buildStreet(sidlo: AresSidlo): string {
  const streetName =
    sidlo.nazevUlice || sidlo.nazevCastiObce || sidlo.nazevObce || "";
  let num = sidlo.cisloDomovni != null ? String(sidlo.cisloDomovni) : "";
  if (sidlo.cisloOrientacni != null) {
    num += `/${sidlo.cisloOrientacni}${sidlo.cisloOrientacniPismeno || ""}`;
  }
  return [streetName, num].filter(Boolean).join(" ").trim();
}

function mapSubject(s: AresEkonomickySubjekt): AresSubject {
  const sidlo = s.sidlo || {};
  return {
    ico: s.ico || "",
    dic: s.dic || null,
    name: s.obchodniJmeno || "",
    street: buildStreet(sidlo),
    city: sidlo.nazevObce || "",
    postal_code: formatPsc(sidlo.psc),
    country: sidlo.nazevStatu || "Česká republika",
  };
}

export type AresError = "invalid_ico" | "not_found" | "ares_unavailable";

/** Lookup a single subject by its 8-digit IČO. */
export async function aresLookupByIco(
  ico: string,
): Promise<AresSubject | { error: AresError }> {
  const normalized = ico.replace(/\s+/g, "");
  if (!/^\d{8}$/.test(normalized)) return { error: "invalid_ico" };

  try {
    const response = await fetch(
      `${ARES_BASE}/ekonomicke-subjekty/${normalized}`,
      { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) },
    );
    if (response.status === 404) return { error: "not_found" };
    if (!response.ok) {
      console.error(`[ares] lookup ${normalized} failed: ${response.status}`);
      return { error: "ares_unavailable" };
    }
    const data = (await response.json()) as AresEkonomickySubjekt;
    if (!data.ico) return { error: "not_found" };
    return mapSubject(data);
  } catch (err) {
    console.error("[ares] lookup failed:", err);
    return { error: "ares_unavailable" };
  }
}

/** Search subjects by (part of) the business name; returns up to 10 matches. */
export async function aresSearchByName(
  name: string,
): Promise<AresSubject[] | { error: AresError }> {
  const query = name.trim();
  if (!query) return [];

  try {
    const response = await fetch(`${ARES_BASE}/ekonomicke-subjekty/vyhledat`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ obchodniJmeno: query, pocet: 10, start: 0 }),
      signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
    });
    if (!response.ok) {
      console.error(`[ares] search "${query}" failed: ${response.status}`);
      return { error: "ares_unavailable" };
    }
    const data = (await response.json()) as {
      ekonomickeSubjekty?: AresEkonomickySubjekt[];
    };
    return (data.ekonomickeSubjekty ?? []).map(mapSubject);
  } catch (err) {
    console.error("[ares] search failed:", err);
    return { error: "ares_unavailable" };
  }
}
