import { useState, useCallback } from "react";
import { exportTaskPatch, pushTaskBranch, createTaskPR, commitWorktree, type ExportPatchResponse } from "../../lib/api";

interface GitActionsPanelProps {
  taskId: string;
  isLocalOnly: boolean;
  taskStatus: string;
}

interface ToastMessage {
  type: "success" | "error" | "info";
  message: string;
}

export function GitActionsPanel({
  taskId,
  isLocalOnly,
  taskStatus,
}: GitActionsPanelProps) {
  const [isExporting, setIsExporting] = useState(false);
  const [isPushing, setIsPushing] = useState(false);
  const [isCreatingPR, setIsCreatingPR] = useState(false);
  const [isCommitting, setIsCommitting] = useState(false);
  const [commitMessage, setCommitMessage] = useState("");
  const [toast, setToast] = useState<ToastMessage | null>(null);
  const [exportedPatch, setExportedPatch] = useState<ExportPatchResponse | null>(null);

  // Only show for completed tasks
  if (taskStatus !== "done") return null;

  const showToast = (type: ToastMessage["type"], message: string) => {
    setToast({ type, message });
    setTimeout(() => setToast(null), 5000);
  };

  const handleExportPatch = useCallback(async () => {
    setIsExporting(true);
    try {
      const result = await exportTaskPatch(taskId);
      setExportedPatch(result);
      showToast("success", `Patch generated: ${result.fileName}`);
    } catch (e) {
      showToast("error", e instanceof Error ? e.message : "Failed to generate patch");
    } finally {
      setIsExporting(false);
    }
  }, [taskId]);

  const handlePushBranch = useCallback(async () => {
    if (isLocalOnly) {
      showToast("error", "Push disabled in local-only mode");
      return;
    }
    setIsPushing(true);
    try {
      const result = await pushTaskBranch(taskId);
      showToast("success", `Branch pushed: ${result.branchName}`);
    } catch (e) {
      showToast("error", e instanceof Error ? e.message : "Failed to push branch");
    } finally {
      setIsPushing(false);
    }
  }, [taskId, isLocalOnly]);

  const handleCreatePR = useCallback(async () => {
    if (isLocalOnly) {
      showToast("error", "PR creation disabled in local-only mode");
      return;
    }
    setIsCreatingPR(true);
    try {
      const result = await createTaskPR(taskId);
      if (result.prUrl) {
        showToast("success", `PR created: ${result.prUrl}`);
        // Open PR in new tab
        window.open(result.prUrl, "_blank", "noopener,noreferrer");
      } else {
        showToast("success", "PR creation initiated");
      }
    } catch (e) {
      showToast("error", e instanceof Error ? e.message : "Failed to create PR");
    } finally {
      setIsCreatingPR(false);
    }
  }, [taskId, isLocalOnly]);

  const handleCommit = useCallback(async () => {
    setIsCommitting(true);
    try {
      const result = await commitWorktree(taskId, commitMessage || undefined);
      if (result.success) {
        showToast("success", `Committed: ${result.commitSha?.substring(0, 8) || "done"}`);
        setCommitMessage("");
      } else {
        showToast("error", result.error || "Failed to commit");
      }
    } catch (e) {
      showToast("error", e instanceof Error ? e.message : "Failed to commit");
    } finally {
      setIsCommitting(false);
    }
  }, [taskId, commitMessage]);

  return (
    <div className="space-y-3">
      {/* Section Header */}
      <div className="font-mono text-xs text-[#9bc3ff] tracking-wide uppercase">
        Git Actions
      </div>

      {/* Local-only mode alert */}
      {isLocalOnly && (
        <div className="bg-yellow-400/10 border border-yellow-400/30 px-3 py-2 font-mono text-xs text-yellow-400 flex items-center gap-2">
          <span className="w-1.5 h-1.5 bg-yellow-400 rounded-full" />
          Contract is in local-only mode. Push/PR actions disabled.
        </div>
      )}

      {/* Toast notification */}
      {toast && (
        <div
          className={`px-3 py-2 font-mono text-xs border ${
            toast.type === "success"
              ? "bg-green-400/10 border-green-400/30 text-green-400"
              : toast.type === "error"
              ? "bg-red-400/10 border-red-400/30 text-red-400"
              : "bg-blue-400/10 border-blue-400/30 text-blue-400"
          }`}
        >
          {toast.message}
        </div>
      )}

      {/* Commit section */}
      <div className="flex gap-2">
        <input
          type="text"
          value={commitMessage}
          onChange={(e) => setCommitMessage(e.target.value)}
          placeholder="Commit message (optional)"
          className="flex-1 px-2 py-1.5 font-mono text-xs bg-transparent border border-[rgba(117,170,252,0.2)] text-[#dbe7ff] placeholder:text-[#555] focus:border-[#75aafc] focus:outline-none"
          onKeyDown={(e) => { if (e.key === "Enter") handleCommit(); }}
        />
        <button
          onClick={handleCommit}
          disabled={isCommitting}
          className="px-3 py-1.5 font-mono text-xs text-emerald-400 border border-emerald-400/30 hover:border-emerald-400/50 hover:bg-emerald-400/10 transition-colors disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap"
        >
          {isCommitting ? "Committing..." : "Commit"}
        </button>
      </div>

      {/* Action buttons */}
      <div className="flex flex-wrap gap-2">
        <button
          onClick={handleExportPatch}
          disabled={isExporting}
          className="px-3 py-1.5 font-mono text-xs text-[#75aafc] border border-[rgba(117,170,252,0.25)] hover:border-[#3f6fb3] hover:bg-[rgba(117,170,252,0.05)] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
        >
          {isExporting ? "Generating..." : "Generate Patch"}
        </button>

        <button
          onClick={handlePushBranch}
          disabled={isPushing || isLocalOnly}
          className={`px-3 py-1.5 font-mono text-xs border transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${
            isLocalOnly
              ? "text-[#555] border-[rgba(117,170,252,0.15)] cursor-not-allowed"
              : "text-cyan-400 border-cyan-400/30 hover:border-cyan-400/50 hover:bg-cyan-400/10"
          }`}
          title={isLocalOnly ? "Disabled in local-only mode" : "Push changes to remote branch"}
        >
          {isPushing ? "Pushing..." : "Push Remote Branch"}
        </button>

        <button
          onClick={handleCreatePR}
          disabled={isCreatingPR || isLocalOnly}
          className={`px-3 py-1.5 font-mono text-xs border transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${
            isLocalOnly
              ? "text-[#555] border-[rgba(117,170,252,0.15)] cursor-not-allowed"
              : "text-green-400 border-green-400/30 hover:border-green-400/50 hover:bg-green-400/10"
          }`}
          title={isLocalOnly ? "Disabled in local-only mode" : "Create pull request"}
        >
          {isCreatingPR ? "Creating PR..." : "Create PR"}
        </button>
      </div>

      {/* Export result info */}
      {exportedPatch && (
        <div className="bg-[rgba(0,0,0,0.2)] border border-[rgba(117,170,252,0.15)] p-3 space-y-2">
          <div className="font-mono text-xs text-[#555]">Exported Patch</div>
          <div className="font-mono text-xs text-[#75aafc] break-all">
            <span className="text-[#555]">File:</span> {exportedPatch.fileName}
          </div>
          {exportedPatch.filePath && (
            <div className="font-mono text-xs text-[#75aafc] break-all">
              <span className="text-[#555]">Path:</span> {exportedPatch.filePath}
            </div>
          )}
          {exportedPatch.patchSize && (
            <div className="font-mono text-xs text-[#75aafc]">
              <span className="text-[#555]">Size:</span> {formatBytes(exportedPatch.patchSize)}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function formatBytes(bytes: number): string {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}
