"use client";

import { useMutation } from "@tanstack/react-query";

async function parseError(res: Response, fallback: string): Promise<Error> {
  const body = await res.json().catch(() => ({}));
  return new Error(body?.error ?? fallback);
}

// One address candidate returned by the portfolio postcode search, plus the
// server-computed flag for candidates already assigned in this portfolio.
export interface SearchCandidate {
  uprn: string;
  address: string;
  postcode: string;
  classificationCode: string | null;
  selectable: boolean; // residential (per OS classification)
  propertyType: string | null;
  builtForm: string | null;
  alreadyInPortfolio: boolean;
}

export interface AddressSearchResult {
  postcode: string;
  source: "cache" | "live";
  candidates: SearchCandidate[];
}

// Run the postcode → address-candidate search. Reuses the add-properties
// endpoint, which read-through caches OS Places results per postcode in the
// postcode_search table (30-day TTL) — so repeat searches of the same postcode
// hit our DB, not the OS API. Throws with the server's { error } on failure.
export async function searchAddresses(
  portfolioId: string,
  postcode: string,
): Promise<AddressSearchResult> {
  const res = await fetch(
    `/api/portfolio/${portfolioId}/properties/search?postcode=${encodeURIComponent(postcode)}`,
  );
  if (!res.ok) throw await parseError(res, "Address search failed.");
  return res.json();
}

export interface AssignUprnInput {
  uprn: string;
  address: string;
  postcode: string;
  userInputtedAddress?: string;
  userInputtedPostcode?: string;
}

// Assign a chosen candidate's UPRN + address to a property.
export function useAssignUprn(portfolioId: string, propertyId: string) {
  return useMutation<{ ok: true }, Error, AssignUprnInput>({
    mutationFn: async (input) => {
      const res = await fetch(
        `/api/portfolio/${portfolioId}/properties/${propertyId}`,
        {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(input),
        },
      );
      if (!res.ok) throw await parseError(res, "Failed to assign UPRN.");
      return res.json();
    },
  });
}
