/**
 * Phase Repository Port Interface
 *
 * Port for Phase aggregate operations.
 * Implementations (Drizzle, etc.) are adapters.
 */

import type { Phase, NewPhase } from '../schema.js';

/**
 * Data for creating a new phase.
 * Omits system-managed fields (id, createdAt, updatedAt).
 */
export type CreatePhaseData = Omit<NewPhase, 'id' | 'createdAt' | 'updatedAt'> & { id?: string };

/**
 * Data for updating a phase.
 * Partial of creation data - all fields optional.
 */
export type UpdatePhaseData = Partial<CreatePhaseData>;

/**
 * Phase Repository Port
 *
 * Defines operations for the Phase aggregate.
 * Only knows about phases - no knowledge of parent or child entities.
 */
export interface PhaseRepository {
  /**
   * Create a new phase.
   * Generates id and sets timestamps automatically.
   * Foreign key to initiative enforced by database.
   */
  create(data: CreatePhaseData): Promise<Phase>;

  /**
   * Find a phase by its ID.
   * Returns null if not found.
   */
  findById(id: string): Promise<Phase | null>;

  /**
   * Find all phases for an initiative.
   * Returns phases ordered by createdAt.
   * Returns empty array if none exist.
   */
  findByInitiativeId(initiativeId: string): Promise<Phase[]>;

  /**
   * Find all dependency edges for phases in an initiative.
   * Returns array of { phaseId, dependsOnPhaseId } pairs.
   */
  findDependenciesByInitiativeId(initiativeId: string): Promise<Array<{ phaseId: string; dependsOnPhaseId: string }>>;

  /**
   * Update a phase.
   * Throws if phase not found.
   * Updates updatedAt timestamp automatically.
   */
  update(id: string, data: UpdatePhaseData): Promise<Phase>;

  /**
   * Delete a phase.
   * Throws if phase not found.
   * Cascades to child plans and tasks via FK constraints.
   */
  delete(id: string): Promise<void>;

  /**
   * Create a dependency between two phases.
   * The phase identified by phaseId will depend on dependsOnPhaseId.
   * Both phases must exist.
   */
  createDependency(phaseId: string, dependsOnPhaseId: string): Promise<void>;

  /**
   * Get IDs of phases that this phase depends on.
   * Returns empty array if no dependencies.
   */
  getDependencies(phaseId: string): Promise<string[]>;

  /**
   * Get IDs of phases that depend on this phase.
   * Returns empty array if no dependents.
   */
  getDependents(phaseId: string): Promise<string[]>;

  /**
   * Remove a dependency between two phases.
   */
  removeDependency(phaseId: string, dependsOnPhaseId: string): Promise<void>;
}
