/**
 * Planning Types
 *
 * Type definitions for the planning system.
 */

import { z } from 'zod';

/**
 * Priority levels for research questions
 */
export type QuestionPriority = 'P0' | 'P1' | 'P2';

/**
 * Agent mode
 */
export enum AgentMode {
  CODE = 'code',
  PLAN = 'plan',
}

/**
 * Similar entity result
 */
export interface SimilarEntity {
  /** Qualified name of the entity */
  qualifiedName: string;
  /** Entity type (Function, Class, File) */
  entityType: 'Function' | 'Class' | 'File';
  /** File path */
  filePath: string;
  /** Line start */
  lineStart?: number;
  /** Line end */
  lineEnd?: number;
  /** Description/docstring */
  description?: string;
  /** Similarity score (0-1) */
  similarityScore: number;
  /** Importance score (activity, PageRank) */
  importanceScore: number;
  /** Combined score */
  combinedScore: number;
}

/**
 * Similar PR result
 */
export interface SimilarPR {
  /** PR number */
  number: number;
  /** PR title */
  title: string;
  /** PR description */
  description?: string;
  /** Author */
  author: string;
  /** Files changed */
  filesChanged: string[];
  /** Similarity score */
  similarityScore: number;
  /** Merged date */
  mergedAt?: Date;
}

/**
 * Domain expert (contributor with relevant experience)
 */
export interface DomainExpert {
  /** Username */
  username: string;
  /** Number of relevant commits */
  relevantCommits: number;
  /** Files they've touched */
  relevantFiles: string[];
  /** Expertise score */
  expertiseScore: number;
}

/**
 * Planning context for feature implementation
 */
export interface PlanningContext {
  /** Original query/goal */
  query: string;
  /** Similar code entities */
  similarCode: SimilarEntity[];
  /** Similar PRs */
  similarPRs: SimilarPR[];
  /** Related files */
  relatedFiles: string[];
  /** Domain experts */
  experts: DomainExpert[];
  /** Entry points (main files to start from) */
  entryPoints: string[];
  /** Suggested tasks */
  suggestedTasks: string[];
}

/**
 * Feature context with expanded graphs
 */
export interface FeatureContext {
  /** Original query */
  query: string;
  /** Root entities found */
  rootEntities: SimilarEntity[];
  /** Expanded call graph (qualified names) */
  callGraph: Map<string, string[]>;
  /** Expanded dependency graph */
  dependencyGraph: Map<string, string[]>;
  /** All affected files */
  affectedFiles: string[];
  /** Related PRs */
  relatedPRs: SimilarPR[];
  /** Contributing authors */
  contributors: DomainExpert[];
}

/**
 * Research question in a plan
 */
export interface ResearchQuestion {
  /** Question ID */
  id: string;
  /** The question text */
  question: string;
  /** Priority level */
  priority: QuestionPriority;
  /** Why this question matters */
  rationale: string;
  /** What constitutes a good answer */
  successCriteria: string[];
  /** Suggested tools/macros to use */
  suggestedTools: string[];
  /** Dependencies on other questions */
  dependsOn: string[];
}

/**
 * Research plan
 */
export interface ResearchPlan {
  /** Plan ID */
  id: string;
  /** Goal/objective */
  goal: string;
  /** Questions to answer */
  questions: ResearchQuestion[];
  /** Expected deliverables */
  deliverables: string[];
  /** Budget constraints */
  budget: {
    maxToolCalls?: number;
    maxTokens?: number;
    maxTimeMinutes?: number;
  };
  /** Created timestamp */
  createdAt: Date;
}

/**
 * Exploration strategy
 */
export type ExplorationStrategy =
  | 'understand_feature'
  | 'debug_issue'
  | 'assess_change_impact'
  | 'onboard_codebase'
  | 'find_similar_code';

/**
 * Exploration plan
 */
export interface ExplorationPlan {
  /** Strategy being used */
  strategy: ExplorationStrategy;
  /** Goal description */
  goal: string;
  /** Steps to execute */
  steps: ExplorationStep[];
  /** Files to examine */
  filesToExamine: string[];
  /** Queries to run */
  queriesToRun: string[];
}

/**
 * Exploration step
 */
export interface ExplorationStep {
  /** Step number */
  step: number;
  /** Action to take */
  action: string;
  /** Tool to use */
  tool: string;
  /** Expected outcome */
  expectedOutcome: string;
}

/**
 * Plan mode state
 */
export interface PlanModeState {
  /** Current mode */
  mode: AgentMode;
  /** Current plan content (if in plan mode) */
  planContent?: string;
  /** Plan file path */
  planPath?: string;
  /** Whether plan is submitted for approval */
  planSubmitted: boolean;
  /** Feedback from rejection */
  rejectionFeedback?: string;
}

/**
 * Team focus data
 */
export interface TeamFocusData {
  /** Hot files (recently changed) */
  hotFiles: Array<{
    path: string;
    changeCount: number;
    lastModified: Date;
    contributors: string[];
  }>;
  /** Hot areas (directories) */
  hotAreas: Array<{
    path: string;
    fileCount: number;
    changeCount: number;
  }>;
  /** Recent PRs */
  recentPRs: SimilarPR[];
  /** Active contributors */
  activeContributors: DomainExpert[];
}

/**
 * Team focus summary
 */
export interface TeamFocusSummary {
  /** Raw data */
  data: TeamFocusData;
  /** LLM-generated summary */
  summary: string;
  /** Time window analyzed */
  timeWindowDays: number;
}

/**
 * Similarity search options
 */
export interface SimilaritySearchOptions {
  /** Maximum results */
  limit?: number;
  /** Minimum similarity score */
  minScore?: number;
  /** Entity types to search */
  entityTypes?: Array<'Function' | 'Class' | 'File'>;
  /** Weight for semantic similarity (0-1) */
  semanticWeight?: number;
  /** Weight for importance (0-1) */
  importanceWeight?: number;
  /** Weight for PageRank (0-1) */
  pageRankWeight?: number;
}

/**
 * Context builder options
 */
export interface ContextBuilderOptions {
  /** Max similar code results */
  maxSimilarCode?: number;
  /** Max similar PRs */
  maxSimilarPRs?: number;
  /** Max experts to find */
  maxExperts?: number;
  /** Include call graph expansion */
  expandCallGraph?: boolean;
  /** Max hops for graph expansion */
  maxHops?: number;
}

/**
 * Planning API request
 */
export const PlanContextRequestSchema = z.object({
  query: z.string().min(1),
  options: z.object({
    maxSimilarCode: z.number().positive().optional(),
    maxSimilarPRs: z.number().positive().optional(),
    maxExperts: z.number().positive().optional(),
    expandCallGraph: z.boolean().optional(),
    maxHops: z.number().positive().optional(),
  }).optional(),
});

export type PlanContextRequest = z.infer<typeof PlanContextRequestSchema>;

/**
 * Similar search request
 */
export const SimilarSearchRequestSchema = z.object({
  query: z.string().min(1),
  type: z.enum(['code', 'prs']).default('code'),
  limit: z.number().positive().default(10),
  minScore: z.number().min(0).max(1).optional(),
});

export type SimilarSearchRequest = z.infer<typeof SimilarSearchRequestSchema>;
