ObjC.import("AppKit");
ObjC.import("Foundation");

const FIRST_BUTTON = 1000;
const CORAL = $.NSColor.colorWithSRGBRedGreenBlueAlpha(0.86, 0.27, 0.20, 1.0);
let STATUS_ITEM = null;
let MENU_CONTROLLER = null;
let SETUP_CONTROLLER = null;

function frame(x, y, width, height) {
  return $.NSMakeRect(x, y, width, height);
}

function textLabel(text, rect, size, weight, color) {
  const label = $.NSTextField.alloc.initWithFrame(rect);
  label.stringValue = text;
  label.editable = false;
  label.selectable = false;
  label.bezeled = false;
  label.drawsBackground = false;
  label.font = $.NSFont.systemFontOfSizeWeight(size, weight);
  label.textColor = color || $.NSColor.labelColor;
  return label;
}

function wrappedLabel(text, rect, size, color) {
  const label = textLabel(text, rect, size, $.NSFontWeightRegular, color);
  label.usesSingleLineMode = false;
  label.cell.wraps = true;
  label.cell.lineBreakMode = $.NSLineBreakByWordWrapping;
  return label;
}

function symbol(name, description, size, color) {
  let image = $.NSImage.imageWithSystemSymbolNameAccessibilityDescription(name, description);
  if (!image) return null;
  const pointConfig = $.NSImageSymbolConfiguration.configurationWithPointSizeWeight(size, $.NSFontWeightMedium);
  image = image.imageWithSymbolConfiguration(pointConfig);
  if (color && $.NSImageSymbolConfiguration.respondsToSelector("configurationWithHierarchicalColor:")) {
    const colorConfig = $.NSImageSymbolConfiguration.configurationWithHierarchicalColor(color);
    image = image.imageWithSymbolConfiguration(colorConfig);
  }
  return image;
}

function configureAlert(alert, iconName, iconDescription, iconColor) {
  alert.window.title = "sdlc.cc";
  alert.icon = symbol(iconName, iconDescription, 46, iconColor);
  alert.alertStyle = $.NSAlertStyleInformational;
}

function addButtons(alert, primary, secondary) {
  alert.addButtonWithTitle(primary);
  if (secondary) {
    alert.addButtonWithTitle(secondary);
    alert.buttons.objectAtIndex(1).keyEquivalent = "\u001b";
  }
}

function commandItem(title, action, keyEquivalent) {
  const item = $.NSMenuItem.alloc.initWithTitleActionKeyEquivalent(title, null, "");
  item.setAction(action);
  item.setKeyEquivalent(keyEquivalent || "");
  // A nil target sends the action through the responder chain to the active
  // field editor. NSSecureTextField then handles paste without the installer
  // ever reading the clipboard itself.
  item.setTarget(null);
  return item;
}

function installEditMenu(app) {
  const mainMenu = $.NSMenu.alloc.initWithTitle("Main Menu");

  const appMenuItem = $.NSMenuItem.alloc.initWithTitleActionKeyEquivalent("sdlc.cc", null, "");
  const appMenu = $.NSMenu.alloc.initWithTitle("sdlc.cc");
  appMenu.addItem(commandItem("Quit sdlc.cc", "terminate:", "q"));
  appMenuItem.setSubmenu(appMenu);
  mainMenu.addItem(appMenuItem);

  const editMenuItem = $.NSMenuItem.alloc.initWithTitleActionKeyEquivalent("Edit", null, "");
  const editMenu = $.NSMenu.alloc.initWithTitle("Edit");
  editMenu.addItem(commandItem("Undo", "undo:", "z"));
  editMenu.addItem(commandItem("Redo", "redo:", "Z"));
  editMenu.addItem($.NSMenuItem.separatorItem);
  editMenu.addItem(commandItem("Cut", "cut:", "x"));
  editMenu.addItem(commandItem("Copy", "copy:", "c"));
  editMenu.addItem(commandItem("Paste", "paste:", "v"));
  editMenu.addItem(commandItem("Select All", "selectAll:", "a"));
  editMenuItem.setSubmenu(editMenu);
  mainMenu.addItem(editMenuItem);

  app.setMainMenu(mainMenu);
}

function activate() {
  const app = $.NSApplication.sharedApplication;
  app.setActivationPolicy($.NSApplicationActivationPolicyAccessory);
  installEditMenu(app);
  app.activateIgnoringOtherApps(true);
}

function applyClipboardText(keyField, validationLabel, rawText) {
  const text = rawText ? ObjC.unwrap(rawText).trim() : "";
  if (!text) {
    validationLabel.stringValue = "The clipboard does not contain text.";
    return false;
  }
  keyField.stringValue = text;
  validationLabel.stringValue = "";
  return true;
}

function securePasteButton(keyField, validationLabel, pasteboard) {
  ObjC.registerSubclass({
    name: "SDLCSecurePasteController",
    methods: {
      "pasteKey:": {
        types: ["void", ["id"]],
        implementation: function () {
          applyClipboardText(
            keyField,
            validationLabel,
            pasteboard.stringForType($.NSPasteboardTypeString),
          );
        },
      },
    },
  });

  SETUP_CONTROLLER = $.SDLCSecurePasteController.alloc.init;
  const button = $.NSButton.alloc.initWithFrame(frame(334, 55, 96, 30));
  button.title = "Paste Key";
  button.bezelStyle = $.NSBezelStyleRounded;
  button.setTarget(SETUP_CONTROLLER);
  button.setAction("pasteKey:");
  button.accessibilityLabel = "Paste tenant key from clipboard";
  return button;
}

function menuItem(title, action, target) {
  const item = $.NSMenuItem.alloc.initWithTitleActionKeyEquivalent(title, action || null, "");
  if (target) item.setTarget(target);
  return item;
}

function launchAppAction(executable, args) {
  const task = $.NSTask.alloc.init;
  task.setLaunchPath(executable);
  task.setArguments($(args));
  task.launch;
}

function statusMenu(executable, gateway) {
  ObjC.registerSubclass({
    name: "SDLCStatusMenuController",
    methods: {
      "verify:": {
        types: ["void", ["id"]],
        implementation: function () {
          launchAppAction(executable, ["-verify"]);
        },
      },
      "configure:": {
        types: ["void", ["id"]],
        implementation: function () {
          launchAppAction(executable, ["-configure", "-exit-after-install"]);
        },
      },
      "openGuide:": {
        types: ["void", ["id"]],
        implementation: function () {
          $.NSWorkspace.sharedWorkspace.openURL($.NSURL.URLWithString("https://sdlc.cc/docs/"));
        },
      },
      "quit:": {
        types: ["void", ["id"]],
        implementation: function () {
          $.NSApplication.sharedApplication.terminate(null);
        },
      },
    },
  });

  MENU_CONTROLLER = $.SDLCStatusMenuController.alloc.init;
  const menu = $.NSMenu.alloc.initWithTitle("sdlc.cc Privacy Gateway");

  const header = menuItem("sdlc.cc Privacy Gateway", null, null);
  header.enabled = false;
  menu.addItem(header);

  const protectedItem = menuItem("Protected", null, null);
  protectedItem.enabled = false;
  protectedItem.state = $.NSControlStateValueOn;
  menu.addItem(protectedItem);

  const gatewayItem = menuItem(gateway, null, null);
  gatewayItem.enabled = false;
  gatewayItem.indentationLevel = 1;
  menu.addItem(gatewayItem);

  menu.addItem($.NSMenuItem.separatorItem);
  menu.addItem(menuItem("Verify Setup…", "verify:", MENU_CONTROLLER));
  menu.addItem(menuItem("Change Settings…", "configure:", MENU_CONTROLLER));
  menu.addItem(menuItem("Open Setup Guide", "openGuide:", MENU_CONTROLLER));
  menu.addItem($.NSMenuItem.separatorItem);
  menu.addItem(menuItem("Quit sdlc.cc", "quit:", MENU_CONTROLLER));
  return menu;
}

function runStatusApp(executable, gateway) {
  const app = $.NSApplication.sharedApplication;
  app.setActivationPolicy($.NSApplicationActivationPolicyAccessory);

  STATUS_ITEM = $.NSStatusBar.systemStatusBar.statusItemWithLength($.NSVariableStatusItemLength);
  const icon = symbol("shield.lefthalf.filled", "sdlc.cc privacy gateway protected", 16, null);
  icon.template = true;
  STATUS_ITEM.button.image = icon;
  STATUS_ITEM.button.imagePosition = $.NSImageOnly;
  STATUS_ITEM.button.toolTip = "sdlc.cc — Claude Code protected";
  STATUS_ITEM.button.accessibilityLabel = "sdlc.cc privacy gateway — Protected";
  STATUS_ITEM.menu = statusMenu(executable, gateway);

  app.run;
  return "quit";
}

function setupPanel(defaultGateway) {
  const alert = $.NSAlert.alloc.init;
  configureAlert(alert, "shield.lefthalf.filled", "Privacy gateway", CORAL);
  alert.messageText = "Protect Claude Code";
  alert.informativeText = "Route supported prompts through the sdlc.cc privacy gateway before they reach Anthropic.";
  addButtons(alert, "Install Protection", "Cancel");

  const view = $.NSView.alloc.initWithFrame(frame(0, 0, 430, 184));
  const gatewayLabel = textLabel("Gateway URL", frame(0, 158, 430, 18), 12, $.NSFontWeightSemibold);
  const gateway = $.NSTextField.alloc.initWithFrame(frame(0, 122, 430, 30));
  gateway.stringValue = defaultGateway || "https://api.sdlc.cc";
  gateway.placeholderString = "https://api.sdlc.cc";
  gateway.font = $.NSFont.systemFontOfSize(13);
  gateway.accessibilityLabel = "Gateway URL";

  const keyLabel = textLabel("Tenant key", frame(0, 91, 430, 18), 12, $.NSFontWeightSemibold);
  const key = $.NSSecureTextField.alloc.initWithFrame(frame(0, 55, 324, 30));
  key.placeholderString = "sk_sdlc_…";
  key.font = $.NSFont.systemFontOfSize(13);
  key.editable = true;
  key.selectable = true;
  key.enabled = true;
  key.accessibilityLabel = "Tenant key";

  const privacy = wrappedLabel(
    "Messages-scoped key. Saved for this macOS user; never sent by the installer.",
    frame(0, 23, 430, 26),
    11,
    $.NSColor.secondaryLabelColor,
  );
  const validation = wrappedLabel("", frame(0, 0, 430, 18), 11, $.NSColor.systemRedColor);
  const pasteKey = securePasteButton(key, validation, $.NSPasteboard.generalPasteboard);

  view.addSubview(gatewayLabel);
  view.addSubview(gateway);
  view.addSubview(keyLabel);
  view.addSubview(key);
  view.addSubview(pasteKey);
  view.addSubview(privacy);
  view.addSubview(validation);
  alert.accessoryView = view;
  alert.window.initialFirstResponder = key;
  gateway.nextKeyView = key;
  key.nextKeyView = gateway;

  while (true) {
    const response = Number(alert.runModal);
    if (response !== FIRST_BUTTON) return JSON.stringify({ canceled: true });

    const gatewayValue = ObjC.unwrap(gateway.stringValue).trim();
    const keyValue = ObjC.unwrap(key.stringValue).trim();
    if (!gatewayValue.startsWith("https://") && !gatewayValue.startsWith("http://localhost") && !gatewayValue.startsWith("http://127.0.0.1")) {
      validation.stringValue = "Enter a complete HTTPS gateway URL.";
      alert.window.initialFirstResponder = gateway;
      continue;
    }
    if (!keyValue.startsWith("sk_sdlc_") || /\s/.test(keyValue)) {
      validation.stringValue = "Enter a tenant key beginning with sk_sdlc_.";
      alert.window.initialFirstResponder = key;
      continue;
    }
    return JSON.stringify({ gateway: gatewayValue, apiKey: keyValue, canceled: false });
  }
}

function statusAccessory(gateway, keyText, ok, nextText) {
  const view = $.NSView.alloc.initWithFrame(frame(0, 0, 430, 130));
  const stateIcon = $.NSImageView.alloc.initWithFrame(frame(0, 105, 18, 18));
  stateIcon.image = symbol(ok ? "checkmark.circle.fill" : "exclamationmark.triangle.fill", ok ? "Protected" : "Needs attention", 16, ok ? $.NSColor.systemGreenColor : $.NSColor.systemOrangeColor);
  const state = textLabel(ok ? "Protected" : "Needs attention", frame(25, 104, 250, 20), 12, $.NSFontWeightSemibold, ok ? $.NSColor.systemGreenColor : $.NSColor.systemOrangeColor);

  const gatewayLabel = textLabel("Gateway", frame(0, 72, 100, 18), 12, $.NSFontWeightRegular, $.NSColor.secondaryLabelColor);
  const gatewayValue = textLabel(gateway || "Not configured", frame(112, 72, 318, 18), 12, $.NSFontWeightMedium);
  gatewayValue.alignment = $.NSTextAlignmentRight;
  gatewayValue.lineBreakMode = $.NSLineBreakByTruncatingMiddle;

  const keyLabel = textLabel("Tenant key", frame(0, 45, 100, 18), 12, $.NSFontWeightRegular, $.NSColor.secondaryLabelColor);
  const keyValue = textLabel(keyText, frame(112, 45, 318, 18), 12, $.NSFontWeightMedium);
  keyValue.alignment = $.NSTextAlignmentRight;

  const divider = $.NSBox.alloc.initWithFrame(frame(0, 33, 430, 1));
  divider.boxType = $.NSBoxSeparator;
  const next = wrappedLabel(nextText, frame(0, 0, 430, 24), 11, $.NSColor.secondaryLabelColor);

  [stateIcon, state, gatewayLabel, gatewayValue, keyLabel, keyValue, divider, next].forEach((item) => view.addSubview(item));
  return view;
}

function successPanel(gateway) {
  const alert = $.NSAlert.alloc.init;
  configureAlert(alert, "checkmark.shield.fill", "Protection installed", $.NSColor.systemGreenColor);
  alert.messageText = "Claude Code is protected";
  alert.informativeText = "The privacy gateway is ready for new Claude Code sessions.";
  alert.accessoryView = statusAccessory(
    gateway,
    "Configured",
    true,
    "Quit Claude Code completely, reopen it, then send a test prompt.",
  );
  addButtons(alert, "Done", null);
  Number(alert.runModal);
  return "ok";
}

function verificationPanel(gateway, keyState, ok) {
  const alert = $.NSAlert.alloc.init;
  configureAlert(
    alert,
    ok ? "checkmark.shield.fill" : "exclamationmark.triangle.fill",
    ok ? "Protection active" : "Setup needs attention",
    ok ? $.NSColor.systemGreenColor : $.NSColor.systemOrangeColor,
  );
  alert.messageText = ok ? "Protection is active" : "Setup needs attention";
  alert.informativeText = ok
    ? "Claude Code is routed through the configured privacy gateway."
    : "Open the installer again to repair the missing settings.";
  const keyText = keyState === "configured" ? "Configured" : keyState === "invalid" ? "Replace key" : "Not configured";
  alert.accessoryView = statusAccessory(
    gateway,
    keyText,
    ok,
    ok ? "New Claude Code sessions will inherit this configuration." : "A messages-scoped sk_sdlc_ key is required.",
  );
  addButtons(alert, ok ? "Done" : "Close", null);
  Number(alert.runModal);
  return "ok";
}

function genericAlert(title, body, kind) {
  const isError = kind === "error";
  const alert = $.NSAlert.alloc.init;
  configureAlert(
    alert,
    isError ? "exclamationmark.triangle.fill" : "info.circle.fill",
    isError ? "Setup error" : "Information",
    isError ? $.NSColor.systemOrangeColor : CORAL,
  );
  alert.alertStyle = isError ? $.NSAlertStyleWarning : $.NSAlertStyleInformational;
  alert.messageText = isError ? "Setup couldn’t finish" : title;
  alert.informativeText = body.replace(/^error:\s*/i, "");
  addButtons(alert, "OK", null);
  Number(alert.runModal);
  return "ok";
}

function auditSpec() {
  return JSON.stringify({
    framework: "AppKit",
    minimumMacOS: "12.0",
    setupTitle: "Protect Claude Code",
    primaryAction: "Install Protection",
    secureKeyField: true,
    accessibilityLabels: ["Gateway URL", "Tenant key"],
    successTitle: "Claude Code is protected",
    systemSymbols: ["shield.lefthalf.filled", "checkmark.shield.fill", "exclamationmark.triangle.fill"],
  });
}

function statusAudit() {
  return JSON.stringify({
    framework: "AppKit",
    presentation: "NSStatusItem",
    icon: "shield.lefthalf.filled",
    templateIcon: true,
    accessibilityLabel: "sdlc.cc privacy gateway — Protected",
    state: "Protected",
    actions: ["Verify Setup…", "Change Settings…", "Open Setup Guide", "Quit sdlc.cc"],
  });
}

function editMenuAudit() {
  const app = $.NSApplication.sharedApplication;
  installEditMenu(app);
  const editMenu = app.mainMenu.itemWithTitle("Edit").submenu;
  const paste = editMenu.itemWithTitle("Paste");
  return JSON.stringify({
    title: ObjC.unwrap(paste.title),
    action: ObjC.unwrap($.NSStringFromSelector(paste.action)),
    keyEquivalent: ObjC.unwrap(paste.keyEquivalent),
  });
}

function securePasteAudit() {
  const key = $.NSSecureTextField.alloc.initWithFrame(frame(0, 0, 100, 30));
  const validation = textLabel("", frame(0, 0, 100, 18), 11, $.NSFontWeightRegular);
  const button = securePasteButton(key, validation, {
    stringForType: function () { return $("sk_sdlc_fixture"); },
  });
  const applied = applyClipboardText(key, validation, $("  sk_sdlc_fixture  "));
  return JSON.stringify({
    applied: applied && ObjC.unwrap(key.stringValue) === "sk_sdlc_fixture",
    action: ObjC.unwrap($.NSStringFromSelector(button.action)),
    title: ObjC.unwrap(button.title),
  });
}

function run(argv) {
  const mode = argv[0] || "audit";
  if (mode === "audit") return auditSpec();
  if (mode === "edit-menu-audit") return editMenuAudit();
  if (mode === "secure-paste-audit") return securePasteAudit();
  if (mode === "status-audit") return statusAudit();
  if (mode === "status") return runStatusApp(argv[1], argv[2] || "https://api.sdlc.cc");
  activate();
  if (mode === "setup") return setupPanel(argv[1] || "https://api.sdlc.cc");
  if (mode === "success") return successPanel(argv[1] || "https://api.sdlc.cc");
  if (mode === "verify") return verificationPanel(argv[1] || "", argv[2] || "missing", argv[3] === "true");
  if (mode === "alert") return genericAlert(argv[1] || "sdlc.cc", argv[2] || "", argv[3] || "information");
  throw new Error(`Unknown UI mode: ${mode}`);
}
