import { hoverTooltip, type EditorView, type Tooltip } from "@codemirror/view";

/**
 * µFrame keyword hover tooltips — shows syntax, attributes, and examples
 * when hovering over a DSL keyword in the editor.
 */

interface KeywordDoc {
  syntax: string;
  attrs: string;
  example: string;
}

const KEYWORD_DOCS: Record<string, KeywordDoc> = {
  // Layout
  page: {
    syntax: 'page "title" [width]',
    attrs: "title: string — page title\nwidth: number — page width in chars (default: 64)",
    example: 'page "Node Status" 60',
  },
  box: {
    syntax: 'box [weight] "title"',
    attrs: "weight: light | heavy | double | rounded\ntitle: string — title in top border",
    example: 'box double "System"\n  text "Content here"',
  },
  row: {
    syntax: "row [gap]",
    attrs: "gap: number — space between columns (default: 1)",
    example: "row 2\n  col 20\n    text \"Left\"\n  col\n    text \"Right\"",
  },
  col: {
    syntax: "col [width]",
    attrs: "width: number — column width in chars (auto if omitted)",
    example: "col 30\n  text \"Fixed width column\"",
  },
  spacer: {
    syntax: "spacer [lines]",
    attrs: "lines: number — vertical space (default: 1)",
    example: "spacer 2",
  },
  pad: {
    syntax: "pad [top] [right] [bottom] [left]",
    attrs: "top, right, bottom, left: number — padding in chars",
    example: "pad 1 2 1 2\n  text \"Padded content\"",
  },

  // Content
  heading: {
    syntax: 'heading [level] "text"',
    attrs: "level: 1 | 2 | 3 — heading size\ntext: string — heading text",
    example: 'heading 1 "Main Title"',
  },
  text: {
    syntax: 'text "content"',
    attrs: "content: string — supports @bold{}, @italic{},\n  @color{hex}{}, @bg{hex}{}, @under{}",
    example: 'text "Hello @bold{world} @color{0f0}{green}"',
  },
  label: {
    syntax: 'label "key" "value"',
    attrs: "key: string — label name (bold)\nvalue: string — label value",
    example: 'label "Uptime" "14d 3h 22m"',
  },
  divider: {
    syntax: "divider [style]",
    attrs: "style: light | heavy | double | dash | dot",
    example: "divider heavy",
  },
  link: {
    syntax: 'link "display" "destination"',
    attrs: "display: string — visible text\ndestination: string — Micron page path",
    example: 'link "Home" "/page/index.mu"',
  },
  list: {
    syntax: "list [style]",
    attrs: "style: bullet | dash | number | arrow",
    example: 'list bullet\n  item "First entry"\n  item "Second entry"',
  },
  item: {
    syntax: 'item "text" OR item "label" "dest" [active]',
    attrs: "text: string — list item content\nlabel, dest: nav item with link\nactive: flag — highlight as current",
    example: 'item "Entry" — in list\nitem "Home" "/page/index.mu" active — in nav',
  },

  // Data Visualization
  gauge: {
    syntax: 'gauge "label" value max width [warn=N] [crit=N]',
    attrs: "label: string — gauge name\nvalue: number — current value\nmax: number — maximum\nwidth: number — bar width in chars\nwarn: number — warning threshold\ncrit: number — critical threshold",
    example: 'gauge "CPU" 62 100 28 warn=75 crit=90',
  },
  sparkline: {
    syntax: 'sparkline "label" "values" width',
    attrs: "label: string — chart name\nvalues: string — comma-separated numbers\nwidth: number — chart width in chars",
    example: 'sparkline "Traffic" "1,3,5,8,7,5,3" 20',
  },
  status: {
    syntax: 'status "label" state',
    attrs: "label: string — indicator name\nstate: online | offline | degraded | unknown | alert",
    example: 'status "East Relay" online',
  },
  table: {
    syntax: 'table "title"',
    attrs: "title: string — table caption\nchildren: columns + row entries",
    example: 'table "Routes"\n  columns "Dest" 20 | "Hops" 6\n  row "east" | "2"',
  },
  columns: {
    syntax: 'columns "name" width | "name" width | ...',
    attrs: "name: string — column header\nwidth: number — column width in chars\nseparated by | pipes",
    example: 'columns "Name" 20 | "Status" 10',
  },

  // Navigation
  hnav: {
    syntax: "hnav [style]",
    attrs: "style: bar | tabs | pills | breadcrumb | underline\nchildren: item, separator",
    example: 'hnav bar\n  item "Status" "/page/status.mu" active\n  item "Peers" "/page/peers.mu"',
  },
  vnav: {
    syntax: "vnav [style] [width]",
    attrs: "style: list | boxed | tree | sidebar | minimal\nwidth: number — panel width (auto if omitted)\nchildren: item, separator, heading",
    example: 'vnav boxed\n  heading "Section"\n  item "Page" "/page/page.mu" active',
  },

  // Forms
  form: {
    syntax: 'form "name"',
    attrs: "name: string — form identifier\nchildren: field, password, radio, checkbox, button",
    example: 'form "search"\n  field "query" 30 "Search..."\n  button "Go" "/page/search.mu"',
  },
  field: {
    syntax: 'field "name" [width] "placeholder"',
    attrs: "name: string — field name\nwidth: number — input width (default: 24)\nplaceholder: string — hint text",
    example: 'field "query" 30 "Enter search term..."',
  },
  password: {
    syntax: 'password "name" [width] "placeholder"',
    attrs: "name: string — field name\nwidth: number — input width (default: 24)\nplaceholder: string — hint text",
    example: 'password "pass" 24 "Enter password"',
  },
  radio: {
    syntax: 'radio "group" "opt1" | "opt2" | "opt3"',
    attrs: "group: string — radio group name\noptions: strings separated by | pipes",
    example: 'radio "mode" "Ping" | "Trace" | "Page"',
  },
  checkbox: {
    syntax: 'checkbox "name" "label"',
    attrs: "name: string — field name\nlabel: string — display text",
    example: 'checkbox "verbose" "Verbose output"',
  },
  button: {
    syntax: 'button "label" "destination"',
    attrs: "label: string — button text\ndestination: string — link target on click",
    example: 'button "Submit" "/page/submit.mu"',
  },

  // Big Text & Image
  bigtitle: {
    syntax: 'bigtitle "text" [font]',
    attrs: "text: string — text to render large\nfont: block | thin | pixel\nmodifiers: align, color",
    example: 'bigtitle "RELAY" block\n  align center\n  color 0cf',
  },
  image: {
    syntax: 'image "path" [mode] [width]',
    attrs: "path: string — image file path\nmode: braille | block | ascii | halfblock\nwidth: number — output width in chars\nmodifiers: dither, invert, align, caption",
    example: 'image "logo.png" braille 30\n  dither floyd\n  caption "Logo"',
  },

  // Style
  align: {
    syntax: "align [direction]",
    attrs: "direction: left | center | right",
    example: "align center",
  },
  color: {
    syntax: "color [hex]",
    attrs: "hex: 3-digit hex color (e.g. 0f0, f00, 0cf)",
    example: "color 0cf",
  },
  bold: {
    syntax: "bold",
    attrs: "no arguments — applies bold to parent",
    example: "box light \"Title\"\n  bold\n  text \"Bold content\"",
  },
  theme: {
    syntax: "theme [name]",
    attrs: "name: default | nouveau | gothic | bamboo | circuit | brutalist",
    example: "theme nouveau",
  },

  // Dynamic
  source: {
    syntax: 'source name : type "command"',
    attrs: "name: string — variable name\ntype: shell | file | json | python | rns | param\ncommand: string — command to execute",
    example: 'source cpu : shell "cat /proc/loadavg"',
  },
  let: {
    syntax: 'let name = "value"',
    attrs: "name: string — variable name\nvalue: string or number",
    example: 'let node_name = "Relay Alpha"',
  },
  cache: {
    syntax: "cache [seconds]",
    attrs: "seconds: number — cache duration (0 = never cache)",
    example: "cache 0",
  },
  if: {
    syntax: "if condition",
    attrs: "condition: expression with $variables\nchildren: content to show when true",
    example: "if $cpu > 90\n  text \"ALERT: CPU critical\"",
  },
  for: {
    syntax: "for var in $collection",
    attrs: "var: string — loop variable name\ncollection: $variable — iterable data",
    example: "for peer in $peers\n  status \"$peer\" online",
  },
  on_submit: {
    syntax: 'on_submit "form_name"',
    attrs: "form_name: string — form to handle\nchildren: handler logic with $field vars",
    example: 'on_submit "search"\n  source results : shell "search.py \'$query\'"',
  },
  state: {
    syntax: 'state "name" "path"',
    attrs: "name: string — state variable name\npath: string — JSON file path for persistence",
    example: 'state "counter" "/tmp/counter.json"',
  },

  // Components
  component: {
    syntax: "component name(arg1, arg2, ...)",
    attrs: "name: string — component name\nargs: parameter names\nchildren: component body template",
    example: 'component stat(label, value, max)\n  gauge "$label" $value $max 20',
  },
  use: {
    syntax: 'use "library"',
    attrs: "library: std/dashboard | std/status-bar | std/nav |\n  std/network | std/form | or file path",
    example: "use std/dashboard\nbanner \"My Node\" \"Mesh\"",
  },
};

function getWordAt(view: EditorView, pos: number): { word: string; from: number; to: number } | null {
  const line = view.state.doc.lineAt(pos);
  const text = line.text;
  const col = pos - line.from;

  let start = col;
  let end = col;
  while (start > 0 && /\w/.test(text[start - 1])) start--;
  while (end < text.length && /\w/.test(text[end])) end++;

  if (start === end) return null;
  return { word: text.slice(start, end), from: line.from + start, to: line.from + end };
}

export const keywordHoverTooltip = hoverTooltip((view, pos) => {
  const result = getWordAt(view, pos);
  if (!result) return null;

  const doc = KEYWORD_DOCS[result.word.toLowerCase()];
  if (!doc) return null;

  return {
    pos: result.from,
    end: result.to,
    above: true,
    create() {
      const dom = document.createElement("div");
      dom.className = "cm-keyword-tooltip";
      dom.innerHTML = `
        <div style="font-family:var(--font-mono);font-size:11px;max-width:360px;line-height:1.4">
          <div style="color:var(--primary);font-weight:bold;margin-bottom:4px;font-size:12px">${escHtml(doc.syntax)}</div>
          <div style="color:var(--muted-foreground);white-space:pre-wrap;margin-bottom:6px;border-bottom:1px solid var(--border);padding-bottom:6px">${escHtml(doc.attrs)}</div>
          <div style="color:var(--foreground);opacity:0.8;white-space:pre;background:var(--muted);padding:4px 6px;margin:-2px -6px -6px">${escHtml(doc.example)}</div>
        </div>
      `;
      return { dom };
    },
  } satisfies Tooltip;
});

function escHtml(s: string): string {
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
}
