module Adr
  # Generates docs/adr/migration-report.md — the single aggregate surface for
  # migration uncertainty (alongside per-file migration_confidence frontmatter).
  class MigrationReport
    FILENAME = "migration-report.md"

    # Pilot-gate threshold (task 5.5): a run whose low-confidence flag rate
    # exceeds this is not good enough for wider rollout — tighten heuristics
    # and re-run. Set empirically during the 2026-07-03 pilot.
    FLAG_RATE_THRESHOLD = 0.25

    def initialize(repository:, detector:)
      @repository = repository
      @detector = detector
    end

    def path = File.join(@repository.dir, FILENAME)

    def write!
      File.write(path, content)
    end

    def migrated_entries
      @repository.entries.select { |e| e.record.frontmatter["migration_source"] }
    end

    def flag_rate
      entries = migrated_entries
      return 0.0 if entries.empty?

      low = entries.count { |e| e.record.frontmatter["migration_confidence"] == "low" }
      (low.to_f / entries.size).round(3)
    end

    def content
      entries = migrated_entries
      unrecognized = @detector.units.select { |u| u.shape == :unrecognized }
      rows = entries.map do |entry|
        record = entry.record
        pending = record.sections.select { |_, v| v == Migrator::PENDING_MARKER }.keys
        not_stated = record.sections.select { |_, v| v == Migrator::NOT_STATED_MARKER }.keys
        "| #{record.id} | [#{record.title}](#{File.basename(entry.path)}) " \
          "| #{record.frontmatter['migration_source']} " \
          "| #{record.frontmatter['migration_confidence']} " \
          "| #{(pending.map { |s| "#{s} (pending)" } + not_stated.map { |s| "#{s} (not stated)" }).join(', ')} |"
      end

      <<~MD
        <!-- Generated by os-adr migration. Regenerated on every migration pass. -->

        # ADR Migration Report

        Converted: #{entries.size} · Low-confidence flag rate: #{(flag_rate * 100).round(1)}% (gate threshold: #{(FLAG_RATE_THRESHOLD * 100).round}% — #{flag_rate > FLAG_RATE_THRESHOLD ? 'EXCEEDED, tighten heuristics before wider rollout' : 'within gate'})

        | ID | Title | Source | Confidence | Open items |
        | --- | --- | --- | --- | --- |
        #{rows.join("\n")}

        ## Unrecognized content (manual handling required)

        #{unrecognized.empty? ? '_none_' : unrecognized.map { |u| "- #{u.source_ref}" }.join("\n")}

        _Sources are untouched. Old-system removal is a separate, explicitly user-approved step._
      MD
    end
  end
end
