import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";
import { MessageMarkdown } from "./MessageMarkdown";
import type { PlanApproval } from "../../stores/useAppStore";
import { readPlanFile, sendRemoteCommand } from "../../services/tauri";
import { CopyButton } from "../shared/CopyButton";
import { useWorkspaceFileOpener } from "./useWorkspaceFileOpener";
import styles from "./PlanApprovalCard.module.css";

interface PlanApprovalCardProps {
  approval: PlanApproval;
  /** Owning workspace for the plan. Lets the rendered plan content route
   *  file-path clicks into this workspace's Monaco tab instead of falling
   *  through to the OS default editor — plans frequently enumerate
   *  "Critical Files" with absolute paths under `~/.claudette/workspaces/`,
   *  which previously rendered as `<a href="claudettepath:…">` links with
   *  no in-app opener context. */
  workspaceId: string;
  /**
   * Called with the user's decision. `approved=true` lets the CLI run the
   * ExitPlanMode tool's `call()` (which writes the plan file and emits the
   * real tool_result). `approved=false` sends a deny with the given reason.
   */
  onRespond: (approved: boolean, reason?: string) => void;
  remoteConnectionId?: string;
}

export function PlanApprovalCard({
  approval,
  workspaceId,
  onRespond,
  remoteConnectionId,
}: PlanApprovalCardProps) {
  const { t } = useTranslation("chat");
  const [planContent, setPlanContent] = useState<string | null>(null);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [loading, setLoading] = useState(false);
  const [expanded, setExpanded] = useState(false);
  const [feedback, setFeedback] = useState("");
  // Memoize an in-flight read so concurrent callers (e.g. user clicks
  // Copy and View Plan in quick succession) share a single network call
  // instead of issuing duplicate `readPlanFile` / `sendRemoteCommand`
  // requests. Cleared in a `finally` so a failed fetch can be retried.
  const inFlightFetchRef = useRef<Promise<string> | null>(null);
  const { openFile, resolveFilePath } = useWorkspaceFileOpener(workspaceId);
  const directPlanContent = approval.planContent ?? null;
  const visiblePlanContent = directPlanContent ?? planContent;
  const hasPlanPreview = approval.planFilePath !== null || directPlanContent !== null;

  useEffect(() => {
    inFlightFetchRef.current = null;
    setPlanContent(null);
    setLoadError(null);
    setLoading(false);
    setExpanded(false);
  }, [approval.toolUseId]);

  const fetchPlanContent = (): Promise<string> => {
    if (directPlanContent !== null) return Promise.resolve(directPlanContent);
    if (planContent !== null) return Promise.resolve(planContent);
    if (inFlightFetchRef.current) return inFlightFetchRef.current;
    if (!approval.planFilePath) {
      return Promise.reject(new Error("No plan file path"));
    }
    const planFilePath = approval.planFilePath;
    const promise = (async () => {
      const content = remoteConnectionId
        ? ((await sendRemoteCommand(remoteConnectionId, "read_plan_file", {
            path: planFilePath,
          })) as string)
        : await readPlanFile(planFilePath);
      setPlanContent(content);
      return content;
    })().finally(() => {
      inFlightFetchRef.current = null;
    });
    inFlightFetchRef.current = promise;
    return promise;
  };

  const handleViewPlan = async () => {
    if (visiblePlanContent !== null) {
      setExpanded(!expanded);
      return;
    }
    if (!approval.planFilePath) return;
    setLoadError(null);
    setLoading(true);
    try {
      await fetchPlanContent();
      setExpanded(true);
    } catch (e) {
      console.error("Failed to read plan file:", e);
      setLoadError(t("plan_approval_failed_read"));
      setExpanded(true);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className={styles.card}>
      <div className={styles.label}>{t("plan_approval_label")}</div>

      <div className={styles.description}>
        {t("plan_approval_description")}
      </div>

      {hasPlanPreview && (
        <div className={styles.planActions}>
          <button
            className={styles.planLink}
            onClick={handleViewPlan}
            disabled={loading}
          >
            {loading
              ? t("plan_approval_loading")
              : expanded
                ? t("plan_approval_hide_plan")
                : t("plan_approval_view_plan")}
            {" \u2014 "}
            {approval.planFilePath
              ? approval.planFilePath.split("/").slice(-2).join("/")
              : t("plan_approval_codex_plan")}
          </button>
          <CopyButton
            variant="bare"
            className={styles.copyBtn}
            source={fetchPlanContent}
            tooltip={{
              copy: t("plan_approval_copy"),
              copied: t("plan_approval_copied"),
            }}
            disabled={loading}
            onError={(e) => {
              console.error("Failed to copy plan:", e);
              setLoadError(t("plan_approval_failed_read"));
            }}
          />
        </div>
      )}

      {expanded && visiblePlanContent !== null && (
        <div className={styles.planContent}>
          <MessageMarkdown
            content={visiblePlanContent}
            onOpenFile={openFile}
            resolveFilePath={resolveFilePath}
          />
        </div>
      )}

      {expanded && visiblePlanContent === null && loadError && (
        <div className={styles.planContent}>{loadError}</div>
      )}

      {approval.allowedPrompts.length > 0 && (
        <div className={styles.permissions}>
          <div className={styles.permLabel}>{t("plan_approval_requested_permissions")}</div>
          <div className={styles.permList}>
            {approval.allowedPrompts.map((p, i) => (
              <div key={i} className={styles.permItem}>
                <span className={styles.permTool}>{p.tool}</span>
                <span>{p.prompt}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      <button
        className={styles.approveBtn}
        onClick={() => onRespond(true)}
      >
        {t("plan_approval_approve")}
      </button>

      <div className={styles.divider}>{t("plan_approval_or_feedback")}</div>

      <div className={styles.freeformRow}>
        <textarea
          className={styles.freeformInput}
          value={feedback}
          onChange={(e) => setFeedback(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter" && !e.shiftKey) {
              e.preventDefault();
              const text = feedback.trim();
              if (text) onRespond(false, text);
            }
          }}
          placeholder={t("plan_approval_feedback_placeholder")}
          rows={1}
        />
        <button
          className={styles.feedbackBtn}
          onClick={() => {
            const text = feedback.trim();
            if (text) onRespond(false, text);
          }}
          disabled={!feedback.trim()}
        >
          {t("plan_approval_send")}
        </button>
      </div>
    </div>
  );
}
