import { useRef, useEffect, useState, useCallback } from "react";
import { SimpleMarkdown } from "../SimpleMarkdown";
import type { TaskOutputEvent } from "../../hooks/useTaskSubscription";
import { sendTaskMessage } from "../../lib/api";

interface TaskOutputProps {
  /** Array of parsed output events from the backend */
  entries: TaskOutputEvent[];
  isStreaming: boolean;
  /** Name of subtask whose output is being viewed (null = parent task) */
  viewingSubtaskName?: string | null;
  /** Callback to return to parent task output */
  onClearSubtaskView?: () => void;
  onClear?: () => void;
  /** Task ID for sending input (if provided, shows input bar when streaming) */
  taskId?: string | null;
  /** Callback when user sends input (to show it immediately in output) */
  onUserInput?: (message: string) => void;
}

export function TaskOutput({ entries, isStreaming, viewingSubtaskName, onClearSubtaskView, onClear, taskId, onUserInput }: TaskOutputProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [autoScroll, setAutoScroll] = useState(true);
  const [inputValue, setInputValue] = useState("");
  const [sendingInput, setSendingInput] = useState(false);
  const [inputError, setInputError] = useState<string | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  // Handle scroll to check if user has scrolled up
  const handleScroll = useCallback(() => {
    if (!containerRef.current) return;
    const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
    const isAtBottom = scrollHeight - scrollTop - clientHeight < 50;
    setAutoScroll(isAtBottom);
  }, []);

  // Auto-scroll when entries change
  useEffect(() => {
    if (autoScroll && containerRef.current) {
      containerRef.current.scrollTop = containerRef.current.scrollHeight;
    }
  }, [entries, autoScroll]);

  // Handle sending input to the task
  const handleSendInput = useCallback(async (e: React.FormEvent) => {
    e.preventDefault();
    if (!taskId || !inputValue.trim() || sendingInput) return;

    const message = inputValue.trim();
    setSendingInput(true);
    setInputError(null);

    // Show user input immediately in the output window
    onUserInput?.(message);

    try {
      await sendTaskMessage(taskId, message);
      setInputValue("");
      inputRef.current?.focus();
    } catch (err) {
      setInputError(err instanceof Error ? err.message : "Failed to send input");
    } finally {
      setSendingInput(false);
    }
  }, [taskId, inputValue, sendingInput, onUserInput]);

  // Show input bar when task is running and has a valid taskId
  const showInputBar = isStreaming && taskId;

  return (
    <div className="flex flex-col h-full">
      {/* Header */}
      <div className="flex items-center justify-between px-3 py-2 border-b border-dashed border-[rgba(117,170,252,0.35)] shrink-0">
        <div className="flex items-center gap-2">
          {viewingSubtaskName ? (
            <>
              <button
                onClick={onClearSubtaskView}
                className="font-mono text-xs text-[#75aafc] hover:text-[#9bc3ff] transition-colors"
              >
                &lt;
              </button>
              <span className="font-mono text-xs text-green-400 tracking-wide uppercase">
                Subtask: {viewingSubtaskName}
              </span>
            </>
          ) : (
            <span className="font-mono text-xs text-[#9bc3ff] tracking-wide uppercase">
              Output
            </span>
          )}
          {isStreaming && (
            <span className="flex items-center gap-1.5 px-2 py-0.5 bg-green-400/10 border border-green-400/30 text-green-400 font-mono text-[10px] uppercase">
              <span className="w-1.5 h-1.5 bg-green-400 rounded-full animate-pulse" />
              Live
            </span>
          )}
        </div>
        <div className="flex items-center gap-2">
          {!autoScroll && (
            <button
              onClick={() => {
                setAutoScroll(true);
                if (containerRef.current) {
                  containerRef.current.scrollTop =
                    containerRef.current.scrollHeight;
                }
              }}
              className="px-2 py-1 font-mono text-[10px] text-[#9bc3ff] border border-[rgba(117,170,252,0.25)] hover:border-[#3f6fb3] transition-colors uppercase"
            >
              Resume Scroll
            </button>
          )}
          {onClear && entries.length > 0 && (
            <button
              onClick={onClear}
              className="px-2 py-1 font-mono text-[10px] text-[#9bc3ff] border border-[rgba(117,170,252,0.25)] hover:border-[#3f6fb3] transition-colors uppercase"
            >
              Clear
            </button>
          )}
        </div>
      </div>

      {/* Output area */}
      <div
        ref={containerRef}
        onScroll={handleScroll}
        className="flex-1 overflow-auto bg-[#0a0f18] p-3 font-mono text-xs min-h-0"
      >
        {entries.length === 0 ? (
          <div className="text-[#555] italic">
            {isStreaming ? "Waiting for output..." : "No output yet"}
          </div>
        ) : (
          <div className="space-y-3">
            {entries.map((entry, idx) => (
              <OutputEntryRenderer key={idx} entry={entry} />
            ))}
            {isStreaming && (
              <span className="inline-block w-2 h-4 bg-[#9bc3ff] animate-pulse" />
            )}
          </div>
        )}
      </div>

      {/* Input bar for sending messages to running tasks */}
      {showInputBar && (
        <div className="shrink-0 border-t border-[rgba(117,170,252,0.35)] bg-[#0d1b2d]">
          {inputError && (
            <div className="px-3 py-1 bg-red-900/20 text-red-400 text-xs font-mono">
              {inputError}
            </div>
          )}
          <form onSubmit={handleSendInput} className="flex items-center gap-2 px-3 py-2">
            <span className="text-green-400 font-mono text-sm">&gt;</span>
            <input
              ref={inputRef}
              type="text"
              value={inputValue}
              onChange={(e) => setInputValue(e.target.value)}
              placeholder={sendingInput ? "Sending..." : "Send input to Claude..."}
              disabled={sendingInput}
              className="flex-1 bg-transparent border-none outline-none font-mono text-sm text-white placeholder-[#555]"
            />
            <button
              type="submit"
              disabled={sendingInput || !inputValue.trim()}
              className="px-3 py-1 font-mono text-xs text-green-400 border border-green-400/30 hover:border-green-400/50 hover:bg-green-400/10 disabled:opacity-50 disabled:cursor-not-allowed transition-colors uppercase"
            >
              {sendingInput ? "..." : "Send"}
            </button>
          </form>
        </div>
      )}
    </div>
  );
}

function OutputEntryRenderer({ entry }: { entry: TaskOutputEvent }) {
  const [expanded, setExpanded] = useState(false);

  switch (entry.messageType) {
    case "user_input":
      return (
        <div className="pl-2 border-l-2 border-cyan-400/50">
          <div className="flex items-center gap-2">
            <span className="text-cyan-400 text-[10px] uppercase tracking-wide">You:</span>
          </div>
          <div className="text-cyan-300 mt-1">{entry.content}</div>
        </div>
      );

    case "system":
      return (
        <div className="text-[#555] text-[10px] uppercase tracking-wide">
          {entry.content}
        </div>
      );

    case "assistant":
      return (
        <div className="pl-2 border-l-2 border-[#3f6fb3]">
          <SimpleMarkdown content={entry.content} className="text-[#9bc3ff]" />
        </div>
      );

    case "tool_use":
      return (
        <div className="space-y-1">
          <div className="flex items-center gap-2">
            <span className="text-yellow-500">*</span>
            <span className="text-[#75aafc]">{entry.toolName || "unknown"}</span>
            {entry.toolInput && Object.keys(entry.toolInput).length > 0 && (
              <button
                onClick={() => setExpanded(!expanded)}
                className="text-[#555] hover:text-[#9bc3ff] text-[10px]"
              >
                {expanded ? "[-]" : "[+]"}
              </button>
            )}
          </div>
          {expanded && entry.toolInput && (
            <pre className="ml-4 text-[10px] text-[#555] bg-[#0a1525] p-2 overflow-x-auto">
              {JSON.stringify(entry.toolInput, null, 2)}
            </pre>
          )}
        </div>
      );

    case "tool_result":
      if (!entry.content) return null;
      return (
        <div className="ml-4 text-[10px]">
          <span className={entry.isError ? "text-red-400" : "text-green-500"}>
            {entry.isError ? "x" : "+"}
          </span>{" "}
          <span className="text-[#555]">
            {entry.content.split("\n")[0]}
            {entry.content.includes("\n") && "..."}
          </span>
        </div>
      );

    case "result":
      return (
        <div className="border-t border-[rgba(117,170,252,0.2)] pt-2 mt-2">
          <div className="text-green-500 font-semibold mb-1">Result:</div>
          <SimpleMarkdown content={entry.content} className="text-[#9bc3ff]" />
          {(entry.costUsd !== undefined || entry.durationMs !== undefined) && (
            <div className="text-[10px] text-[#555] mt-2">
              {entry.durationMs !== undefined && (
                <span>Duration: {(entry.durationMs / 1000).toFixed(1)}s</span>
              )}
              {entry.costUsd !== undefined && entry.durationMs !== undefined && " | "}
              {entry.costUsd !== undefined && (
                <span>Cost: ${entry.costUsd.toFixed(4)}</span>
              )}
            </div>
          )}
        </div>
      );

    case "error":
      return (
        <div className="text-red-400 pl-2 border-l-2 border-red-400/50">
          {entry.content}
        </div>
      );

    case "raw":
      return (
        <div className="text-[#555] text-[10px]">
          {entry.content}
        </div>
      );

    case "auth_required":
      return <AuthRequiredEntry entry={entry} />;

    default:
      return null;
  }
}

function AuthRequiredEntry({ entry }: { entry: TaskOutputEvent }) {
  const [authCode, setAuthCode] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [submitted, setSubmitted] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const loginUrl = entry.toolInput?.loginUrl as string | undefined;
  const hostname = entry.toolInput?.hostname as string | undefined;
  // Get taskId from entry or fallback to toolInput (for robustness)
  const taskId = entry.taskId || (entry.toolInput?.taskId as string | undefined);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!authCode.trim() || !taskId) return;

    setSubmitting(true);
    setError(null);

    try {
      // Send the auth code to the task via the message endpoint
      await sendTaskMessage(taskId, `AUTH_CODE:${authCode.trim()}`);
      setSubmitted(true);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Failed to submit code");
    } finally {
      setSubmitting(false);
    }
  };

  if (submitted) {
    return (
      <div className="bg-green-900/30 border border-green-500/50 rounded p-3 my-2">
        <div className="flex items-center gap-2 text-green-400 font-semibold">
          <span>✓</span>
          <span>Authentication code submitted</span>
        </div>
        <p className="text-green-200/80 text-sm mt-1">
          Waiting for authentication to complete...
        </p>
      </div>
    );
  }

  return (
    <div className="bg-amber-900/30 border border-amber-500/50 rounded p-3 my-2">
      <div className="flex items-center gap-2 text-amber-400 font-semibold mb-2">
        <span>🔐</span>
        <span>Authentication Required{hostname ? ` (${hostname})` : ""}</span>
      </div>
      <p className="text-amber-200/80 text-sm mb-3">
        The daemon's OAuth token has expired. Click the button to login, then paste the code below:
      </p>

      <div className="flex flex-col gap-3">
        {loginUrl ? (
          <a
            href={loginUrl}
            target="_blank"
            rel="noopener noreferrer"
            className="inline-block bg-amber-500 hover:bg-amber-400 text-black font-medium px-4 py-2 rounded transition-colors text-center"
          >
            1. Login to Claude
          </a>
        ) : (
          <p className="text-red-400 text-sm">Login URL not available</p>
        )}

        <form onSubmit={handleSubmit} className="flex gap-2">
          <input
            type="text"
            value={authCode}
            onChange={(e) => setAuthCode(e.target.value)}
            placeholder="2. Paste authentication code here"
            className="flex-1 bg-[#0a1525] border border-amber-500/30 rounded px-3 py-2 text-amber-100 placeholder-amber-500/50 focus:outline-none focus:border-amber-400"
            disabled={submitting}
          />
          <button
            type="submit"
            disabled={submitting || !authCode.trim()}
            className="bg-amber-500 hover:bg-amber-400 disabled:bg-amber-700 disabled:cursor-not-allowed text-black font-medium px-4 py-2 rounded transition-colors"
          >
            {submitting ? "..." : "Submit"}
          </button>
        </form>

        {error && (
          <p className="text-red-400 text-sm">{error}</p>
        )}
      </div>
    </div>
  );
}
