/**
 * SuperAssistant Content Script — Main Entry Point
 *
 * Injected into AI chat pages (ChatGPT, Gemini, etc.)
 * 1. Detects which AI platform is active
 * 2. Initializes MCP bridge (content ↔ background)
 * 3. Starts DOM observer to render function_call blocks
 * 4. ★ NEW: Fetches workflow context and injects into chat input
 */
import { logMessage, createLogger } from "./logger"
import { initializeBridge } from "./bridge"
import { detectAdapter } from "./adapters"
import { startObserver, stopObserver } from "./renderer"

const logger = createLogger("SuperAssistant")

async function initialize(): Promise<void> {
  logMessage("Content script loaded — initializing SuperAssistant")

  // 1. Detect platform
  const adapter = detectAdapter()
  if (!adapter) {
    logger.info("No supported AI platform detected on this page. SuperAssistant inactive.")
    return
  }

  logger.info(`Detected platform: ${adapter.name}`)

  // 2. Initialize adapter
  try {
    await adapter.initialize()
    await adapter.activate()
    // Expose adapter globally for renderer use
    ;(window as any).__n8nAdapter = adapter
    logger.info(`Adapter ${adapter.name} activated`)
  } catch (err) {
    logger.error(`Failed to initialize adapter ${adapter.name}:`, err)
  }

  // 3. Initialize MCP bridge
  try {
    initializeBridge()
    logger.info("MCP bridge ready")
  } catch (err) {
    logger.error("Failed to initialize MCP bridge:", err)
  }

  // 4. Start DOM observer (scans for function_call blocks in AI responses)
  try {
    startObserver()
    logger.info("DOM observer started — watching for function_call blocks")
  } catch (err) {
    logger.error("Failed to start DOM observer:", err)
  }

  // 5. ★ Context Injection — fetch workflow context and inject into chat
  try {
    await injectWorkflowContext(adapter)
  } catch (err) {
    logger.error("Context injection failed:", err)
  }

  logMessage(`SuperAssistant ready on ${adapter.name} ⚡`)
}

// ─── System Prompt Fallback ─────────────────────────────────────────

const SYSTEM_PROMPT_FALLBACK = `You are an expert n8n workflow automation engineer with direct API access to a live n8n instance through MCP (Model Context Protocol) tools. Your role is to design, build, modify, validate, and execute n8n workflows with maximum accuracy and efficiency.

## Available MCP Tools
Note: Since you are connected directly to n8n, tools DO NOT have the 'n8n_' prefix.
- list_workflows: List all workflows
- get_workflow: Get workflow JSON (full/structure/minimal)
- create_workflow: Create new workflow
- update_workflow: Full workflow update (replace)
- execute_workflow: Trigger workflow with input data
- list_credentials: List credential names/types

## Workflow Modification Process
1. Read Current State (get_workflow)
2. Understand Structure (identify nodes and connections)
3. Plan Changes (tell user)
4. Build & Update (update_workflow with COMPLETE JSON)
5. Verify (get_workflow structure)

## Critical Warnings
- Use \`={{ $json.field }}\` syntax for expressions.
- ALWAYS use the LATEST stable typeVersion for each node.
- Connections use SOURCE NODE NAME as key.

Respond in the SAME LANGUAGE as the user's message.
`;

// ─── Context Injection ──────────────────────────────────────────────

/**
 * Fetch active workflow context from background and inject into AI chat input.
 * This is the "Context-First" UX — user must have opened n8n workflow first.
 */
async function injectWorkflowContext(adapter: any): Promise<void> {
  // Ask background for active workflow context
  const response = await sendMessage({ type: "n8n-context:get" })

  if (!response?.success || !response.context) {
    logger.info("No active workflow context — user hasn't selected a workflow yet")
    return
  }

  const ctx = response.context
  logger.info(`Found workflow context: ${ctx.workflowId} (${ctx.workflowName})`)

  // Store context globally for bridge to auto-attach to tool calls
  ;(window as any).__n8nWorkflowContext = ctx

  // Fetch system prompt from MCP proxy (optional fallback)
  let systemPrompt = SYSTEM_PROMPT_FALLBACK
  try {
    const mcpConfig = await sendMessage({ type: "n8n-mcp:get-config" })
    const proxyUrl = mcpConfig?.proxyUrl || "http://localhost:3006"
    
    // If using local proxy, try to fetch its custom prompt
    if (proxyUrl.includes("localhost") || proxyUrl.includes("127.0.0.1")) {
      const res = await fetch(`${proxyUrl}/system-prompt`)
      if (res.ok) {
        systemPrompt = await res.text()
        logger.info("✅ System prompt loaded from local proxy")
      }
    } else {
      logger.info("ℹ️ Native MCP detected — using embedded system prompt")
    }
  } catch (err) {
    logger.info("⚠️ Using embedded system prompt fallback")
  }

  // Build the final prompt: system prompt + workflow context
  const prompt = buildContextPrompt(ctx, systemPrompt)

  // Wait a bit for the chat UI to fully render (especially on fresh page load)
  await sleep(2000)

  // Inject into chat input via adapter
  const inserted = await adapter.insertText(prompt)
  if (inserted) {
    logger.info("✅ Workflow context injected into chat input")
    // Trigger auto-send if the prompt is large (optional, but better for UX)
  } else {
    logger.info("⚠️ Could not inject context — chat input not found (user may type manually)")
  }
}

function buildContextPrompt(ctx: any, systemPrompt: string): string {
  const contextBlock = [
    `--- WORKFLOW CONTEXT ---`,
    `I'm working on this n8n workflow:`,
    `ID: ${ctx.workflowId}`,
    `Name: ${ctx.workflowName}`,
    `URL: ${ctx.n8nBaseUrl}/workflow/${ctx.workflowId}`,
    ``,
    `Current structure (JSON):`,
    "```json",
    ctx.workflowSummary,
    "```",
    `-----------------------`,
    ``,
    `I want you to help me with this workflow. Please use the MCP tools available to you to read or modify it.`,
  ].join("\n")

  return [
    `# INSTRUCTIONS`,
    systemPrompt,
    ``,
    contextBlock,
    ``,
    `My request: `,
  ].join("\n")
}

// ─── Helpers ────────────────────────────────────────────────────────

function sendMessage(msg: any): Promise<any> {
  return new Promise((resolve) => {
    chrome.runtime.sendMessage(msg, (response) => {
      resolve(response || {})
    })
  })
}

function sleep(ms: number): Promise<void> {
  return new Promise((r) => setTimeout(r, ms))
}

// ─── Lifecycle ──────────────────────────────────────────────────────

// Initialize when DOM is ready
if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", initialize)
} else {
  initialize()
}

// Cleanup on page unload
window.addEventListener("beforeunload", () => {
  stopObserver()
  logMessage("SuperAssistant cleanup complete")
})

// Listen for messages from background/popup
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
  if (message.command === "superassistant:status") {
    const adapter = (window as any).__n8nAdapter
    const ctx = (window as any).__n8nWorkflowContext
    sendResponse({
      active: !!adapter,
      platform: adapter?.name || null,
      adapterStatus: adapter?.getStatus() || "inactive",
      workflowId: ctx?.workflowId || null,
      workflowName: ctx?.workflowName || null,
    })
    return true
  }

  if (message.command === "superassistant:rescan") {
    import("./renderer").then(({ scanAndRender }) => {
      scanAndRender()
      sendResponse({ success: true })
    })
    return true
  }
})
