/**
 * AiDescriptionCompare
 *
 * Shared side-by-side description editor for AI validation results.
 * Shows the current description next to the AI-suggested version,
 * both editable, with issues list and accept/dismiss actions.
 *
 * Layout uses a ResizeObserver to measure the right-side header+issues
 * area and mirrors that height as a spacer on the left so both
 * textareas start at the same vertical position. Textareas auto-resize
 * to fit their content; the parent container controls overflow.
 *
 * Used by:
 * - MultilineInput (inside a Popover, in the import validation table)
 * - ProductEditForm (inside a Dialog, in the product editor)
 */

import { useState, useEffect, useRef, useCallback } from "react";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Sparkles, AlertCircle, Check, RefreshCw } from "lucide-react";
import { cn } from "@/lib/utils";

export interface AiDescriptionCompareProps {
  currentValue: string;
  onCurrentChange: (value: string) => void;
  suggestion: string;
  issues: string[];
  onAccept: (editedSuggestion: string) => void;
  onDismiss: () => void;
  /** Called to re-roll (re-run) the AI validation */
  onRevalidate?: () => void;
  /** Whether re-validation is in progress */
  isRevalidating?: boolean;
  productName?: string;
  className?: string;
}

export function AiDescriptionCompare({
  currentValue,
  onCurrentChange,
  suggestion,
  issues,
  onAccept,
  onDismiss,
  onRevalidate,
  isRevalidating = false,
  productName,
  className,
}: AiDescriptionCompareProps) {
  const [editedSuggestion, setEditedSuggestion] = useState(suggestion);
  const [aiHeaderHeight, setAiHeaderHeight] = useState(0);
  const aiHeaderRef = useRef<HTMLDivElement>(null);
  const mainTextareaRef = useRef<HTMLTextAreaElement>(null);
  const suggestionTextareaRef = useRef<HTMLTextAreaElement>(null);

  // Reset edited suggestion when the suggestion prop changes
  useEffect(() => {
    setEditedSuggestion(suggestion);
  }, [suggestion]);

  // Measure right-side header+issues area for left-side spacer alignment.
  // Wrapped in rAF because Radix portals mount asynchronously — the ref
  // is null on the first synchronous run.
  useEffect(() => {
    let observer: ResizeObserver | null = null;
    const rafId = requestAnimationFrame(() => {
      const el = aiHeaderRef.current;
      if (!el) return;
      observer = new ResizeObserver(([entry]) => {
        // Subtract 8px to compensate for the left column's py-2 top padding,
        // so both "Current Description" and "Suggested" labels align vertically.
        setAiHeaderHeight(Math.max(0, entry.contentRect.height - 8));
      });
      observer.observe(el);
    });
    return () => {
      cancelAnimationFrame(rafId);
      observer?.disconnect();
    };
  }, []);

  // Auto-resize both textareas to fit content, then equalize their heights
  // on desktop so tops and bottoms align exactly.
  const syncTextareaHeights = useCallback(() => {
    const main = mainTextareaRef.current;
    const suggestion = suggestionTextareaRef.current;
    if (!main && !suggestion) return;

    // Reset to auto to measure natural content height
    if (main) main.style.height = "auto";
    if (suggestion) suggestion.style.height = "auto";

    const mainH = main?.scrollHeight ?? 0;
    const suggestionH = suggestion?.scrollHeight ?? 0;

    // On desktop (lg), equalize so both textareas are the same height
    const isDesktop = window.matchMedia("(min-width: 1024px)").matches;
    const targetH = isDesktop ? Math.max(mainH, suggestionH) : 0;

    if (main) main.style.height = `${targetH || mainH}px`;
    if (suggestion) suggestion.style.height = `${targetH || suggestionH}px`;
  }, []);

  // Sync heights on mount and when content changes.
  // Retry after a short delay to handle dialog/popover entry animations
  // where the DOM isn't fully laid out on the first frame.
  useEffect(() => {
    requestAnimationFrame(syncTextareaHeights);
    const timer = setTimeout(syncTextareaHeights, 200);
    return () => clearTimeout(timer);
  }, [currentValue, editedSuggestion, syncTextareaHeights]);

  return (
    <div className={cn("flex flex-col lg:flex-row items-stretch w-full", className)}>
      {/* Left: current description */}
      <div className="flex flex-col min-h-0 w-full lg:w-1/2">
        <div className="px-3 py-2 bg-accent flex flex-col flex-1 min-h-0">
          {/* Product name - shown inline on mobile */}
          {productName && (
            <div className="flex-shrink-0 flex flex-col lg:hidden px-1 mb-2">
              <div className="text-sm font-medium text-foreground mb-1">
                Editing description for:
              </div>
              <div className="text-md font-semibold text-foreground">
                {productName}
              </div>
            </div>
          )}
          {/* Desktop spacer matching the right-side header+issues height */}
          {aiHeaderHeight > 0 && (
            <div
              className="flex-shrink-0 hidden lg:flex items-start"
              style={{ height: aiHeaderHeight }}
            >
              {productName && (
                <div className="flex flex-col">
                  <div className="text-sm font-medium text-foreground px-1 mb-1">
                    Editing description for:
                  </div>
                  <div className="text-md font-semibold text-foreground px-1">
                    {productName}
                  </div>
                </div>
              )}
            </div>
          )}
          <div className="text-sm mb-1 font-medium flex items-center gap-2 flex-shrink-0">
            Current Description:
          </div>
          <Textarea
            ref={mainTextareaRef}
            value={currentValue}
            onChange={(e) => {
              onCurrentChange(e.target.value);
              syncTextareaHeights();
            }}
            className="overflow-y-auto overscroll-contain text-sm resize-y bg-white min-h-[120px] max-h-[50vh]"
          />
          {/* Footer spacer matching the action buttons height on the right */}
          <div className="h-[43px] flex-shrink-0 hidden lg:block" />
        </div>
      </div>

      {/* Right: AI suggestion */}
      <div className="bg-purple-50/80 dark:bg-purple-950/30 flex flex-col w-full lg:w-1/2">
        {/* Measured header + issues area (height mirrored as spacer on the left) */}
        <div ref={aiHeaderRef} className="flex-shrink-0">
          {/* Header */}
          <div className="w-full flex items-center justify-between px-3 py-2">
            <div className="flex items-center gap-2">
              <Sparkles className="h-3.5 w-3.5 text-purple-500" />
              <span className="text-xs font-medium text-purple-600 dark:text-purple-400">
                AI Suggestion
              </span>
              <span className="text-xs text-purple-500 dark:text-purple-400">
                ({issues.length} {issues.length === 1 ? "issue" : "issues"})
              </span>
            </div>
          </div>

          {/* Issues list */}
          {issues.length > 0 && (
            <div className="flex flex-col gap-1 px-3 pb-3">
              {issues.map((issue, index) => (
                <div
                  key={index}
                  className="flex items-start gap-1.5 text-xs text-purple-600 dark:text-purple-400"
                >
                  <AlertCircle className="h-3 w-3 mt-0.5 flex-shrink-0 text-purple-400" />
                  <span>{issue}</span>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Content */}
        <div className="px-3 pb-3 flex flex-col flex-1 gap-3">
          {/* Editable suggestion */}
          <div className="flex flex-col flex-1">
            <div className="text-sm text-purple-500 dark:text-purple-400 mb-1 font-medium flex-shrink-0">
              Suggested (editable):
            </div>
            <Textarea
              ref={suggestionTextareaRef}
              value={editedSuggestion}
              onChange={(e) => {
                setEditedSuggestion(e.target.value);
                syncTextareaHeights();
              }}
              className="overflow-y-auto overscroll-contain text-sm bg-white dark:bg-black/20 border-purple-200 dark:border-purple-700 focus-visible:ring-purple-400 resize-y min-h-[120px] max-h-[50vh]"
            />
          </div>

          {/* Actions */}
          <div className="flex items-center gap-2 flex-shrink-0">
            <Button
              size="sm"
              variant="outline"
              className="h-7 px-3 text-xs bg-white border-green-300 text-green-700 hover:bg-green-50 hover:border-green-400 dark:bg-green-950/30 dark:border-green-700 dark:text-green-400"
              onClick={() => onAccept(editedSuggestion)}
            >
              <Check className="h-3 w-3 mr-1" />
              Replace With Suggestion
            </Button>
            <Button
              size="sm"
              variant="ghost"
              className="h-7 px-3 text-xs text-gray-500 hover:text-gray-700 dark:text-gray-400"
              onClick={onDismiss}
            >
              Ignore
            </Button>
            {onRevalidate && (
              <Button
                size="sm"
                variant="ghost"
                className="h-7 px-3 text-xs text-purple-500 hover:text-purple-700 dark:text-purple-400"
                disabled={isRevalidating}
                onClick={onRevalidate}
              >
                <RefreshCw className={`h-3 w-3 mr-1 ${isRevalidating ? "animate-spin" : ""}`} />
                Refresh
              </Button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}
