<?php

declare(strict_types=1);

namespace Drupal\flowdrop_workflow\Service;

use Drupal\flowdrop_workflow\Diagnostic\DoctorReport;
use Drupal\flowdrop_workflow\Diagnostic\RemedyPlan;
use Drupal\flowdrop_workflow\WorkflowDefinitionInterface;

/**
 * Headless, UI-agnostic entry point for diagnosing and repairing a workflow.
 *
 * Where {@see WorkflowValidatorInterface} is a pre-save gate (may this
 * prospective state be written?), the doctor is a post-hoc clinic for state
 * already at rest: it runs every tagged diagnostic, offers remedies, and — on
 * confirmation — rebuilds the chosen mutations server-side, applies them, and
 * saves. The admin screen, the drush command, and (later) import-preflight all
 * call this one service.
 *
 * The apply path never trusts a client-supplied mutation payload: the client
 * sends only {@see \Drupal\flowdrop_workflow\Diagnostic\RemedySelection}s, and
 * both preview and apply re-diagnose from scratch and rebuild mutations,
 * closing the time-of-check/time-of-use gap between render and submit.
 *
 * @api
 */
interface WorkflowDoctorInterface {

  /**
   * Diagnoses the workflow across every registered diagnostic.
   *
   * @param \Drupal\flowdrop_workflow\WorkflowDefinitionInterface $workflow
   *   The stored workflow to diagnose.
   *
   * @return \Drupal\flowdrop_workflow\Diagnostic\DoctorReport
   *   The aggregated findings.
   */
  public function diagnose(WorkflowDefinitionInterface $workflow): DoctorReport;

  /**
   * Dry-run: rebuilds the mutations for the selections and summarises them.
   *
   * Re-diagnoses, matches each selection to a still-present finding by stable
   * id, rebuilds its mutations, and returns a human-readable summary of what
   * *would* change — plus any selections skipped because their finding
   * vanished. Applies nothing and saves nothing.
   *
   * @param \Drupal\flowdrop_workflow\WorkflowDefinitionInterface $workflow
   *   The stored workflow.
   * @param list<\Drupal\flowdrop_workflow\Diagnostic\RemedySelection> $selections
   *   The user's remedy choices.
   *
   * @return \Drupal\flowdrop_workflow\Diagnostic\RemedyPlan
   *   The preview of pending changes.
   */
  public function previewRemedies(WorkflowDefinitionInterface $workflow, array $selections): RemedyPlan;

  /**
   * Applies the selected remedies and saves the workflow.
   *
   * Re-derives the whole change set from scratch (re-diagnose → match by stable
   * id → rebuild mutations) rather than trusting the previewed plan, applies
   * the union via the mutator, then saves. Selections whose findings vanished
   * are skipped. Remaining (unremedied) findings do NOT block the save — a
   * partial repair of an already-stored workflow is still an improvement.
   *
   * @param \Drupal\flowdrop_workflow\WorkflowDefinitionInterface $workflow
   *   The stored workflow to repair and save.
   * @param list<\Drupal\flowdrop_workflow\Diagnostic\RemedySelection> $selections
   *   The user's remedy choices.
   *
   * @return \Drupal\flowdrop_workflow\Diagnostic\DoctorReport
   *   A fresh diagnosis of the workflow after the repair.
   */
  public function applyRemedies(WorkflowDefinitionInterface $workflow, array $selections): DoctorReport;

}
