import { useEffect, useState } from "react";
import { ThumbsDown, ThumbsUp } from "lucide-react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Textarea } from "@/components/ui/textarea";
import {
  useAIFeedbackSummary,
  useSubmitAIFeedback,
} from "@/hooks/queries/useAIFeedback";
import { cn } from "@/lib/utils";
import type {
  AIFeedbackRating,
  AIFeedbackSubjectType,
} from "@/types/ai-feedback";

export interface AIFeedbackButtonsProps {
  subjectType: AIFeedbackSubjectType;
  subjectId: number;
  promptKey?: string;
  promptVersion?: number;
  aiLogId?: number;
  entityId?: number;
  courseId?: number;
  size?: "sm" | "md";
  className?: string;
}

/** Thumbs up/down widget for any AI-generated artefact.
 *
 * Always renders the same UI regardless of whether the user has rated the
 * artefact before — a previous rating will show as highlighted. Clicking the
 * same button again is a no-op; clicking the opposite button updates the
 * server-side row in place. A thumbs-down always prompts the user for a short
 * comment (required by the backend).
 */
export function AIFeedbackButtons({
  subjectType,
  subjectId,
  promptKey,
  promptVersion,
  aiLogId,
  entityId,
  courseId,
  size = "sm",
  className,
}: AIFeedbackButtonsProps) {
  const summary = useAIFeedbackSummary(subjectType, subjectId);
  const submit = useSubmitAIFeedback();

  const [downOpen, setDownOpen] = useState(false);
  const [comment, setComment] = useState("");

  useEffect(() => {
    if (downOpen) {
      setComment(summary.data?.my_comment ?? "");
    }
  }, [downOpen, summary.data?.my_comment]);

  const myRating: AIFeedbackRating | null = summary.data?.my_rating ?? null;

  const submitUp = async () => {
    if (myRating === "up") return;
    try {
      await submit.mutateAsync({
        subject_type: subjectType,
        subject_id: subjectId,
        rating: "up",
        prompt_key: promptKey,
        prompt_version: promptVersion,
        ai_log_id: aiLogId,
        entity_id: entityId,
        course_id: courseId,
      });
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Failed to submit");
    }
  };

  const submitDown = async () => {
    if (!comment.trim()) {
      toast.error("Please tell us what was wrong.");
      return;
    }
    try {
      await submit.mutateAsync({
        subject_type: subjectType,
        subject_id: subjectId,
        rating: "down",
        comment: comment.trim(),
        prompt_key: promptKey,
        prompt_version: promptVersion,
        ai_log_id: aiLogId,
        entity_id: entityId,
        course_id: courseId,
      });
      setDownOpen(false);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Failed to submit");
    }
  };

  const btnSize = size === "sm" ? "sm" : "default";
  const iconCls = size === "sm" ? "h-3.5 w-3.5" : "h-4 w-4";

  return (
    <div className={cn("flex items-center gap-1", className)}>
      <Button
        variant={myRating === "up" ? "default" : "outline"}
        size={btnSize}
        onClick={submitUp}
        disabled={submit.isPending}
        aria-label="Thumbs up"
      >
        <ThumbsUp className={iconCls} />
        <span className="ml-1 text-xs">{summary.data?.up ?? 0}</span>
      </Button>
      <Button
        variant={myRating === "down" ? "default" : "outline"}
        size={btnSize}
        onClick={() => setDownOpen(true)}
        disabled={submit.isPending}
        aria-label="Thumbs down"
      >
        <ThumbsDown className={iconCls} />
        <span className="ml-1 text-xs">{summary.data?.down ?? 0}</span>
      </Button>

      <Dialog open={downOpen} onOpenChange={setDownOpen}>
        <DialogContent
          className="max-w-md"
          description="Tell us what was wrong so we can improve this AI output."
        >
          <DialogHeader>
            <DialogTitle>What went wrong?</DialogTitle>
          </DialogHeader>
          <Textarea
            value={comment}
            onChange={(e) => setComment(e.target.value)}
            rows={4}
            placeholder="e.g. Wrong answer, confusing wording, off-topic…"
          />
          <DialogFooter>
            <Button variant="outline" onClick={() => setDownOpen(false)}>
              Cancel
            </Button>
            <Button onClick={submitDown} disabled={submit.isPending}>
              Submit feedback
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

export default AIFeedbackButtons;
