/**
 * Lead Service Types
 * CRUD operation types for the acquisition platform (lists, companies, contacts, deals)
 *
 * Implementation: apps/api/src/acquisition/lead-service.ts (LeadService class)
 */

import type { Json } from '../../../supabase'

// Re-export acquisition domain types from the authoritative source
import type {
  AcqList,
  AcqCompany,
  AcqContact,
  AcqDealTask,
  AcqDealTaskKind,
  ListStatus,
  ScrapingConfig,
  IcpRubric,
  PipelineConfig,
  ProcessingState,
  ListTelemetry,
  DealDetail
} from '../../../business/acquisition/types'
import type { ListProgress, ProcessingStageStatus } from '../../../business/acquisition/api-schemas'

export type {
  AcqList,
  AcqCompany,
  AcqContact,
  AcqDealTask,
  AcqDealTaskKind,
  ListStatus,
  ScrapingConfig,
  IcpRubric,
  PipelineConfig,
  ProcessingState,
  ProcessingStageStatus,
  ListTelemetry,
  DealDetail,
  ListProgress
}

// Pagination types
export interface PaginationParams {
  limit: number
  offset: number
}

export interface PaginatedResult<T> {
  data: T[]
  total: number
  limit: number
  offset: number
}

// List params
export interface CreateListParams {
  organizationId: string
  name: string
  description?: string
  type?: string
  batchIds?: string[]
  instantlyCampaignId?: string
  status?: ListStatus
  buildTemplateId?: string
  metadata?: Record<string, unknown>
  scrapingConfig?: ScrapingConfig
  icp?: IcpRubric
  pipelineConfig?: PipelineConfig
}

export interface UpdateListParams {
  name?: string
  description?: string
  batchIds?: string[]
}

export interface UpdateListStatusParams {
  organizationId: string
  listId: string
  status: ListStatus
}

// Company params
export interface CreateCompanyParams {
  organizationId: string
  name: string
  domain?: string
  linkedinUrl?: string
  website?: string
  numEmployees?: number
  foundedYear?: number
  locationCity?: string
  locationState?: string
  category?: string
  source?: string
  batchId?: string
  verticalResearch?: string
  /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
  pipelineStatus?: unknown
}

export interface UpdateCompanyParams {
  name?: string
  domain?: string
  linkedinUrl?: string
  website?: string
  numEmployees?: number
  foundedYear?: number
  locationCity?: string
  locationState?: string
  category?: string
  segment?: string
  processingState?: ProcessingState
  /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
  pipelineStatus?: unknown
  enrichmentData?: Record<string, unknown>
  source?: string
  batchId?: string
  status?: 'active' | 'invalid'
  verticalResearch?: string | null
  /** Track A: flat qualification score column (null until a scoring rubric is defined) */
  qualificationScore?: number | null
  /** Track A: flat qualification signals jsonb */
  qualificationSignals?: Record<string, unknown> | null
  /** Track A: key identifying the rubric used for qualification */
  qualificationRubricKey?: string | null
}

export type UpsertCompanyParams = CreateCompanyParams
// Upsert by domain - uses same fields as create

export interface CompanyFilters {
  listId?: string // Filter to companies in a specific list (via acq_list_companies)
  search?: string
  domain?: string
  website?: string
  segment?: string
  category?: string
  processingState?: ProcessingState
  /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
  pipelineStatus?: unknown
  /** Exclude companies whose processing state contains this value (PostgREST NOT contains) */
  processingStateNot?: ProcessingState
  batchId?: string
  status?: 'active' | 'invalid'
  includeAll?: boolean
  excludeColumns?: Array<'enrichmentData' | 'processingState'>
  limit?: number
}

// Contact params
export interface CreateContactParams {
  organizationId: string
  email: string
  companyId?: string
  firstName?: string
  lastName?: string
  linkedinUrl?: string
  title?: string
  source?: string
  sourceId?: string
  batchId?: string
  /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
  pipelineStatus?: unknown
}

export interface UpdateContactParams {
  companyId?: string
  emailValid?: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN'
  firstName?: string
  lastName?: string
  linkedinUrl?: string
  title?: string
  headline?: string
  filterReason?: string
  openingLine?: string
  processingState?: ProcessingState
  /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
  pipelineStatus?: unknown
  enrichmentData?: Record<string, unknown>
  status?: 'active' | 'invalid'
}

export type UpsertContactParams = CreateContactParams
// Upsert by email - uses same fields as create

export interface ContactFilters {
  listId?: string // Filter to contacts in a specific list (via acq_list_members)
  search?: string
  openingLineIsNull?: boolean // Filter to contacts without personalization
  processingState?: ProcessingState
  /** @deprecated Use processingState. Accepted as a no-op compatibility bridge for external tenants. */
  pipelineStatus?: unknown
  batchId?: string
  contactStatus?: 'active' | 'invalid' // Filter by contact status (soft-delete flag)
}

// Deal params (for acq_deals table)
export interface UpsertDealParams {
  organizationId: string
  /** Contact email — dedupe key together with organization_id */
  contactEmail: string
  /** Optional contact ID for foreign key join */
  contactId?: string
  /** Campaign list that generated this deal (FK to acq_lists) */
  sourceListId?: string
  /** Deal origin: 'instantly', 'referral', 'inbound', 'manual' */
  sourceType?: 'instantly' | 'referral' | 'inbound' | 'manual'
  /** Optional discovery data JSONB to set on upsert */
  discoveryData?: unknown
  /** Optional proposal data JSONB to set on upsert */
  proposalData?: unknown
  /** Instantly email UUID used to hydrate the reply thread */
  instantlyThreadUuid?: string
  /** Instantly sender account for direction detection */
  instantlyEmailAccount?: string
}

export interface UpdateDiscoveryDataParams {
  organizationId: string
  contactEmail: string
  discoveryData: unknown
  submittedBy?: string
}

export interface UpdateProposalDataParams {
  organizationId: string
  contactEmail: string
  proposalData: unknown
  proposalPdfUrl?: string
}

export interface MarkProposalSentParams {
  organizationId: string
  contactEmail: string
}

export interface MarkProposalReviewedParams {
  organizationId: string
  contactEmail: string
  reviewedBy: string
  proposalData?: unknown
}

export interface UpdateCloseLostReasonParams {
  organizationId: string
  dealId: string
  reason: string
}

export interface UpdateFeesParams {
  organizationId: string
  contactEmail?: string
  dealId?: string
  initialFee?: number
  monthlyFee?: number
}

export interface CacheInstantlyThreadIdsParams {
  organizationId: string
  dealId: string
  instantlyThreadUuid: string
  instantlyEmailAccount: string
}

export interface TransitionItemParams {
  organizationId: string
  dealId: string
  pipelineKey: string
  stageKey: string
  stateKey?: string | null
  reason?: string
  expectedUpdatedAt?: string
}

export interface SetContactNurtureParams {
  organizationId: string
  contactEmail: string
  nurture?: boolean
}

export interface DeactivateContactsByCompanyParams {
  organizationId: string
  companyId: string
}

export interface DeactivateContactsByCompanyResult {
  deactivated: number
}

export interface CancelSchedulesAndHitlByEmailParams {
  organizationId: string
  email: string
}

export interface CancelHitlByDealIdParams {
  organizationId: string
  dealId: string
}

export interface ClearDealFieldsParams {
  organizationId: string
  contactEmail?: string
  dealId?: string
  fields: (
    | 'proposalPdfUrl'
    | 'proposalGeneratedAt'
    | 'initialFee'
    | 'monthlyFee'
    | 'closedLostReason'
    | 'closedLostAt'
    | 'discoveryData'
    | 'discoverySubmittedAt'
  )[]
}

export interface DeleteDealParams {
  organizationId: string
  dealId: string
}

export interface GetDealByIdParams {
  dealId: string
  organizationId: string
}

export interface GetContactByIdParams {
  contactId: string
  organizationId: string
}

export interface GetCompanyByIdParams {
  companyId: string
  organizationId: string
}

// Social monitoring params (acq_social_posts table)
export interface UpsertSocialPostParams {
  organizationId: string
  platform: string
  platformPostId: string
  authorName: string
  authorUrl?: string | null
  postTitle: string
  postText: string
  postUrl: string
  engagementCount?: number
  commentsCount?: number
  postedAt: string
  metadata?: Record<string, unknown>
  relevanceScore?: number
  matchedKeywords?: string[]
  matchedQuery?: string | null
  initialDraft?: string | null
  finalResponse?: string | null
  sourceCategory?: string | null
}

export interface UpsertSocialPostsParams {
  organizationId: string
  posts: Omit<UpsertSocialPostParams, 'organizationId'>[]
}

export interface UpsertSocialPostsResult {
  inserted: number
  duplicatesSkipped: number
}

export interface AcqDeal {
  id: string
  organizationId: string
  contactEmail: string
  pipelineKey: string
  stageKey?: string | null
  stateKey?: string | null
  discoveryData?: Json | null
  proposalData?: Json | null
  proposalSentAt?: string | null
  proposalPdfUrl?: string | null
  signatureEnvelopeId?: string | null
  sourceListId?: string | null
  sourceType?: string | null
  activityLog: DealActivityEntry[]
  createdAt: Date
  updatedAt: Date
}

export interface DealActivityEntry {
  type: string
  title: string
  description?: string
  payload?: Record<string, unknown>
  occurredAt: string
}

export interface AcqDealNote {
  id: string
  dealId: string
  organizationId: string
  authorUserId: string | null
  body: string
  createdAt: string
  updatedAt: string
}

export interface CreateDealNoteParams {
  organizationId: string
  dealId: string
  body: string
  authorUserId?: string
}

export interface ListDealNotesParams {
  organizationId: string
  dealId: string
}

export interface CreateDealTaskParams {
  organizationId: string
  dealId: string
  title: string
  description?: string | null
  kind?: AcqDealTaskKind
  dueAt?: string | null
  assigneeUserId?: string | null
  createdByUserId?: string | null
}

export interface ListDealTasksParams {
  organizationId: string
  dealId: string
}

export interface ListDealTasksDueParams {
  organizationId: string
  assigneeUserId?: string | null
  /** Window filter: 'overdue' = past due, 'today' = due today only, 'today_and_overdue' (default) = both, 'upcoming' = future */
  window?: 'overdue' | 'today' | 'today_and_overdue' | 'upcoming'
}

export interface CompleteDealTaskParams {
  organizationId: string
  taskId: string
  completedByUserId: string | null
}

export interface RecordDealActivityParams {
  organizationId: string
  dealId: string
  type: string
  title: string
  description?: string
  payload?: Record<string, unknown>
}

export interface SetDealStateKeyParams {
  organizationId: string
  dealId: string
  stateKey: string
}

export interface TransitionDealParams {
  organizationId: string
  dealId: string
  toStage: string
  toState?: string
}

export interface LoadDealParams {
  organizationId: string
  dealId: string
}

// Deal analytics types (for /meta status and platform-status workflow)

export interface DealStageSummary {
  stage: string
  count: number
  oldestUpdatedAt: string | null
  newestUpdatedAt: string | null
}

export interface StaleDeal {
  id: string
  contactEmail: string
  stageKey: string
  updatedAt: string
  daysStale: number
}

export interface DealPipelineAnalytics {
  totalDeals: number
  stageSummary: DealStageSummary[]
  staleDeals: StaleDeal[]
  recentActivity: AcqDeal[]
}

export interface DealAnalyticsParams {
  organizationId: string
  recentLimit?: number
}

export interface DealFilters {
  stage?: string
  search?: string
  limit?: number
  offset?: number
}

export interface AddContactsToListParams {
  organizationId: string
  listId: string
  contactIds: string[]
}

export interface AddContactsToListResult {
  added: number
  alreadyExisted: number
}

// List config/progress/executions params
export interface UpdateListConfigParams {
  organizationId: string
  listId: string
  scrapingConfig?: ScrapingConfig
  icp?: IcpRubric
  pipelineConfig?: PipelineConfig
}

export interface UpdateCompanyStageParams {
  organizationId: string
  listId: string
  companyId: string
  stage: string
  status?: ProcessingStageStatus
  data?: unknown
  executionId?: string
}

export interface UpdateContactStageParams {
  organizationId: string
  listId: string
  contactId: string
  stage: string
  status?: ProcessingStageStatus
  data?: unknown
  executionId?: string
}

export interface ClearCompanyStagesParams {
  organizationId: string
  listId: string
  companyId: string
  stages: string[]
}

export interface ClearContactStagesParams {
  organizationId: string
  listId: string
  contactId: string
  stages: string[]
}

export interface ListPendingCompanyIdsParams {
  organizationId: string
  listId: string
  stageKey: string
  limit?: number
}

export interface ListPendingContactIdsParams {
  organizationId: string
  listId: string
  stageKey: string
  limit?: number
}

export interface AddCompaniesToListParams {
  organizationId: string
  listId: string
  companyIds: string[]
}

export interface AddCompaniesToListResult {
  added: number
  alreadyExisted: number
}

export interface RemoveCompaniesFromListParams {
  organizationId: string
  listId: string
  companyIds: string[]
}

export interface RemoveCompaniesFromListResult {
  removed: number
}

export interface RecordListExecutionParams {
  organizationId: string
  listId: string
  executionId: string
  configSnapshot?: Record<string, unknown>
}

export interface ListExecutionSummary {
  executionId: string
  resourceId: string
  status: string
  createdAt: string
  completedAt: string | null
  durationMs: number | null
  input?: unknown
}

// Bulk import (contacts)
export interface BulkImportParams {
  organizationId: string
  contacts: CreateContactParams[]
  listId?: string
}

export interface BulkImportResult {
  created: number
  updated: number
  errors: Array<{ email: string; error: string }>
}

// Bulk import (companies)
export interface BulkImportCompanyEntry {
  name: string
  domain: string
  website?: string
  locationCity?: string
  locationState?: string
  category?: string
  source?: string
  enrichmentData?: Record<string, unknown>
  processingState?: ProcessingState
}

export interface BulkImportCompaniesParams {
  organizationId: string
  batchId: string
  companies: BulkImportCompanyEntry[]
}

export interface BulkImportCompaniesResult {
  created: number
  skipped: number
  errors: Array<{ companyName: string; error: string }>
}

/**
 * Lead Service interface for acquisition platform tools.
 * Provides CRUD operations for lists, companies, and contacts.
 *
 * Implementation: apps/api/src/acquisition/lead-service.ts (LeadService class)
 *
 * Multi-tenancy: All operations require organizationId for tenant isolation.
 * All queries are filtered by organizationId via RLS policies.
 */
export interface ILeadService {
  // List operations
  /**
   * Create a new list
   * @see LeadService.createList (apps/api/src/acquisition/lead-service.ts)
   */
  createList(params: CreateListParams): Promise<AcqList>

  /**
   * Update an existing list
   * @see LeadService.updateList (apps/api/src/acquisition/lead-service.ts)
   */
  updateList(id: string, params: UpdateListParams): Promise<AcqList>

  /**
   * Delete a list
   * @see LeadService.deleteList (apps/api/src/acquisition/lead-service.ts)
   */
  deleteList(id: string, organizationId: string): Promise<void>

  /**
   * Add contacts to a list (upsert — idempotent on re-runs)
   * @see LeadService.addContactsToList (apps/api/src/business/acquisition/lead-service.ts)
   */
  addContactsToList(params: AddContactsToListParams): Promise<AddContactsToListResult>

  /**
   * List all lists for an organization
   * @see LeadService.listLists (apps/api/src/acquisition/lead-service.ts)
   */
  listLists(organizationId: string): Promise<AcqList[]>

  /**
   * Get a single list by ID.
   */
  getList(id: string, organizationId: string): Promise<AcqList | null>

  /**
   * Deep-merge patch the jsonb `config` column. Patch keys at any depth
   * replace the corresponding subtree.
   */
  updateListConfig(params: UpdateListConfigParams): Promise<AcqList>

  /**
   * Add companies to a list via the acq_list_companies junction.
   * Idempotent on (list_id, company_id).
   */
  addCompaniesToList(params: AddCompaniesToListParams): Promise<AddCompaniesToListResult>

  /**
   * Remove companies from a list (delete junction rows only — company rows untouched).
   */
  removeCompaniesFromList(params: RemoveCompaniesFromListParams): Promise<RemoveCompaniesFromListResult>

  /**
   * Live org-wide list telemetry — computed on demand from acq_companies
   * and acq_contacts joined through the acq_list_companies / acq_list_members
   * junctions. Replaces the batch-scoped getBatchTelemetry.
   */
  getListsTelemetry(organizationId: string): Promise<ListTelemetry[]>

  /**
   * On-demand progress aggregation: COUNT(*) FILTER over processing_state flags,
   * keyed by the list's pipeline_config.stages[].key (Decision #4 + #7).
   */
  getListProgress(listId: string, organizationId: string): Promise<ListProgress | null>

  /**
   * Advance a company row within a list's explicit stage journey.
   */
  updateCompanyStage(params: UpdateCompanyStageParams): Promise<void>

  /**
   * Advance a contact row within a list's explicit stage journey.
   */
  updateContactStage(params: UpdateContactStageParams): Promise<void>

  /**
   * Clear company stage entries by deleting keys from processing_state.
   * Missing stage keys represent "not attempted"; never persist null markers.
   */
  clearCompanyStages(params: ClearCompanyStagesParams): Promise<void>

  /**
   * Clear contact stage entries by deleting keys from processing_state.
   * Missing stage keys represent "not attempted"; never persist null markers.
   */
  clearContactStages(params: ClearContactStagesParams): Promise<void>

  /**
   * Return the company_ids in acq_list_companies for the given list where
   * processing_state[stageKey].status is NULL or NOT IN ('success', 'no_result').
   * Used by build-pipeline workflows to skip already-processed records.
   */
  listPendingCompanyIds(params: ListPendingCompanyIdsParams): Promise<string[]>

  /**
   * Return the contact_ids in acq_list_members for the given list where
   * processing_state[stageKey].status is NULL or NOT IN ('success', 'no_result').
   * Used by build-pipeline workflows to skip already-processed records.
   */
  listPendingContactIds(params: ListPendingContactIdsParams): Promise<string[]>

  /**
   * Per-list execution history — reads via the feature-owned
   * acq_list_executions junction, joined to execution_logs for details.
   */
  getListExecutions(listId: string, organizationId: string): Promise<ListExecutionSummary[]>

  /**
   * Write a junction row linking (listId, executionId). Called by the
   * workflow layer at execution start in Step 4. No-op if the row exists.
   */
  recordListExecution(params: RecordListExecutionParams): Promise<void>

  // Company operations
  /**
   * Create a new company
   * @see LeadService.createCompany (apps/api/src/acquisition/lead-service.ts)
   */
  createCompany(params: CreateCompanyParams): Promise<AcqCompany>

  /**
   * Update an existing company
   * @see LeadService.updateCompany (apps/api/src/acquisition/lead-service.ts)
   */
  updateCompany(id: string, params: UpdateCompanyParams): Promise<AcqCompany>

  /**
   * Upsert a company by domain
   * @see LeadService.upsertCompany (apps/api/src/acquisition/lead-service.ts)
   */
  upsertCompany(params: UpsertCompanyParams): Promise<AcqCompany>

  /**
   * Get a company by ID
   * @see LeadService.getCompany (apps/api/src/acquisition/lead-service.ts)
   */
  getCompany(id: string, organizationId: string): Promise<AcqCompany | null>

  /**
   * List companies with optional filters
   * @see LeadService.listCompanies (apps/api/src/acquisition/lead-service.ts)
   */
  listCompanies(organizationId: string, filters: CompanyFilters): Promise<AcqCompany[]>

  /**
   * Delete a company
   * @see LeadService.deleteCompany (apps/api/src/acquisition/lead-service.ts)
   */
  deleteCompany(id: string, organizationId: string): Promise<void>

  // Contact operations
  /**
   * Create a new contact
   * @see LeadService.createContact (apps/api/src/acquisition/lead-service.ts)
   */
  createContact(params: CreateContactParams): Promise<AcqContact>

  /**
   * Update an existing contact
   * @see LeadService.updateContact (apps/api/src/acquisition/lead-service.ts)
   */
  updateContact(id: string, params: UpdateContactParams): Promise<AcqContact>

  /**
   * Upsert a contact by email
   * @see LeadService.upsertContact (apps/api/src/acquisition/lead-service.ts)
   */
  upsertContact(params: UpsertContactParams): Promise<AcqContact>

  /**
   * Get a contact by ID
   * @see LeadService.getContact (apps/api/src/acquisition/lead-service.ts)
   */
  getContact(id: string, organizationId: string): Promise<AcqContact | null>

  /**
   * List contacts with pagination and filters
   * @see LeadService.listContacts (apps/api/src/acquisition/lead-service.ts)
   */
  listContacts(
    organizationId: string,
    filters: ContactFilters,
    pagination: PaginationParams
  ): Promise<PaginatedResult<AcqContact>>

  /**
   * Delete a contact
   * @see LeadService.deleteContact (apps/api/src/acquisition/lead-service.ts)
   */
  deleteContact(id: string, organizationId: string): Promise<void>

  /**
   * Bulk import contacts
   * @see LeadService.bulkImportContacts (apps/api/src/acquisition/lead-service.ts)
   */
  bulkImportContacts(params: BulkImportParams): Promise<BulkImportResult>

  /**
   * Bulk import companies with domain dedup (skips existing domains).
   * Inserts in batches using Supabase bulk insert + ON CONFLICT.
   * @see LeadService.bulkImportCompanies (apps/api/src/business/acquisition/lead-service.ts)
   */
  bulkImportCompanies(params: BulkImportCompaniesParams): Promise<BulkImportCompaniesResult>

  /**
   * Deactivate all active contacts belonging to a company.
   * Used by qualification workflow to cascade company disqualification to contacts.
   */
  deactivateContactsByCompany(params: DeactivateContactsByCompanyParams): Promise<DeactivateContactsByCompanyResult>

  /**
   * Get a contact by email address
   * Used for looking up existing leads when they reply to outreach
   * @see LeadService.getContactByEmail (apps/api/src/acquisition/lead-service.ts)
   */
  getContactByEmail(email: string, organizationId: string): Promise<AcqContact | null>

  // Deal operations (acq_deals table)
  /**
   * Upsert a deal by Attio Deal ID
   * Creates or updates acq_deals record linking Attio Deal to Supabase
   * @see LeadService.upsertDeal (apps/api/src/acquisition/lead-service.ts)
   */
  upsertDeal(params: UpsertDealParams): Promise<AcqDeal>

  /**
   * Get a deal by contact email
   * Used for looking up existing deals when leads book via email (fallback lookup)
   * @see LeadService.getDealByEmail (apps/api/src/acquisition/lead-service.ts)
   */
  getDealByEmail(email: string, organizationId: string): Promise<AcqDeal | null>

  /**
   * Get a deal by SignatureAPI envelope ID
   * Used by webhook handler to find deal when contract is signed
   * @see LeadService.getDealByEnvelopeId (apps/api/src/acquisition/lead-service.ts)
   */
  getDealByEnvelopeId(envelopeId: string, organizationId: string): Promise<AcqDeal | null>

  /**
   * Update deal with signature envelope ID
   * Called when proposal is sent via SignatureAPI
   * @see LeadService.updateDealEnvelopeId (apps/api/src/acquisition/lead-service.ts)
   */
  updateDealEnvelopeId(dealId: string, envelopeId: string, organizationId: string): Promise<AcqDeal | null>

  // Deal-sync operations (mirror deal-sync.ts utilities as server-side methods)

  getDealById(params: GetDealByIdParams): Promise<AcqDeal | null>

  getContactById(params: GetContactByIdParams): Promise<AcqContact | null>

  getCompanyById(params: GetCompanyByIdParams): Promise<AcqCompany | null>

  updateDiscoveryData(params: UpdateDiscoveryDataParams): Promise<void>

  updateProposalData(params: UpdateProposalDataParams): Promise<void>

  markProposalSent(params: MarkProposalSentParams): Promise<void>

  markProposalReviewed(params: MarkProposalReviewedParams): Promise<void>

  updateCloseLostReason(params: UpdateCloseLostReasonParams): Promise<void>

  updateFees(params: UpdateFeesParams): Promise<void>

  cacheInstantlyThreadIds(params: CacheInstantlyThreadIdsParams): Promise<void>

  transitionItem(params: TransitionItemParams): Promise<void>

  setContactNurture(params: SetContactNurtureParams): Promise<void>

  cancelSchedulesAndHitlByEmail(
    params: CancelSchedulesAndHitlByEmailParams
  ): Promise<{ schedulesCancelled: number; hitlDeleted: number }>

  cancelHitlByDealId(params: CancelHitlByDealIdParams): Promise<{ hitlDeleted: number }>

  clearDealFields(params: ClearDealFieldsParams): Promise<void>

  deleteDeal(params: DeleteDealParams): Promise<void>

  listDeals(organizationId: string, filters?: DealFilters): Promise<AcqDeal[]>

  getDealPipelineAnalytics(organizationId: string, recentLimit?: number): Promise<DealPipelineAnalytics>

  /**
   * Deep-merge enrichment data into a company or contact record.
   * Merges per source key rather than wholesale replacing the JSONB object.
   * @see LeadService.mergeEnrichmentData (apps/api/src/business/acquisition/lead-service.ts)
   */
  mergeEnrichmentData(
    id: string,
    orgId: string,
    table: 'acq_companies' | 'acq_contacts',
    data: Record<string, unknown>
  ): Promise<void>

  // Deal note operations (acq_deal_notes table)
  /**
   * Create a human-authored note on a deal
   * @see LeadService.createDealNote (apps/api/src/business/acquisition/lead-service.ts)
   */
  createDealNote(params: CreateDealNoteParams): Promise<AcqDealNote>

  /**
   * List notes for a deal, ordered by created_at DESC
   * @see LeadService.listDealNotes (apps/api/src/business/acquisition/lead-service.ts)
   */
  listDealNotes(params: ListDealNotesParams): Promise<AcqDealNote[]>

  // Deal task operations (acq_deal_tasks table)
  /**
   * Creates a new task attached to a deal.
   * @see LeadService.createDealTask (apps/api/src/business/acquisition/lead-service.ts)
   */
  createDealTask(params: CreateDealTaskParams): Promise<AcqDealTask>

  /**
   * Lists all tasks for a given deal, ordered by due date.
   * @see LeadService.listDealTasks (apps/api/src/business/acquisition/lead-service.ts)
   */
  listDealTasks(params: ListDealTasksParams): Promise<AcqDealTask[]>

  /**
   * Lists open (uncompleted) tasks within a date window across all deals.
   * @see LeadService.listDealTasksDue (apps/api/src/business/acquisition/lead-service.ts)
   */
  listDealTasksDue(params: ListDealTasksDueParams): Promise<AcqDealTask[]>

  /**
   * Marks a task as completed.
   * @see LeadService.completeDealTask (apps/api/src/business/acquisition/lead-service.ts)
   */
  completeDealTask(params: CompleteDealTaskParams): Promise<AcqDealTask>

  /**
   * Record a deal activity entry by deal ID.
   * Generic method for any activity type — used by SDK workflows.
   * @see LeadService.recordDealActivity (apps/api/src/business/acquisition/lead-service.ts)
   */
  recordDealActivity(params: RecordDealActivityParams): Promise<void>

  /**
   * Update the state_key on an acq_deals row.
   * @see LeadService.setDealStateKey (apps/api/src/business/acquisition/lead-service.ts)
   */
  setDealStateKey(params: SetDealStateKeyParams): Promise<{ ok: true }>

  /**
   * Transition a deal to a new stage, resolving pipeline_key automatically.
   * @see LeadService.transitionDeal (apps/api/src/business/acquisition/lead-service.ts)
   */
  transitionDeal(params: TransitionDealParams): Promise<{ deal: AcqDeal }>

  /**
   * Load a deal with its joined contact and company data.
   * @see LeadService.loadDeal (apps/api/src/business/acquisition/lead-service.ts)
   */
  loadDeal(params: LoadDealParams): Promise<DealDetail | null>

  // Social monitoring operations (acq_social_posts table)
  /**
   * Bulk upsert social posts (deduplicate by platform + platform_post_id)
   * @see LeadService.upsertSocialPosts (apps/api/src/business/acquisition/lead-service.ts)
   */
  upsertSocialPosts(params: UpsertSocialPostsParams): Promise<UpsertSocialPostsResult>
}
