import type { ApiCourseHole, ApiCourseTee } from "@/components/course-template-editor"
import type { Account, ApiGender, Course, Facility, Gender, KnownGuest, Tee } from "./types"

// --- Kjønn-konvertering (samme mønster som new-round.tsx) ------------------

export function apiGenderOf(g: Gender): ApiGender | "x" {
  return g === "mann" ? "m" : g === "kvinne" ? "f" : "x"
}
export function uiGenderOf(g: ApiGender): Gender {
  return g === "m" ? "mann" : "kvinne"
}

// --- Rå API-typer (kun det denne veiviseren faktisk leser) -----------------

type ApiTeeOption = { name: string; genders: ApiGender[] }
type ApiFacility = { slug: string; name: string; city: string | null; county: string | null }
type ApiNearbyFacility = ApiFacility & { distance_km: number }
type ApiOfficialCourseOption = {
  teeoff_course_id: number
  name: string
  is_main_course: boolean
  tees: ApiTeeOption[]
  holes: ApiCourseHole[]
  full_tees: ApiCourseTee[]
}
type ApiPersonalCourse = { id: string; name: string; is_mine: boolean; created_by_display_name: string }
type ApiPersonalCourseDetail = {
  id: string
  name: string
  tees: ApiTeeOption[]
  holes: ApiCourseHole[]
  full_tees: ApiCourseTee[]
  is_mine: boolean
  created_by_display_name: string
  forked_from_id: string | null
}
export type PersonMatch = {
  id: string
  first_name: string
  last_name: string
  avatar_url: string | null
  home_club: string | null
  handicap_index: number | null
}
type ApiKnownGuest = {
  guest_first_name: string
  guest_last_name: string | null
  gender: ApiGender | null
  handicap_index: number | null
}

let idSeq = 0
function newId(prefix: string) {
  idSeq += 1
  return `${prefix}-${idSeq}`
}

function apiTeesToTees(apiTees: ApiTeeOption[]): Tee[] {
  return apiTees.map((t, i) => ({ id: `${t.name}-${i}`, name: t.name, genders: t.genders }))
}

function courseFromOfficial(teeoffCourseId: number, c: {
  name: string
  tees: ApiTeeOption[]
  holes: ApiCourseHole[]
  full_tees: ApiCourseTee[]
}): Course {
  return {
    id: `teeoff-${teeoffCourseId}`,
    name: c.name,
    tees: apiTeesToTees(c.tees),
    templateHoles: c.holes,
    templateTees: c.full_tees,
  }
}

// --- Offisielt banesøk -------------------------------------------------------

export async function searchOfficialFacilities(query: string): Promise<Facility[]> {
  const res = await fetch(`/rounds/official-search?q=${encodeURIComponent(query)}`, { credentials: "include" })
  if (!res.ok) return []
  const data: ApiFacility[] = await res.json()
  return data
}

export async function nearbyOfficialFacilities(lat: number, lng: number): Promise<(Facility & { distanceKm: number })[]> {
  const res = await fetch(`/rounds/official-search/nearby?lat=${lat}&lng=${lng}&limit=5`, { credentials: "include" })
  if (!res.ok) return []
  const data: ApiNearbyFacility[] = await res.json()
  return data.map((f) => ({ slug: f.slug, name: f.name, city: f.city, county: f.county, distanceKm: f.distance_km }))
}

export async function fetchFacilityCourses(slug: string): Promise<{ teeoffCourseId: number; course: Course }[]> {
  const res = await fetch(`/rounds/official-search/${slug}`, { credentials: "include" })
  if (!res.ok) return []
  const data: { slug: string; name: string; courses: ApiOfficialCourseOption[] } = await res.json()
  return data.courses.map((c) => ({
    teeoffCourseId: c.teeoff_course_id,
    course: courseFromOfficial(c.teeoff_course_id, c),
  }))
}

// --- Egne baner ---------------------------------------------------------------

export async function searchOwnCourses(query: string): Promise<{ id: string; name: string }[]> {
  const res = await fetch(`/personal-courses?q=${encodeURIComponent(query)}`, { credentials: "include" })
  if (!res.ok) return []
  const data: ApiPersonalCourse[] = await res.json()
  return data.map((c) => ({ id: c.id, name: c.name }))
}

export async function fetchOwnCourse(id: string): Promise<Course | null> {
  const res = await fetch(`/personal-courses/${id}`, { credentials: "include" })
  if (!res.ok) return null
  const c: ApiPersonalCourseDetail = await res.json()
  return {
    id: c.id,
    name: c.name,
    tees: apiTeesToTees(c.tees),
    templateHoles: c.holes,
    templateTees: c.full_tees,
  }
}

export async function createOwnCourse(body: {
  name: string
  holes: { hole_number: number; par: number; stroke_index: number }[]
  tees: { name: string; ratings: { gender: ApiGender; course_rating: number; slope_rating: number; par: number }[] }[]
  forkedFromId?: string | null
}): Promise<Course> {
  const res = await fetch("/personal-courses", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({
      name: body.name,
      holes: body.holes,
      tees: body.tees,
      forked_from_id: body.forkedFromId ?? null,
    }),
  })
  if (!res.ok) throw new Error(`create: ${res.status}`)
  const created: { id: string; name: string } = await res.json()
  return {
    id: created.id,
    name: created.name,
    tees: body.tees.map((t) => ({
      id: newId(t.name),
      name: t.name,
      genders: t.ratings.map((r) => r.gender),
    })),
  }
}

// --- Internasjonal bane fra GolfAPI.io (ADR-064) ------------------------------
// Importerte baner havner i DEN SAMME personal_course-katalogen som "egen
// bane" over -- derav gjenbruk av fetchOwnCourse for å hente full detalj
// (tees/holes) etter import, samme to-stegs mønster.

export type ApiInternationalCourseOption = { course_id: string; course_name: string; num_holes: number; has_gps: boolean }
export type ApiInternationalClub = {
  club_id: string
  club_name: string
  city: string | null
  country: string | null
  courses: ApiInternationalCourseOption[]
}

export async function searchInternationalClubs(query: string): Promise<ApiInternationalClub[]> {
  const res = await fetch(`/personal-courses/international-search?q=${encodeURIComponent(query)}`, { credentials: "include" })
  if (!res.ok) return []
  return res.json()
}

export async function importInternationalCourse(golfapiCourseId: string): Promise<Course> {
  const importRes = await fetch(`/personal-courses/international-import`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    body: JSON.stringify({ golfapi_course_id: golfapiCourseId }),
  })
  if (!importRes.ok) throw new Error(`international-import: ${importRes.status}`)
  const imported: { id: string } = await importRes.json()
  const course = await fetchOwnCourse(imported.id)
  if (!course) throw new Error("international-import: klarte ikke å hente full banedetalj")
  return course
}

// --- Spillersøk / kjent gjest -------------------------------------------------

export async function searchAccounts(query: string): Promise<Account[]> {
  const res = await fetch(`/people/search?q=${encodeURIComponent(query)}`, { credentials: "include" })
  if (!res.ok) return []
  const data: PersonMatch[] = await res.json()
  return data.map((p) => ({ id: p.id, firstName: p.first_name, lastName: p.last_name, handicap: p.handicap_index }))
}

export async function lookupKnownGuest(email: string): Promise<KnownGuest | null> {
  const res = await fetch(`/rounds/guests/known?email=${encodeURIComponent(email)}`, { credentials: "include" })
  if (!res.ok) return null
  const g: ApiKnownGuest | null = await res.json()
  if (!g) return null
  return {
    firstName: g.guest_first_name,
    lastName: g.guest_last_name ?? "",
    gender: g.gender,
    hcp: g.handicap_index,
  }
}
