import { z } from 'zod';

// ---------------------------------------------------------------------------
// Shared primitives
// ---------------------------------------------------------------------------

export type DocumentFormat = 'pdf' | 'md' | 'txt';

// ---------------------------------------------------------------------------
// Pipeline: Chunk
// ---------------------------------------------------------------------------

export interface ChunkMetadata {
  // MD-specific
  headingLevel?: number;
  headingText?: string;
  parentHeading?: string;
  // TXT-specific
  approximatePosition?: 'start' | 'middle' | 'end';
  // PDF-specific
  pageNumber?: number;
  chunkIndexOnPage?: number;
}

export interface Chunk {
  id: string;
  documentId: string;
  text: string;
  format: DocumentFormat;
  index: number;
  metadata: ChunkMetadata;
}

// ---------------------------------------------------------------------------
// Pipeline: DraftKB (AI output — validated with Zod before use)
// ---------------------------------------------------------------------------

const DraftTopicRelationshipsSchema = z.object({
  related: z.array(z.string()),
  prerequisites: z.array(z.string()),
  contrasts: z.array(z.string()),
});

export const DraftTopicSchema = z.object({
  title: z.string().min(1),
  body: z.string().min(1),
  difficulty: z.enum(['introductory', 'intermediate', 'advanced']),
  complexityWeight: z.number().int().min(1).max(5),
  keyTerms: z.array(z.string()),
  sourceChunkIds: z.array(z.string()),
  relationships: DraftTopicRelationshipsSchema,
});

export const DraftThemeSchema = z.object({
  title: z.string().min(1),
  description: z.string().min(1),
  topics: z.array(DraftTopicSchema).min(1),
});

export const DraftKBSchema = z.object({
  themes: z.array(DraftThemeSchema).min(1),
});

export type DraftTopic = z.infer<typeof DraftTopicSchema>;
export type DraftTheme = z.infer<typeof DraftThemeSchema>;
export type DraftKB = z.infer<typeof DraftKBSchema>;

// ---------------------------------------------------------------------------
// Pipeline: PocketBase write result
// ---------------------------------------------------------------------------

export interface WrittenTopic {
  id: string;
  title: string;
  themeId: string;
  body: string;
  sourceChunkIds: string[];
}

// ---------------------------------------------------------------------------
// Qdrant payload types
// ---------------------------------------------------------------------------

export interface SourceChunkPayload {
  [key: string]: unknown;
  source_document_id: string;
  chunk_index: number;
  text: string;
  theme_id: string | null;
  topic_id: string | null;
  format: DocumentFormat;
}

export interface TopicSummaryPayload {
  [key: string]: unknown;
  topic_id: string;
  theme_id: string;
  title: string;
  text: string;
}

// ---------------------------------------------------------------------------
// Job system
// ---------------------------------------------------------------------------

export type JobStatus =
  | 'queued'
  | 'extracting'
  | 'chunking'
  | 'structuring'
  | 'writing'
  | 'embedding'
  | 'done'
  | 'failed';

export interface JobProgress {
  chunksTotal: number;
  chunksEmbedded: number;
  themesFound: number;
  topicsFound: number;
}

export interface Job {
  id: string;
  documentId: string;
  filename: string;
  format: DocumentFormat;
  fileUrl: string;
  filePath: string;
  status: JobStatus;
  progress: JobProgress;
  error: string | null;
  createdAt: Date;
  updatedAt: Date;
}

// ---------------------------------------------------------------------------
// API schemas (Zod — validates external input)
// ---------------------------------------------------------------------------

export const IngestBodySchema = z.object({
  documentId: z.string().min(1),
  filename: z.string().min(1),
  format: z.enum(['pdf', 'md', 'txt']),
  fileUrl: z.string().url(),
});

export type IngestBody = z.infer<typeof IngestBodySchema>;
