/**
 * Dreamify partner listing schema v1 — TypeScript types.
 * Same shape as /schema/listing.v1.schema.json. Money is in minor units (cents).
 * Type ids and destinations come from the shared DFB tree (GET /v1/taxonomy).
 */

export type ListingTypeId =
  | 'publish.image'
  | 'publish.article'
  | 'publish.news'
  | 'publish.video'
  | 'publish.podcast'
  | 'publish.music'
  | 'publish.profile'
  | 'local.profile'
  | 'local.deal'
  | 'local.item'
  | 'local.job'
  | 'local.menu'
  | 'local.service'
  | 'venues.profile'
  | 'local.ride'
  | 'local.activity'
  | 'travel.stay'
  | 'travel.package'
  | 'travel.retreat'
  | 'travel.adventure'
  | 'travel.car'
  | 'travel.cruise'
  | 'travel.deal'
  | 'host.event'
  | 'host.activity'
  | 'host.tour'
  | 'host.class'
  | 'host.retreat'
  | 'teach.course'
  | 'teach.workshop'
  | 'teach.cohort'
  | 'teach.coaching'
  | 'teach.webinar'
  | 'teach.instructor'
  | 'teach.membership'
  | 'sell.product'
  | 'sell.service'
  | 'sell.digital'
  | 'sell.subscription'
  | 'sell.gift-card'
  | 'sell.bundle'
  | 'talent.performer'
  | 'talent.creator'
  | 'talent.professional'
  | 'inspire.idea'
  | 'inspire.list'
  | 'inspire.challenge'
  | 'inspire.guide'
  | 'community.group'
  | 'community.club'
  | 'community.team'

export type DestinationId =
  | 'shop'
  | 'explore.images'
  | 'explore.articles'
  | 'explore.news'
  | 'explore.videos'
  | 'explore.podcasts'
  | 'explore.music'
  | 'explore.people'
  | 'local.places'
  | 'deals'
  | 'marketplace'
  | 'local.jobs'
  | 'local.meals'
  | 'local.services'
  | 'your-store'
  | 'local-venues'
  | 'local.rides'
  | 'local.activities'
  | 'travel.stays'
  | 'travel.packages'
  | 'travel.retreats'
  | 'travel.adventures'
  | 'travel.cars'
  | 'travel.cruises'
  | 'travel.deals'
  | 'travel.flights'
  | 'experiences'
  | 'learn'
  | 'learn.instructors'
  | 'local-talent'
  | 'ideas'
  | 'dream.lists'
  | 'dream.challenges'
  | 'community.groups'
  | 'feed'
  | 'cities'

export type ListingStatus = 'pending_review' | 'approved' | 'published' | 'rejected' | 'paused' | 'expired' | 'removed'

export interface MediaItem { url: string; type?: 'image' | 'video'; alt?: string; width?: number; height?: number }
export interface Price {
  amount_cents?: number
  /** Alternative to amount_cents, in major units. */
  amount?: number
  currency?: string
  unit?: 'total' | 'per_person' | 'per_item' | 'per_night' | 'per_hour' | 'per_day' | 'per_week' | 'per_month' | 'per_session'
  from?: boolean
  free?: boolean
}
export interface Offer { id?: string; name: string; price_cents?: number; original_price_cents?: number; currency?: string; quantity?: number; valid_from?: string; valid_to?: string }
export interface Session { id?: string; starts_at: string; ends_at?: string; capacity?: number; remaining?: number; price_cents?: number }

export interface ExperienceBlock {
  schedule_mode?: 'single' | 'multi' | 'weekly' | 'flexible'
  duration_minutes?: number; highlights?: string[]; included?: string[]; excluded?: string[]
  meeting_point?: string; min_age?: number; languages?: string[]; accessibility?: string[]; cancellation_policy?: string
}
export interface DealBlock {
  deal_category?: string; original_price_cents: number; deal_price_cents: number; discount_percent?: number
  fine_print?: string; redeem_by?: string; voucher_type?: 'voucher' | 'promo_code' | 'instant' | 'booking'
  promo_code?: string; max_per_customer?: number; quantity_available?: number
}
export interface ProductBlock {
  sku?: string; brand?: string; gtin?: string; condition?: 'new' | 'used' | 'refurbished'
  availability?: 'in_stock' | 'out_of_stock' | 'preorder' | 'limited'; digital?: boolean
  shipping?: { regions?: string[]; price_cents?: number; days?: number }
  variants?: { sku?: string; name: string; price_cents?: number }[]
}
export interface CourseBlock {
  format?: 'online' | 'in_person' | 'hybrid' | 'self_paced'; level?: 'beginner' | 'intermediate' | 'advanced' | 'all'
  duration_hours?: number; lessons_count?: number; certificate?: boolean; instructor?: { name?: string; bio?: string }; prerequisites?: string[]
}
export interface StayBlock {
  property_type?: string; bedrooms?: number; bathrooms?: number; max_guests?: number; amenities?: string[]
  check_in?: string; check_out?: string; min_nights?: number; rate_unit?: 'hour' | 'day' | 'night' | 'week' | 'month'; deposit_cents?: number
}
export interface ProfileBlock {
  kind?: 'talent' | 'venue'; headline?: string; capacity?: number; rate_cents?: number
  rate_unit?: 'hour' | 'day' | 'event' | 'set' | 'project'; genres?: string[]; skills?: string[]; amenities?: string[]; portfolio_urls?: string[]
}
export interface StudioBlock { duration_seconds?: number; embed_url?: string; season?: number; episode?: number; published_at?: string }

export interface PartnerListingV1 {
  external_id: string
  type: ListingTypeId
  destinations?: DestinationId[]
  title: string
  summary?: string
  description?: string
  language?: string
  tags?: string[]
  /** Test content. Sample listings can never go live. */
  sample?: boolean
  category?: { cat?: string; sub?: string; kind?: string }
  /** DreamSuite Market taxonomy id (GET /v1/taxonomy → market), e.g. "places.restaurants". */
  market?: string
  place?: { city?: string; region?: string; country?: string; place_id?: string; online?: boolean }
  location?: { name?: string; address?: string; postal_code?: string; lat?: number; lng?: number }
  media?: MediaItem[]
  price?: Price
  offers?: Offer[]
  starts_at?: string
  ends_at?: string
  timezone?: string
  sessions?: Session[]
  booking?: { mode?: 'handoff' | 'native'; url?: string; phone?: string }
  booking_url?: string
  expires_at?: string
  rating?: { value?: number; count?: number }
  experience?: ExperienceBlock
  deal?: DealBlock
  product?: ProductBlock
  course?: CourseBlock
  stay?: StayBlock
  profile?: ProfileBlock
  studio?: StudioBlock
}

export interface RowError { path: string; code: string; message: string }
export interface RowResult {
  index: number
  external_id: string | null
  result: 'created' | 'updated' | 'unchanged' | 'failed' | 'valid'
  id?: string
  status?: ListingStatus
  errors?: RowError[]
  warnings?: RowError[]
  checks?: { passed: boolean; blocking: number; problems: { id: string; severity: 'block' | 'warn'; message: string }[] }
}
