import type {
  Crumb,
  CrumbPlace,
  CrumbSource,
  ExtractCrumbDraft,
  PlaceRef,
} from '@crumbs/core/schemas'

// a crumb being composed: at most one resolved target (placeRef | placeId),
// otherwise free-form hints that become a provisional place on save
export type Draft = {
  name: string
  note: string | null
  tags: string[]
  source: CrumbSource
  sourceId: string | null
  imageUrl: string | null
  placeRef: PlaceRef | null
  placeId: string | null
  place: CrumbPlace | null
  address: string | null
  latitude: number | null
  longitude: number | null
  category: string | null
}

export const emptyDraft: Draft = {
  name: '',
  note: null,
  tags: [],
  source: 'manual',
  sourceId: null,
  imageUrl: null,
  placeRef: null,
  placeId: null,
  place: null,
  address: null,
  latitude: null,
  longitude: null,
  category: null,
}

export const placeToDraft = (ref: PlaceRef): Draft => ({
  ...emptyDraft,
  name: ref.name,
  placeRef: ref,
  address: ref.address ?? null,
  category: ref.category ?? null,
})

export const coordsToDraft = (coordinate: {
  latitude: number
  longitude: number
}): Draft => ({
  ...emptyDraft,
  latitude: coordinate.latitude,
  longitude: coordinate.longitude,
})

export const crumbToDraft = (crumb: Crumb): Draft => ({
  ...emptyDraft,
  name: crumb.name,
  note: crumb.note,
  tags: crumb.tags.map((t) => t.name),
  source: crumb.source,
  imageUrl: crumb.imageUrl,
  placeId: crumb.place?.id ?? null,
  place: crumb.place,
  address: crumb.place?.address ?? null,
  category: crumb.place?.category ?? null,
})

export const extractToDraft = (
  extract: ExtractCrumbDraft,
): Draft => ({
  ...emptyDraft,
  name: extract.name,
  note: extract.note,
  tags: extract.tags,
  source: extract.source,
  sourceId: extract.sourceId,
  imageUrl: extract.imageUrl,
  placeId: extract.placeId,
  place: extract.place,
  address:
    extract.place?.address ?? extract.placeDraft?.address ?? null,
  category: extract.place?.category ?? null,
})

// resolved place data is canonical — user edits to it belong on the
// crumb (or a fresh provisional place), never on the shared entity
export const hasCanonicalPlace = (draft: Draft): boolean =>
  draft.placeRef != null || draft.place?.status === 'canonical'

export const hasLocation = (draft: Draft): boolean =>
  draft.placeRef != null ||
  draft.place != null ||
  draft.latitude != null ||
  draft.address != null
