/**
 * Workflow Context Manager
 *
 * Manages the "active workflow" state used to enforce the Context-First UX:
 * User MUST have an n8n workflow open before they can use AI chat to edit it.
 *
 * Storage: chrome.storage.session (ephemeral, cleared on browser restart)
 */
import { createLogger } from "./logger"

const logger = createLogger("WorkflowContext")

const STORAGE_KEY = "n8n_active_workflow"

// ─── Types ──────────────────────────────────────────────────────────

export interface WorkflowContext {
  /** n8n workflow ID (from URL) */
  workflowId: string
  /** Workflow display name (fetched from n8n API) */
  workflowName: string
  /** Simplified workflow structure for AI context */
  workflowSummary: string
  /** Full workflow JSON (optional, can be large) */
  workflowJson?: any
  /** n8n instance URL */
  n8nBaseUrl: string
  /** Timestamp when context was captured */
  capturedAt: number
  /** Tab ID of the n8n page */
  sourceTabId: number
}

// ─── URL Detection ──────────────────────────────────────────────────

/** n8n workflow URL patterns (supports various deployment configurations) */
const N8N_WORKFLOW_PATTERNS = [
  // Standard: /workflow/abc123
  /\/workflow\/([a-zA-Z0-9_-]+)/,
  // Alternative: /workflows/abc123
  /\/workflows\/([a-zA-Z0-9_-]+)/,
  // With execution: /workflow/abc123/executions/456
  /\/workflow\/([a-zA-Z0-9_-]+)\/executions/,
]

/** Check if a URL is an n8n workflow page and extract the ID */
export function extractWorkflowIdFromUrl(url: string): { workflowId: string; baseUrl: string } | null {
  try {
    const parsed = new URL(url)
    for (const pattern of N8N_WORKFLOW_PATTERNS) {
      const match = parsed.pathname.match(pattern)
      if (match?.[1]) {
        return {
          workflowId: match[1],
          baseUrl: `${parsed.protocol}//${parsed.host}`,
        }
      }
    }
  } catch {
    // Invalid URL
  }
  return null
}

/** Quick check if a URL looks like an n8n instance */
export function isN8nUrl(url: string): boolean {
  return extractWorkflowIdFromUrl(url) !== null
}

// ─── Workflow Summary Builder ───────────────────────────────────────

/** Build a compact summary of a workflow JSON for AI context injection */
export function buildWorkflowSummary(workflowJson: any): string {
  if (!workflowJson) return "Empty workflow"

  const name = workflowJson.name || "Untitled"
  const nodes = workflowJson.nodes || []
  const connections = workflowJson.connections || {}

  const nodeList = nodes.map((n: any) => `- ${n.name} (${n.type})`).join("\n")
  const connectionCount = Object.keys(connections).length

  return [
    `Workflow: "${name}"`,
    `Nodes (${nodes.length}):`,
    nodeList,
    `Connections: ${connectionCount} node(s) connected`,
  ].join("\n")
}

// ─── Storage Operations ─────────────────────────────────────────────

/** Save active workflow context */
export async function setActiveWorkflow(context: WorkflowContext): Promise<void> {
  try {
    await chrome.storage.session.set({ [STORAGE_KEY]: context })
    logger.info(`Active workflow set: ${context.workflowId} (${context.workflowName})`)
  } catch (err) {
    logger.error("Failed to set active workflow:", err)
    // Fallback to local storage if session not available
    await chrome.storage.local.set({ [STORAGE_KEY]: context })
  }
}

/** Get active workflow context */
export async function getActiveWorkflow(): Promise<WorkflowContext | null> {
  try {
    const data = await chrome.storage.session.get(STORAGE_KEY)
    return data[STORAGE_KEY] || null
  } catch {
    // Fallback
    const data = await chrome.storage.local.get(STORAGE_KEY)
    return data[STORAGE_KEY] || null
  }
}

/** Clear active workflow context */
export async function clearActiveWorkflow(): Promise<void> {
  try {
    await chrome.storage.session.remove(STORAGE_KEY)
    logger.info("Active workflow cleared")
  } catch {
    await chrome.storage.local.remove(STORAGE_KEY)
  }
}

// ─── Context Prompt Builder ─────────────────────────────────────────

/** Build the initial prompt to inject into AI chat */
export function buildContextPrompt(context: WorkflowContext): string {
  return [
    `I'm working on an n8n workflow.`,
    ``,
    `**Workflow ID:** ${context.workflowId}`,
    `**Name:** ${context.workflowName}`,
    `**Instance:** ${context.n8nBaseUrl}`,
    ``,
    `**Current structure:**`,
    "```",
    context.workflowSummary,
    "```",
    ``,
    `Please help me modify this workflow. When you need to make changes, use the available n8n MCP tools ` +
      `(like \`update_workflow\`, \`create_node\`, etc.) with workflow ID \`${context.workflowId}\`.`,
    ``,
    `What would you like me to change?`,
  ].join("\n")
}
