import { z } from 'zod'
import { DescriptionSchema, DisplayMetadataSchema, ModelIdSchema, ReferenceIdsSchema } from './shared'

export type { LeadGenStageCatalogEntry } from '../catalogs/lead-gen'

// OrganizationModelSalesSchema and DEFAULT_ORGANIZATION_MODEL_SALES are retired.
// Pipeline/stage data lives in System.ontology.catalogTypes on the owning system
// (e.g. sales.crm). Use getAllPipelines() / getStagesInPipeline() from
// migration-helpers to read pipeline data portably.
//
// SalesStageSemanticClassSchema, SalesStageSchema, SalesPipelineSchema are retained
// below as TypeScript types used by generic CRM business logic and stateful
// pipeline definitions. Elevasis CRM runtime constants live in @repo/elevasis-core.

export const SalesStageSemanticClassSchema = z.enum(['open', 'active', 'nurturing', 'closed_won', 'closed_lost'])

export const SalesStageSchema = DisplayMetadataSchema.extend({
  id: ModelIdSchema,
  order: z.number().int().min(0),
  semanticClass: SalesStageSemanticClassSchema,
  surfaceIds: ReferenceIdsSchema,
  resourceIds: ReferenceIdsSchema
})

export const SalesPipelineSchema = z.object({
  id: ModelIdSchema,
  label: z.string().trim().min(1).max(120),
  description: DescriptionSchema.optional(),
  entityId: ModelIdSchema,
  stages: z.array(SalesStageSchema).min(1)
})

// ============================================================================
// Generic Stateful Pipeline Types
// ============================================================================

/** One state within a stage: minimal shape of key + display label. */
export interface StatefulStateDefinition {
  /** Matches state_key values written by workflow steps. */
  stateKey: string
  label: string
}

/** One stage within a pipeline: has a stage_key and ordered valid states. */
export interface StatefulStageDefinition {
  /** Matches stage_key values written by workflow steps. */
  stageKey: string
  label: string
  /** UI color token. Consumers may map this to their design system. */
  color?: string
  states: StatefulStateDefinition[]
}

/**
 * Pipeline definition for a single entity participating in the Stateful trait.
 * Parallel to acq_deals' pipeline_key concept but structured for any entity.
 */
export interface StatefulPipelineDefinition {
  /** Matches pipeline_key values in the database. */
  pipelineKey: string
  label: string
  /** Entity this pipeline applies to. */
  entityKey: string
  stages: StatefulStageDefinition[]
}

export type CrmPriorityBucketKey = 'needs_response' | 'follow_up_due' | 'waiting' | 'stale' | 'closed_low'

export interface CrmPriorityBucketDefinition {
  bucketKey: CrmPriorityBucketKey
  label: string
  /** Lower ranks sort first in deal lists and pipeline columns. */
  rank: number
  /** UI color token. Consumers may map this to their design system. */
  color: string
}

export interface CrmPriorityRuleConfig {
  buckets: CrmPriorityBucketDefinition[]
  closedStageKeys: string[]
  followUpAfterDaysByStateKey: Record<string, number>
  staleAfterDays: number
}

/**
 * Find a pipeline definition by pipeline_key within an array of definitions.
 * Preferred over direct array indexing since the model is array-based.
 */
export function findPipeline(
  definitions: StatefulPipelineDefinition[],
  pipelineKey: string
): StatefulPipelineDefinition | undefined {
  return definitions.find((def) => def.pipelineKey === pipelineKey)
}

/**
 * Returns the valid states for a given stage within a pipeline definition.
 * Returns an empty array if the stage is not found.
 */
export function getValidStatesForStage(
  definition: StatefulPipelineDefinition,
  stageKey: string
): StatefulStateDefinition[] {
  return definition.stages.find((s) => s.stageKey === stageKey)?.states ?? []
}

// ============================================================================
// CRM Next-Action Rule Config Types
//
// Generic rule config types only. Elevasis-specific CRM runtime mappings live
// in @repo/elevasis-core, not in the published @repo/core surface.
// ============================================================================

export interface CrmNextActionMapping {
  /** state_key to match, or '*' for any state. */
  stateKey: string
  /** ownership value to match ('us' | 'them'), or '*' for any. */
  ownership: 'us' | 'them' | '*'
  /** Action key from a caller-supplied action catalog. */
  actionKey: string
  /**
   * When true, this mapping only fires if age >= staleAfterDays.
   * Defaults to false.
   */
  requiresStale?: boolean
}

export interface CrmNextActionRuleConfig {
  mappings: CrmNextActionMapping[]
  /** Fallback action key when ownership === 'us' and no explicit mapping matches. */
  ownershipUsFallback?: string | null
}
