import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import {
  forwardRef,
  useState,
  useImperativeHandle,
  useRef,
  useEffect,
  useMemo
} from "react";
import { Box, Text } from "ink";
import { ApprovalType } from "@dexto/core";
import { ElicitationForm } from "./ElicitationForm.js";
import { DiffPreview, CreateFilePreview } from "./renderers/index.js";
import { isEditWriteTool } from "../utils/toolUtils.js";
import { formatToolHeader } from "../utils/messageFormatting.js";
const ApprovalPrompt = forwardRef(
  ({ approval, onApprove, onDeny, onCancel }, ref) => {
    const isCommandApproval = approval.type === ApprovalType.COMMAND_APPROVAL;
    const isElicitation = approval.type === "elicitation";
    const toolName = approval.metadata.toolName;
    const toolArgs = approval.metadata.args || {};
    const approvalKey = typeof approval.metadata.approvalKey === "string" ? approval.metadata.approvalKey : void 0;
    const hasApprovalKey = approvalKey !== void 0;
    const callDescriptionRaw = typeof approval.metadata.description === "string" ? approval.metadata.description : void 0;
    const callDescription = useMemo(() => {
      if (!callDescriptionRaw) return null;
      const singleLine = callDescriptionRaw.replace(/\s+/g, " ").trim();
      if (!singleLine) return null;
      const maxLength = 120;
      if (singleLine.length <= maxLength) return singleLine;
      return `${singleLine.slice(0, Math.max(0, maxLength - 1))}\u2026`;
    }, [callDescriptionRaw]);
    const isPlanReview = toolName === "plan_review";
    const isEditOrWriteTool = isEditWriteTool(toolName);
    const presentationSnapshot = useMemo(() => {
      const raw = approval.metadata.presentationSnapshot;
      if (typeof raw !== "object" || raw === null) {
        return void 0;
      }
      if (raw.version !== 1) {
        return void 0;
      }
      return raw;
    }, [approval.metadata]);
    const formattedTool = useMemo(() => {
      if (!toolName) return null;
      return formatToolHeader({
        toolName,
        args: toolArgs,
        ...presentationSnapshot !== void 0 && { presentationSnapshot }
      });
    }, [toolName, toolArgs, presentationSnapshot]);
    const [selectedIndex, setSelectedIndex] = useState(0);
    const [showFeedbackInput, setShowFeedbackInput] = useState(false);
    const [feedbackText, setFeedbackText] = useState("");
    const elicitationFormRef = useRef(null);
    const selectedIndexRef = useRef(0);
    const options = [];
    if (isPlanReview) {
      options.push({ id: "plan-approve", label: "Approve" });
      options.push({ id: "plan-approve-accept-edits", label: "Approve + Accept All Edits" });
    } else if (isCommandApproval) {
      options.push({ id: "yes", label: "Yes" });
      options.push({ id: "no", label: "No" });
    } else if (hasApprovalKey) {
      options.push({ id: "yes", label: "Yes (once)" });
      options.push({ id: "yes-session", label: "Yes, remember this approval" });
      options.push({ id: "no", label: "No" });
    } else if (isEditOrWriteTool) {
      options.push({ id: "yes", label: "Yes" });
      options.push({ id: "yes-accept-edits", label: "Yes, and accept all edits" });
      options.push({ id: "no", label: "No" });
    } else {
      options.push({ id: "yes", label: "Yes" });
      options.push({ id: "yes-session", label: "Yes (Session)" });
      options.push({ id: "no", label: "No" });
    }
    useEffect(() => {
      selectedIndexRef.current = selectedIndex;
    }, [selectedIndex]);
    const getCurrentOption = () => options[selectedIndexRef.current];
    useImperativeHandle(
      ref,
      () => ({
        handleInput: (input, key) => {
          if (isElicitation && elicitationFormRef.current) {
            return elicitationFormRef.current.handleInput(input, key);
          }
          const totalOptions = isPlanReview ? options.length + 1 : options.length;
          const isFeedbackSelected = isPlanReview && selectedIndexRef.current === options.length;
          if (isFeedbackSelected) {
            if (key.return) {
              onDeny(feedbackText || void 0);
              return true;
            } else if (key.backspace || key.delete) {
              setFeedbackText((prev) => prev.slice(0, -1));
              return true;
            } else if (key.upArrow) {
              setSelectedIndex(options.length - 1);
              return true;
            } else if (key.downArrow) {
              setSelectedIndex(0);
              return true;
            } else if (key.escape) {
              onCancel();
              return true;
            } else if (input && !key.ctrl && !key.meta) {
              setFeedbackText((prev) => prev + input);
              return true;
            }
            return true;
          }
          if (key.upArrow) {
            setSelectedIndex(
              (current) => current === 0 ? totalOptions - 1 : current - 1
            );
            return true;
          } else if (key.downArrow) {
            setSelectedIndex(
              (current) => current === totalOptions - 1 ? 0 : current + 1
            );
            return true;
          } else if (key.return) {
            const option = getCurrentOption();
            if (!option) return false;
            if (option.id === "plan-approve") {
              onApprove({});
            } else if (option.id === "plan-approve-accept-edits") {
              onApprove({ enableAcceptEditsMode: true });
            } else if (option.id === "yes") {
              onApprove({});
            } else if (option.id === "yes-session") {
              onApprove({ rememberChoice: true });
            } else if (option.id === "yes-accept-edits") {
              onApprove({ enableAcceptEditsMode: true });
            } else if (option.id === "no") {
              onDeny();
            }
            return true;
          } else if (key.shift && key.tab && isEditOrWriteTool) {
            onApprove({ enableAcceptEditsMode: true });
            return true;
          } else if (key.escape) {
            onCancel();
            return true;
          }
          return false;
        }
      }),
      [
        isElicitation,
        isEditOrWriteTool,
        isPlanReview,
        options,
        onApprove,
        onDeny,
        onCancel,
        feedbackText
      ]
    );
    if (isElicitation) {
      const metadata = approval.metadata;
      return /* @__PURE__ */ jsx(
        ElicitationForm,
        {
          ref: elicitationFormRef,
          metadata,
          onSubmit: (formData) => onApprove({ formData }),
          onCancel
        }
      );
    }
    const command = approval.metadata.command;
    const displayPreview = approval.metadata.displayPreview;
    const renderPreview = () => {
      if (!displayPreview) return null;
      switch (displayPreview.type) {
        case "diff":
          return /* @__PURE__ */ jsx(DiffPreview, { data: displayPreview });
        case "shell":
          return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
            /* @__PURE__ */ jsx(Box, { marginBottom: 0, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: displayPreview.title ?? "Bash" }) }),
            /* @__PURE__ */ jsxs(
              Box,
              {
                flexDirection: "column",
                borderStyle: "round",
                borderColor: "gray",
                paddingX: 1,
                children: [
                  displayPreview.command.split("\n").map((line, i) => /* @__PURE__ */ jsxs(Text, { color: "yellowBright", wrap: "wrap", children: [
                    i === 0 ? "$ " : "  ",
                    line
                  ] }, i)),
                  displayPreview.isBackground && /* @__PURE__ */ jsx(Text, { color: "gray", children: "(background)" })
                ]
              }
            ),
            callDescription && /* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: callDescription }) })
          ] });
        case "file":
          if (displayPreview.content) {
            return /* @__PURE__ */ jsx(CreateFilePreview, { data: displayPreview });
          }
          return /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
            displayPreview.operation === "read" && `Read ${displayPreview.lineCount ?? "file"} lines`,
            displayPreview.operation === "write" && `Write to ${displayPreview.path}`,
            displayPreview.operation === "delete" && `Delete ${displayPreview.path}`
          ] }) });
        default:
          return null;
      }
    };
    const showHeaderBlock = isCommandApproval || !displayPreview;
    return /* @__PURE__ */ jsxs(Box, { paddingX: 0, paddingY: 0, flexDirection: "column", children: [
      showHeaderBlock && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 0, children: isCommandApproval ? /* @__PURE__ */ jsxs(Fragment, { children: [
        /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: /* @__PURE__ */ jsxs(Text, { color: "yellowBright", bold: true, children: [
          "Confirm command:",
          " "
        ] }) }),
        command && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 0, children: /* @__PURE__ */ jsx(
          Box,
          {
            flexDirection: "column",
            borderStyle: "round",
            borderColor: "gray",
            paddingX: 1,
            children: command.split("\n").map((line, i) => /* @__PURE__ */ jsx(Text, { color: "red", wrap: "wrap", children: line }, i))
          }
        ) })
      ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
        /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
          /* @__PURE__ */ jsxs(Text, { color: "yellowBright", bold: true, children: [
            "Confirm:",
            " "
          ] }),
          formattedTool && /* @__PURE__ */ jsx(Text, { color: "cyan", children: formattedTool.header })
        ] }),
        callDescription && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", marginTop: 0, children: [
          /* @__PURE__ */ jsx(Text, { color: "gray", children: "  " }),
          /* @__PURE__ */ jsx(Text, { color: "gray", children: callDescription })
        ] })
      ] }) }),
      renderPreview(),
      /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 0, children: [
        options.map((option, index) => {
          const isSelected = index === selectedIndex;
          const isNo = option.id === "no";
          return /* @__PURE__ */ jsx(Box, { children: isSelected ? /* @__PURE__ */ jsxs(Text, { color: isNo ? "red" : "green", bold: true, children: [
            "  \u25B6 ",
            option.label
          ] }) : /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
            "    ",
            option.label
          ] }) }, option.id);
        }),
        isPlanReview && /* @__PURE__ */ jsx(Box, { children: selectedIndex === options.length ? (
          // Selected - show editable input
          /* @__PURE__ */ jsxs(Box, { flexDirection: "row", children: [
            /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "  \u25B6 " }),
            feedbackText ? /* @__PURE__ */ jsxs(Text, { color: "white", children: [
              feedbackText,
              /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u258B" })
            ] }) : /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
              "What changes would you like?",
              /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u258B" })
            ] })
          ] })
        ) : (
          // Not selected - show placeholder
          /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
            "    ",
            feedbackText || "What changes would you like?"
          ] })
        ) })
      ] }),
      /* @__PURE__ */ jsx(Box, { marginTop: 0, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
        "  ",
        "\u2191\u2193 to select \u2022 Enter to confirm \u2022 Esc to cancel"
      ] }) })
    ] });
  }
);
ApprovalPrompt.displayName = "ApprovalPrompt";
export {
  ApprovalPrompt
};
