import { z } from 'zod'
import { defineDomainRecord } from '../helpers'

// ---------------------------------------------------------------------------
// Firmographics — optional demographic/firmographic filters that describe the
// target customer segment's organizational profile. All fields are optional so
// a segment can declare only the axes relevant to targeting.
// ---------------------------------------------------------------------------

export const FirmographicsSchema = z.object({
  /** Industry vertical (e.g. "Marketing Agency", "Legal", "Real Estate"). */
  industry: z.string().trim().max(200).optional(),
  /**
   * Company headcount band (e.g. "1–10", "11–50", "51–200", "200+").
   * Free-form string to accommodate any band notation.
   */
  companySize: z.string().trim().max(100).optional(),
  /**
   * Primary geographic region the segment operates in or is targeted from
   * (e.g. "North America", "Europe", "Global").
   */
  region: z.string().trim().max(200).optional()
})

// ---------------------------------------------------------------------------
// Customer segment schema — one entry per distinct buyer archetype.
// Modeled after Value Proposition Canvas (BMC / VPC) and Business Model Canvas
// customer-segment language. Fields use plain English throughout.
// ---------------------------------------------------------------------------

export const CustomerSegmentSchema = z.object({
  /** Stable unique identifier for the segment (e.g. "segment-smb-agencies"). */
  id: z.string().trim().min(1).max(100),
  /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
  order: z.number(),
  /** Human-readable name shown to agents and in UI (e.g. "SMB Marketing Agencies"). */
  name: z.string().trim().max(200).default(''),
  /** One or two sentences describing who this segment is. */
  description: z.string().trim().max(2000).default(''),
  /**
   * The primary job(s) this segment is trying to get done — the goal they hire
   * a product/service to accomplish. Plain-language narrative or bullet list.
   */
  jobsToBeDone: z.string().trim().max(2000).default(''),
  /**
   * Pains — frustrations, obstacles, and risks the segment experiences
   * when trying to accomplish their jobs-to-be-done.
   */
  pains: z.array(z.string().trim().max(500)).default([]),
  /**
   * Gains — outcomes and benefits the segment desires; positive motivators
   * beyond merely resolving pains.
   */
  gains: z.array(z.string().trim().max(500)).default([]),
  /** Firmographic profile for targeting and filtering. */
  firmographics: FirmographicsSchema.default({}),
  /**
   * Value proposition — one or two sentences stating why this organization's
   * offering is uniquely suited for this segment's needs.
   */
  valueProp: z.string().trim().max(2000).default('')
})

// ---------------------------------------------------------------------------
// Customers domain schema — id-keyed map of customer segments.
// ---------------------------------------------------------------------------

export const CustomersDomainSchema = z
  .record(z.string(), CustomerSegmentSchema)
  .refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
    message: 'Each segment entry id must match its map key'
  })
  .default({})

// ---------------------------------------------------------------------------
// Seed — empty by default; adapters populate with real segment definitions.
// ---------------------------------------------------------------------------

export const DEFAULT_ORGANIZATION_MODEL_CUSTOMERS: z.infer<typeof CustomersDomainSchema> = {}

/** Validate and return a single customer segment entry. */
export function defineCustomer(entry: z.input<typeof CustomerSegmentSchema>): z.infer<typeof CustomerSegmentSchema> {
  return CustomerSegmentSchema.parse(entry)
}

/** Validate and return an id-keyed map of customer segment entries. */
export function defineCustomers(
  entries: readonly z.input<typeof CustomerSegmentSchema>[]
): Record<string, z.infer<typeof CustomerSegmentSchema>> {
  return defineDomainRecord(CustomerSegmentSchema, entries)
}

export type CustomerSegment = z.infer<typeof CustomerSegmentSchema>
export type CustomersDomain = z.infer<typeof CustomersDomainSchema>
export type Firmographics = z.infer<typeof FirmographicsSchema>
