#!/usr/bin/env ruby
# encoding: UTF-8
# Usage: hook-session-start <index_path> <store_root> <mode> [plugin_root]
# Outputs hook JSON for the session-start hook. Exits silently if nothing to show.

require "json"
require "date"
require "yaml"
require_relative "lib/bridge"

index_path, store_root, mode, plugin_root = ARGV
exit 0 unless index_path && store_root && mode

# --- Parse INDEX.md ---

lines = File.readlines(index_path)
active = []
future = []
section = nil

lines.each do |line|
  if line.start_with?("## Active")
    section = :active
    next
  elsif line.start_with?("## Future")
    section = :future
    next
  elsif line.start_with?("## ")
    section = nil
    next
  end

  next unless section && line.strip.start_with?("- [")

  if section == :active
    active << line.strip
  elsif section == :future
    future << line.strip
  end
end

# --- Derive bridge for active intent ---

bridge_data = nil
if active.length == 1 && active.first =~ /store\/([\w-]+)\//
  dir_name = $1
  intent_dir = "#{store_root}/store/#{dir_name}"
  session = ENV["CLAUDE_SESSION_ID"] || Process.pid.to_s
  intent_id = dir_name.split("--").first
  intent_name = active.first[/\[([^\]]+)\]/, 1] || "unknown"
  bridge_data = Bridge.derive(session, intent_id: intent_id, intent_dir: intent_dir, store: store_root, name: intent_name)
end

# --- Detect stale future intents ---

stale = []
read_config = if plugin_root && !plugin_root.empty?
  "#{plugin_root}/scripts/read-config"
else
  File.expand_path("~/.plastic/scripts/read-config")
end
stale_days = `"#{read_config}" stale_threshold_days`.strip.to_i
stale_days = 3 if stale_days == 0

future.each do |f|
  if f =~ /store\/([\w-]+)\//
    dir_name = $1
    intent_file = "#{store_root}/store/#{dir_name}/#{dir_name}.md"
    next unless File.exist?(intent_file)

    content = File.read(intent_file)
    if content =~ /^created:\s*['"]?(\d{4}-\d{2}-\d{2})/
      age = (Date.today - Date.parse($1)).to_i
      if age >= stale_days
        name = f[/\[([^\]]+)\]/, 1] || "unknown"
        stale << { name: name, age: age, entry: f }
      end
    end
  end
end

# --- Detect current project ---

current_project = nil
project_active = []
project_future = []

projects_path = "#{store_root}/projects.yml"
if File.exist?(projects_path)
  projects = YAML.safe_load(File.read(projects_path)) rescue {}
  cwd = Dir.pwd
  (projects["projects"] || {}).each do |slug, info|
    project_path = File.expand_path(info["path"])
    if cwd.start_with?(project_path)
      current_project = { "slug" => slug, "parent" => info["parent"], "path" => project_path }
      project_index = "#{store_root}/projects/#{slug}/INDEX.md"
      if File.exist?(project_index)
        p_section = nil
        File.readlines(project_index).each do |pline|
          if pline.start_with?("## Active")
            p_section = :active
            next
          elsif pline.start_with?("## Future")
            p_section = :future
            next
          elsif pline.start_with?("## ")
            p_section = nil
            next
          end
          next unless p_section && pline.strip.start_with?("- [")
          project_active << pline.strip if p_section == :active
          project_future << pline.strip if p_section == :future
        end
      end
      break
    end
  end
end

# --- Load deprecations ---

deprecations = []
if plugin_root && !plugin_root.empty?
  dep_file = "#{plugin_root}/deprecations.yml"
  if File.exist?(dep_file)
    dep_data = YAML.safe_load(File.read(dep_file)) rescue {}
    deprecations = dep_data["deprecations"] || []
  end
end

dismissed_json = `"#{read_config}" deprecations_dismissed`.strip
dismissed = begin
  JSON.parse(dismissed_json)
rescue
  []
end

current_version = nil
if plugin_root && !plugin_root.empty?
  plugin_json_path = "#{plugin_root}/.claude-plugin/plugin.json"
  if File.exist?(plugin_json_path)
    pj = JSON.parse(File.read(plugin_json_path)) rescue {}
    current_version = pj["version"]
  end
end

active_deprecations = deprecations.select do |dep|
  next true if dep["severity"] == "critical"
  next true if current_version && dep["removal"] == current_version
  !dismissed.include?(dep["id"])
end

# --- Early exit if nothing to show ---

all_active = active + project_active
all_future = future + project_future
exit 0 if all_active.empty? && stale.empty? && all_future.empty? && active_deprecations.empty?

# --- Build context ---

parts = []

if current_project
  parts << "PLASTIC — Global store | Project: #{current_project["slug"]} (#{current_project["path"]})\n"
else
  parts << "PLASTIC — Global store loaded from ~/.plastic/\n"
end

if all_active.any?
  parts << "Active intents:\n"
  all_active.each { |a| parts << a }
  if bridge_data
    stage = bridge_data["build"]["stage"]
    missing = bridge_data["build"]["missing"]
    missing_str = missing.empty? ? "none" : missing.join(", ")
    parts << "Stage: #{stage} | Next: #{missing_str}"
  end
  parts << ""
else
  parts << "No active intents. #{future.length} future intents available.\n"
end

if stale.any?
  parts << "\nStale future intents (untouched for days):\n"
  stale.each do |s|
    parts << "- #{s[:name]} (#{s[:age]} days) — consider: activate, abandon, or defer to agent"
  end
  parts << "\nWhen appropriate, ask the user what to do with stale intents."
end

if active_deprecations.any?
  parts << ""
  active_deprecations.each do |dep|
    severity = dep["severity"] || "info"
    summary = dep["summary"] || dep["id"]
    removal = dep["removal"]
    link = dep["link"]
    steps = dep["migration_steps"] || []

    if severity == "info"
      line = "i Deprecation: #{summary}. Removed in: #{removal}."
      line += " See: #{link}" if link
      parts << line
    else
      marker = severity == "critical" ? "!! DEPRECATION (critical)" : "! DEPRECATION (warning)"
      parts << "#{marker}: #{summary}"
      if steps.any?
        parts << "  Migration steps:"
        steps.each_with_index { |s, i| parts << "  #{i + 1}. #{s}" }
      end
      trail = "  Removed in: #{removal}"
      trail += " | Details: #{link}" if link
      parts << trail
    end
  end
end

payload = {
  "hookSpecificOutput" => {
    "hookEventName" => "SessionStart",
    "additionalContext" => parts.join("\n")
  }
}
puts JSON.generate(payload)
