import { useState } from "react";
import { ChevronRight, ChevronDown, Copy } from "lucide-react";
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";

interface DiagramSourcePanelProps {
  mermaidSource: string;
  onRerender: (source: string) => void;
  className?: string;
}

export function DiagramSourcePanel({ mermaidSource, onRerender, className }: DiagramSourcePanelProps) {
  const [open, setOpen] = useState(false);
  const [editedSource, setEditedSource] = useState(mermaidSource);
  const [dirty, setDirty] = useState(false);

  function handleSourceChange(value: string) {
    setEditedSource(value);
    if (value !== mermaidSource) {
      setDirty(true);
    } else {
      setDirty(false);
    }
  }

  // eslint-disable-next-line @typescript-eslint/no-empty-function
  function handleBlur() {}

  function handleRerender() {
    onRerender(editedSource);
    setDirty(false);
  }

  function handleCopySource() {
    void navigator.clipboard.writeText(editedSource);
  }

  // Reset edited source when mermaidSource prop changes
  if (!dirty && editedSource !== mermaidSource) {
    setEditedSource(mermaidSource);
  }

  return (
    <Collapsible open={open} onOpenChange={setOpen} className={cn("w-full", className)}>
      <CollapsibleTrigger asChild>
        <button
          type="button"
          className="flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors py-1"
        >
          {open ? (
            <ChevronDown className="size-4" aria-hidden="true" />
          ) : (
            <ChevronRight className="size-4" aria-hidden="true" />
          )}
          {open ? "Hide source" : "View Mermaid source"}
        </button>
      </CollapsibleTrigger>
      <CollapsibleContent
        className={cn(
          "overflow-hidden",
          "data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up",
          "[&[data-state]]:transition-none [@media(prefers-reduced-motion:no-preference)&[data-state]]:transition-[height] [@media(prefers-reduced-motion:no-preference)&[data-state]]:duration-[250ms] [@media(prefers-reduced-motion:no-preference)&[data-state]]:ease-[ease]"
        )}
      >
        <div className="relative mt-2 rounded-md border border-border bg-secondary p-3">
          <div className="absolute right-2 top-2">
            <button
              type="button"
              aria-label="Copy source"
              title="Copy source"
              onClick={handleCopySource}
              className="inline-flex items-center justify-center size-7 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent transition-colors"
            >
              <Copy className="size-4" aria-hidden="true" />
            </button>
          </div>
          <Textarea
            value={editedSource}
            onChange={(e) => handleSourceChange(e.target.value)}
            onBlur={handleBlur}
            className="font-mono text-sm min-h-[120px] bg-transparent border-none shadow-none focus-visible:ring-0 resize-y pr-10"
            spellCheck={false}
          />
          {dirty && (
            <div className="flex justify-end mt-2">
              <Button
                type="button"
                variant="secondary"
                size="sm"
                onClick={handleRerender}
              >
                Re-render diagram
              </Button>
            </div>
          )}
        </div>
      </CollapsibleContent>
    </Collapsible>
  );
}
