import { z } from 'zod';

export const EcosystemArtifactTypeSchema = z.enum([
  'transcript',
  'note',
  'memory',
  'plan',
  'routine',
  'habit',
  'habit-checkin',
  'trail-report',
  'route-session',
  'agent-output',
  'document',
  'digest',
]);

export const ArtifactLinkRelationSchema = z.enum([
  'derived-from',
  'summarizes',
  'generated-task',
  'generated-routine',
  'generated-habit',
  'generated-memory',
  'evidence-for',
  'review-of',
  'attached-to',
]);

export const ArtifactLinkSchema = z.object({
  relation: ArtifactLinkRelationSchema,
  targetArtifactId: z.string().min(1),
});

export const ArtifactCreatedBySchema = z.object({
  actorType: z.enum(['user', 'agent', 'system', 'mixed']),
  actorId: z.string().min(1).nullable(),
});

export const ArtifactOwnershipSchema = z.object({
  userId: z.string().min(1),
  orgId: z.string().min(1).nullable().optional(),
});

export const ArtifactVisibilitySchema = z.object({
  scope: z.enum(['private', 'org', 'shared', 'local-only']),
  allowedProducts: z.array(z.string().min(1)).optional(),
});

export const ArtifactLineageStepSchema = z.object({
  stepType: z.string().min(1),
  productId: z.string().min(1),
  actorType: z.enum(['user', 'agent', 'system']),
  timestamp: z.string().datetime(),
});

export const ArtifactProvenanceSchema = z.object({
  originProductId: z.string().min(1),
  originActionId: z.string().min(1).nullable().optional(),
  sessionId: z.string().min(1).nullable().optional(),
  runId: z.string().min(1).nullable().optional(),
  approvalId: z.string().min(1).nullable().optional(),
  correlationId: z.string().min(1).nullable().optional(),
  lineage: z.array(ArtifactLineageStepSchema).min(1),
});

export const BaseArtifactEnvelopeSchema = z.object({
  id: z.string().min(1),
  artifactType: EcosystemArtifactTypeSchema,
  schemaVersion: z.literal(1),
  productId: z.string().min(1),
  sourceSurface: z.string().min(1),
  title: z.string().min(1).nullable(),
  summary: z.string().min(1).nullable(),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
  createdBy: ArtifactCreatedBySchema,
  ownership: ArtifactOwnershipSchema,
  visibility: ArtifactVisibilitySchema,
  status: z.string().min(1),
  tags: z.array(z.string().min(1)),
  links: z.array(ArtifactLinkSchema),
  provenance: ArtifactProvenanceSchema,
  payload: z.record(z.unknown()),
});

export const TranscriptPayloadSchema = z.object({
  transcriptText: z.string().min(1),
  transcriptSource: z.enum(['microphone', 'upload', 'call', 'browser', 'other']),
  language: z.string().min(1),
  durationMs: z.number().int().nonnegative(),
  segments: z
    .array(
      z.object({
        speaker: z.string().min(1).nullable().optional(),
        startedAtMs: z.number().int().nonnegative(),
        endedAtMs: z.number().int().nonnegative(),
        text: z.string().min(1),
      })
    )
    .default([]),
});

export const NotePayloadSchema = z.object({
  noteFormat: z.enum(['markdown', 'plain-text', 'rich-text']),
  body: z.string().min(1),
  excerpt: z.string().min(1).nullable().optional(),
});

export const MemoryPayloadSchema = z.object({
  memoryKind: z.enum(['fact', 'preference', 'person', 'project', 'insight', 'todo']),
  text: z.string().min(1),
  confidence: z.number().min(0).max(1),
  sourceArtifactIds: z.array(z.string().min(1)).min(1),
  reviewState: z.enum(['proposed', 'accepted', 'rejected']),
});

export const PlanPayloadSchema = z.object({
  weekOf: z.string().min(1),
  taskCount: z.number().int().nonnegative(),
  scheduledEntryCount: z.number().int().nonnegative(),
  totalScheduledMinutes: z.number().int().nonnegative(),
  entries: z.array(
    z.object({
      taskTitle: z.string().min(1),
      scheduledDate: z.string().min(1),
      startTime: z.string().min(1),
      endTime: z.string().min(1),
      durationMinutes: z.number().int().nonnegative(),
      flowName: z.string().min(1).nullable(),
      zoneName: z.string().min(1).nullable(),
      priority: z.string().min(1),
    })
  ),
});

export const RoutinePayloadSchema = z.object({
  routineId: z.string().min(1),
  stepCount: z.number().int().nonnegative(),
  totalDurationMinutes: z.number().nonnegative(),
  status: z.string().min(1),
  isTemplate: z.boolean(),
  category: z.string().min(1).nullable().optional(),
  steps: z.array(
    z.object({
      label: z.string().min(1),
      durationMinutes: z.number().nonnegative(),
      transition: z.string().min(1),
      status: z.string().min(1),
    })
  ),
});

export const HabitPayloadSchema = z.object({
  habitId: z.string().min(1),
  identityId: z.string().min(1),
  frequency: z.enum(['daily', 'weekly', 'custom']),
  customDays: z.array(z.number().int().min(0).max(6)).optional(),
  targetCount: z.number().int().positive(),
  reminderTime: z.string().min(1).nullable().optional(),
  isActive: z.boolean(),
  sourceRoutineId: z.string().min(1),
});

export const TrailReportPayloadSchema = z.object({
  sourceProduct: z.literal('claw-cowork'),
  sourceTaskId: z.string().min(1).nullable().optional(),
  generatedFrom: z.enum(['audit-export-json', 'audit-query-json']),
  reportGeneratedAt: z.string().datetime(),
  actionCount: z.number().int().nonnegative(),
  toolCallCount: z.number().int().nonnegative(),
  approvalCount: z.number().int().nonnegative(),
  failureCount: z.number().int().nonnegative(),
  safetySignalCount: z.number().int().nonnegative(),
  tasks: z.array(z.string().min(1)),
  actionBreakdown: z.array(
    z.object({
      action: z.string().min(1),
      count: z.number().int().positive(),
    })
  ),
  entries: z.array(
    z.object({
      timestamp: z.string().datetime(),
      taskId: z.string().min(1).nullable(),
      action: z.string().min(1),
      tool: z.string().min(1).nullable().optional(),
      result: z.string().min(1).nullable().optional(),
      approval: z.string().min(1).nullable().optional(),
      inputSummary: z.string().min(1).nullable().optional(),
      metadata: z.record(z.unknown()).nullable().optional(),
    })
  ),
});

export const TranscriptArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('transcript'),
  payload: TranscriptPayloadSchema,
});

export const NoteArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('note'),
  payload: NotePayloadSchema,
});

export const MemoryArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('memory'),
  payload: MemoryPayloadSchema,
});

export const PlanArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('plan'),
  payload: PlanPayloadSchema,
});

export const RoutineArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('routine'),
  payload: RoutinePayloadSchema,
});

export const HabitArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('habit'),
  payload: HabitPayloadSchema,
});

export const TrailReportArtifactEnvelopeSchema = BaseArtifactEnvelopeSchema.extend({
  artifactType: z.literal('trail-report'),
  payload: TrailReportPayloadSchema,
});

export const Phase1ArtifactEnvelopeSchema = z.discriminatedUnion('artifactType', [
  TranscriptArtifactEnvelopeSchema,
  NoteArtifactEnvelopeSchema,
  MemoryArtifactEnvelopeSchema,
]);

export const EcosystemEventActorSchema = z.object({
  actorType: z.enum(['user', 'agent', 'system', 'device']),
  actorId: z.string().min(1).nullable().optional(),
});

export const EcosystemEventTraceSchema = z.object({
  correlationId: z.string().min(1).nullable(),
  causationId: z.string().min(1).nullable(),
  parentEventId: z.string().min(1).nullable(),
});

export const BaseEcosystemEventSchema = z.object({
  eventId: z.string().min(1),
  eventName: z.string().min(1),
  eventVersion: z.literal(1),
  occurredAt: z.string().datetime(),
  productId: z.string().min(1),
  sourceSurface: z.string().min(1),
  userId: z.string().min(1).nullable().optional(),
  orgId: z.string().min(1).nullable().optional(),
  sessionId: z.string().min(1).nullable().optional(),
  runId: z.string().min(1).nullable().optional(),
  artifactId: z.string().min(1).nullable().optional(),
  actor: EcosystemEventActorSchema,
  trace: EcosystemEventTraceSchema,
  payload: z.record(z.unknown()),
});

export const CaptureTranscriptCreatedPayloadSchema = z.object({
  artifactId: z.string().min(1),
  durationMs: z.number().int().nonnegative(),
  language: z.string().min(1),
  transcriptSource: z.enum(['microphone', 'upload', 'call', 'browser', 'other']),
});

export const ArtifactCreatedPayloadSchema = z.object({
  artifactType: z.enum([
    'transcript',
    'note',
    'memory',
    'plan',
    'routine',
    'habit',
    'trail-report',
  ]),
  title: z.string().min(1).nullable(),
  status: z.string().min(1),
});

export const ArtifactLinkedPayloadSchema = z.object({
  sourceArtifactId: z.string().min(1),
  targetArtifactId: z.string().min(1),
  relation: z.enum([
    'summarizes',
    'generated-memory',
    'generated-routine',
    'generated-habit',
    'derived-from',
  ]),
});

export const MemoryEntryCreatedPayloadSchema = z.object({
  artifactId: z.string().min(1),
  memoryKind: MemoryPayloadSchema.shape.memoryKind,
  reviewState: MemoryPayloadSchema.shape.reviewState,
  confidence: MemoryPayloadSchema.shape.confidence,
  sourceArtifactIds: z.array(z.string().min(1)).min(1),
});

export const CaptureTranscriptCreatedEventSchema = BaseEcosystemEventSchema.extend({
  eventName: z.literal('capture.transcript.created'),
  payload: CaptureTranscriptCreatedPayloadSchema,
});

export const ArtifactCreatedEventSchema = BaseEcosystemEventSchema.extend({
  eventName: z.literal('artifact.created'),
  payload: ArtifactCreatedPayloadSchema,
});

export const ArtifactLinkedEventSchema = BaseEcosystemEventSchema.extend({
  eventName: z.literal('artifact.linked'),
  payload: ArtifactLinkedPayloadSchema,
});

export const MemoryEntryCreatedEventSchema = BaseEcosystemEventSchema.extend({
  eventName: z.literal('memory.entry.created'),
  payload: MemoryEntryCreatedPayloadSchema,
});

export const Phase1EcosystemEventSchema = z.discriminatedUnion('eventName', [
  CaptureTranscriptCreatedEventSchema,
  ArtifactCreatedEventSchema,
  ArtifactLinkedEventSchema,
  MemoryEntryCreatedEventSchema,
]);

export const Phase1EcosystemEventSchemas = {
  'capture.transcript.created': CaptureTranscriptCreatedEventSchema,
  'artifact.created': ArtifactCreatedEventSchema,
  'artifact.linked': ArtifactLinkedEventSchema,
  'memory.entry.created': MemoryEntryCreatedEventSchema,
} as const;

export type ArtifactEnvelope = z.infer<typeof BaseArtifactEnvelopeSchema>;
export type TranscriptArtifactEnvelope = z.infer<typeof TranscriptArtifactEnvelopeSchema>;
export type NoteArtifactEnvelope = z.infer<typeof NoteArtifactEnvelopeSchema>;
export type MemoryArtifactEnvelope = z.infer<typeof MemoryArtifactEnvelopeSchema>;
export type PlanArtifactEnvelope = z.infer<typeof PlanArtifactEnvelopeSchema>;
export type RoutineArtifactEnvelope = z.infer<typeof RoutineArtifactEnvelopeSchema>;
export type HabitArtifactEnvelope = z.infer<typeof HabitArtifactEnvelopeSchema>;
export type Phase1ArtifactEnvelope = z.infer<typeof Phase1ArtifactEnvelopeSchema>;
export type EcosystemEvent = z.infer<typeof BaseEcosystemEventSchema>;
export type Phase1EcosystemEvent = z.infer<typeof Phase1EcosystemEventSchema>;
