import { z } from 'zod'

/**
 * Base Entity Contracts
 *
 * Typed base interfaces for CRM, Lead-Gen (Acquisition), and Projects domains.
 * Each uses a `<TMeta>` generic parameter so client projects can narrow the
 * metadata type in their own `foundations/types/` directory.
 *
 * These are PARALLEL abstractions — they do NOT replace or modify the existing
 * row types (ProjectRow, AcqDealRow, etc.). Use these as the SDK-facing contract
 * layer; use the row types internally for direct Supabase access.
 *
 * Usage in a client project:
 *   import { BaseProject } from '@elevasis/core'
 *   type Project = BaseProject<{ budget: number; riskScore: 'low' | 'medium' | 'high' }>
 *
 * Extending a Zod schema in a client project:
 *   import { BaseProjectSchema } from '@elevasis/core'
 *   const ProjectMetaSchema = z.object({ budget: z.number(), riskScore: z.enum(['low','medium','high']) })
 *   const ProjectSchema = BaseProjectSchema.extend({ metadata: ProjectMetaSchema })
 */

// =============================================================================
// Projects / Delivery
// =============================================================================

/**
 * Common fields shared across all project implementations.
 * `TMeta` narrows the `metadata` JSONB column (prj_projects.metadata).
 */
export interface BaseProject<TMeta = Record<string, unknown>> {
  id: string
  organizationId: string
  name: string
  kind: string
  status: string
  description: string | null
  metadata: TMeta
  createdAt: string
  updatedAt: string
}

/**
 * Common fields shared across all milestone implementations.
 * `TMeta` narrows the `metadata` JSONB column (prj_milestones.metadata).
 */
export interface BaseMilestone<TMeta = Record<string, unknown>> {
  id: string
  organizationId: string
  projectId: string
  name: string
  status: string
  description: string | null
  metadata: TMeta
  createdAt: string
  updatedAt: string
}

/**
 * Common fields shared across all task implementations.
 * `TMeta` narrows the `metadata` JSONB column (prj_tasks.metadata).
 */
export interface BaseTask<TMeta = Record<string, unknown>> {
  id: string
  organizationId: string
  projectId: string
  name: string
  status: string
  type: string
  description: string | null
  metadata: TMeta
  createdAt: string
  updatedAt: string
}

// =============================================================================
// CRM / Acquisition
// =============================================================================

/**
 * Common fields shared across all deal implementations.
 * `TMeta` is an extension point for client-specific deal metadata.
 * Note: The underlying acq_deals table does not have a `metadata` column;
 * this field serves as a typed extension slot for SDK consumers.
 */
export interface BaseDeal<TMeta = Record<string, unknown>> {
  id: string
  organizationId: string
  contactEmail: string
  stage: string | null
  metadata: TMeta
  createdAt: string
  updatedAt: string
}

/**
 * Common fields shared across all company implementations.
 * `TMeta` is an extension point for client-specific company metadata.
 */
export interface BaseCompany<TMeta = Record<string, unknown>> {
  id: string
  organizationId: string
  name: string
  domain: string | null
  status: string
  metadata: TMeta
  createdAt: string
  updatedAt: string
}

/**
 * Common fields shared across all contact implementations.
 * `TMeta` is an extension point for client-specific contact metadata.
 */
export interface BaseContact<TMeta = Record<string, unknown>> {
  id: string
  organizationId: string
  email: string
  firstName: string | null
  lastName: string | null
  status: string
  metadata: TMeta
  createdAt: string
  updatedAt: string
}

// =============================================================================
// Base Zod Schemas
// =============================================================================

/**
 * Base Zod schema for a project record.
 * Extend with `BaseProjectSchema.extend({ metadata: ProjectMetaSchema })`.
 */
export const BaseProjectSchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  name: z.string(),
  kind: z.string(),
  status: z.string(),
  description: z.string().nullable(),
  metadata: z.record(z.string(), z.unknown()).default({}),
  createdAt: z.string(),
  updatedAt: z.string()
})

/**
 * Base Zod schema for a milestone record.
 * Extend with `BaseMilestoneSchema.extend({ metadata: MilestoneMetaSchema })`.
 */
export const BaseMilestoneSchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  projectId: z.string(),
  name: z.string(),
  status: z.string(),
  description: z.string().nullable(),
  metadata: z.record(z.string(), z.unknown()).default({}),
  createdAt: z.string(),
  updatedAt: z.string()
})

/**
 * Base Zod schema for a task record.
 * Extend with `BaseTaskSchema.extend({ metadata: TaskMetaSchema })`.
 */
export const BaseTaskSchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  projectId: z.string(),
  name: z.string(),
  status: z.string(),
  type: z.string(),
  description: z.string().nullable(),
  metadata: z.record(z.string(), z.unknown()).default({}),
  createdAt: z.string(),
  updatedAt: z.string()
})

/**
 * Base Zod schema for a deal record.
 * Extend with `BaseDealSchema.extend({ metadata: DealMetaSchema })`.
 */
export const BaseDealSchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  contactEmail: z.string(),
  stage: z.string().nullable(),
  metadata: z.record(z.string(), z.unknown()).default({}),
  createdAt: z.string(),
  updatedAt: z.string()
})

/**
 * Base Zod schema for a company record.
 * Extend with `BaseCompanySchema.extend({ metadata: CompanyMetaSchema })`.
 */
export const BaseCompanySchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  name: z.string(),
  domain: z.string().nullable(),
  status: z.string(),
  metadata: z.record(z.string(), z.unknown()).default({}),
  createdAt: z.string(),
  updatedAt: z.string()
})

/**
 * Base Zod schema for a contact record.
 * Extend with `BaseContactSchema.extend({ metadata: ContactMetaSchema })`.
 */
export const BaseContactSchema = z.object({
  id: z.string(),
  organizationId: z.string(),
  email: z.string(),
  firstName: z.string().nullable(),
  lastName: z.string().nullable(),
  status: z.string(),
  metadata: z.record(z.string(), z.unknown()).default({}),
  createdAt: z.string(),
  updatedAt: z.string()
})

// =============================================================================
// Inferred types (convenience — matches the interface shapes above)
// =============================================================================

/** Default (unnarrowed) inferred type from BaseProjectSchema */
export type BaseProjectInput = z.infer<typeof BaseProjectSchema>
/** Default (unnarrowed) inferred type from BaseMilestoneSchema */
export type BaseMilestoneInput = z.infer<typeof BaseMilestoneSchema>
/** Default (unnarrowed) inferred type from BaseTaskSchema */
export type BaseTaskInput = z.infer<typeof BaseTaskSchema>
/** Default (unnarrowed) inferred type from BaseDealSchema */
export type BaseDealInput = z.infer<typeof BaseDealSchema>
/** Default (unnarrowed) inferred type from BaseCompanySchema */
export type BaseCompanyInput = z.infer<typeof BaseCompanySchema>
/** Default (unnarrowed) inferred type from BaseContactSchema */
export type BaseContactInput = z.infer<typeof BaseContactSchema>
