import { useEffect, useMemo, useRef, useState } from "react";
import {
  ThumbsUp,
  ThumbsDown,
  CheckCircle2,
  MessageSquare,
  Loader2,
  Heart,
  AlertCircle,
} from "lucide-react";
import {
  submitKbFeedback,
  fetchKbFeedbackStats,
  feedbackStorageKey,
  type FeedbackRating,
  type KbFeedbackStats,
} from "@/lib/kbFeedback";

interface FeedbackWidgetProps {
  /** Stable article id (e.g. "clients-portal-overview"). */
  articleId: string;
  /** Parent category id, stored alongside for easier reporting. */
  categoryId?: string;
  /** Human-readable article title — used only inside the UI. */
  articleTitle?: string;
}

type Phase = "initial" | "commenting" | "submitting" | "done" | "error";

/**
 * "Was this article helpful?" widget.
 *
 * Flow:
 *   1. User clicks 👍 or 👎 — the rating is persisted immediately so we
 *      capture a signal even if they don't leave a comment.
 *   2. A follow-up form appears inline asking for an optional comment
 *      (and email, for 👎 only — useful for follow-up).
 *   3. On submit (or skip), we show a thank-you state and remember in
 *      localStorage that this browser has voted on this article.
 *
 * Aggregate counts are fetched on mount so visitors can see social
 * proof ("125 people found this helpful").
 */
export default function FeedbackWidget({
  articleId,
  categoryId,
  articleTitle,
}: FeedbackWidgetProps) {
  const [rating, setRating] = useState<FeedbackRating | null>(null);
  const [phase, setPhase] = useState<Phase>("initial");
  const [comment, setComment] = useState("");
  const [email, setEmail] = useState("");
  const [stats, setStats] = useState<KbFeedbackStats>({
    up: 0,
    down: 0,
    total: 0,
  });
  const [hasVoted, setHasVoted] = useState(false);
  const initialRatingIdRef = useRef<number | null>(null);

  // Reset everything when switching to a different article.
  useEffect(() => {
    setRating(null);
    setPhase("initial");
    setComment("");
    setEmail("");
    initialRatingIdRef.current = null;

    // Check if this browser has already voted on this article.
    try {
      const stored = window.localStorage.getItem(feedbackStorageKey(articleId));
      if (stored) {
        const parsed = JSON.parse(stored) as { rating?: FeedbackRating };
        if (parsed?.rating === "up" || parsed?.rating === "down") {
          setRating(parsed.rating);
          setHasVoted(true);
          setPhase("done");
        }
      } else {
        setHasVoted(false);
      }
    } catch {
      setHasVoted(false);
    }

    // Fetch aggregate stats so the widget feels alive.
    let cancelled = false;
    fetchKbFeedbackStats(articleId).then((s) => {
      if (!cancelled) setStats(s);
    });
    return () => {
      cancelled = true;
    };
  }, [articleId]);

  const helpfulRate = useMemo(() => {
    if (stats.total === 0) return null;
    return Math.round((stats.up / stats.total) * 100);
  }, [stats]);

  /**
   * Captures the initial thumbs-up / down click. Persists immediately
   * so we never lose a rating even if the user abandons the comment.
   */
  async function handleRate(next: FeedbackRating) {
    if (hasVoted || phase === "submitting") return;
    setRating(next);
    setPhase("submitting");
    const res = await submitKbFeedback({
      article_id: articleId,
      category_id: categoryId,
      rating: next,
      page_url: typeof window !== "undefined" ? window.location.href : undefined,
      user_agent:
        typeof navigator !== "undefined" ? navigator.userAgent : undefined,
    });
    if (res) {
      initialRatingIdRef.current = res.id;
      // Optimistic count update so the user sees immediate feedback.
      setStats((s) => ({
        up: s.up + (next === "up" ? 1 : 0),
        down: s.down + (next === "down" ? 1 : 0),
        total: s.total + 1,
      }));
      setPhase("commenting");
    } else {
      // Rating couldn't be persisted — show an inline error but still
      // allow the user to leave a comment; we'll retry on submit.
      setPhase("error");
    }
  }

  /**
   * Submits the optional comment. This creates a SECOND row tied to
   * the same article — the rollup query aggregates by article_id so
   * this is fine and keeps the schema simple. Skipping the comment
   * just finalizes the widget.
   */
  async function handleSubmitComment(withComment: boolean) {
    if (!rating) return;
    if (withComment && !comment.trim()) {
      // Treat empty-comment submit as a skip.
      withComment = false;
    }

    if (withComment) {
      setPhase("submitting");
      await submitKbFeedback({
        article_id: articleId,
        category_id: categoryId,
        rating,
        comment: comment.trim(),
        user_email: email.trim() || undefined,
        page_url:
          typeof window !== "undefined" ? window.location.href : undefined,
      });
    }

    // Remember this browser voted so the widget stays finalized.
    try {
      window.localStorage.setItem(
        feedbackStorageKey(articleId),
        JSON.stringify({ rating, at: Date.now() }),
      );
    } catch {
      /* storage disabled — ignore */
    }

    setHasVoted(true);
    setPhase("done");
  }

  async function handleRetry() {
    if (!rating) return;
    setPhase("submitting");
    const res = await submitKbFeedback({
      article_id: articleId,
      category_id: categoryId,
      rating,
    });
    if (res) {
      initialRatingIdRef.current = res.id;
      setStats((s) => ({
        up: s.up + (rating === "up" ? 1 : 0),
        down: s.down + (rating === "down" ? 1 : 0),
        total: s.total + 1,
      }));
      setPhase("commenting");
    } else {
      setPhase("error");
    }
  }

  // --------------------------------------------------------------------
  // Render
  // --------------------------------------------------------------------

  return (
    <div className="mt-10 rounded-2xl border border-slate-200 bg-gradient-to-br from-white via-emerald-50/40 to-white p-6 md:p-7 shadow-sm">
      <div className="flex items-start gap-3">
        <div className="w-10 h-10 rounded-xl bg-[#0e6305] text-white flex items-center justify-center shrink-0">
          <Heart className="w-5 h-5" />
        </div>
        <div className="min-w-0 flex-1">
          <div className="flex flex-wrap items-start justify-between gap-3">
            <div>
              <h4 className="text-lg font-bold text-slate-900">
                Was this article helpful?
              </h4>
              <p className="text-sm text-slate-600 mt-0.5">
                {articleTitle
                  ? `Your feedback on “${articleTitle}” helps us improve.`
                  : "Your feedback helps us keep this knowledge base useful."}
              </p>
            </div>
            {stats.total > 0 && (
              <div className="text-xs text-slate-500 font-medium bg-white border border-slate-200 rounded-full px-3 py-1">
                {helpfulRate !== null ? (
                  <>
                    <span className="text-[#0e6305] font-bold">
                      {helpfulRate}%
                    </span>{" "}
                    of {stats.total} people found this helpful
                  </>
                ) : (
                  <>{stats.total} votes</>
                )}
              </div>
            )}
          </div>

          {/* --- Phase: initial vote buttons --- */}
          {phase === "initial" && !hasVoted && (
            <div className="mt-5 flex flex-wrap items-center gap-3">
              <button
                type="button"
                onClick={() => handleRate("up")}
                className="group inline-flex items-center gap-2 px-5 py-2.5 rounded-lg border-2 border-emerald-500 text-emerald-700 bg-white hover:bg-emerald-500 hover:text-white font-bold text-sm transition shadow-sm"
                aria-label="Yes, this article was helpful"
              >
                <ThumbsUp className="w-4 h-4 transition group-hover:scale-110" />
                Yes, it helped
                {stats.up > 0 && (
                  <span className="ml-1 text-xs bg-emerald-100 text-emerald-800 group-hover:bg-white/20 group-hover:text-white px-2 py-0.5 rounded-full font-semibold">
                    {stats.up}
                  </span>
                )}
              </button>
              <button
                type="button"
                onClick={() => handleRate("down")}
                className="group inline-flex items-center gap-2 px-5 py-2.5 rounded-lg border-2 border-rose-400 text-rose-700 bg-white hover:bg-rose-500 hover:text-white font-bold text-sm transition shadow-sm"
                aria-label="No, this article was not helpful"
              >
                <ThumbsDown className="w-4 h-4 transition group-hover:scale-110" />
                Not really
                {stats.down > 0 && (
                  <span className="ml-1 text-xs bg-rose-100 text-rose-800 group-hover:bg-white/20 group-hover:text-white px-2 py-0.5 rounded-full font-semibold">
                    {stats.down}
                  </span>
                )}
              </button>
            </div>
          )}

          {/* --- Phase: submitting initial vote --- */}
          {phase === "submitting" && rating && (
            <div className="mt-5 inline-flex items-center gap-2 text-sm text-slate-600">
              <Loader2 className="w-4 h-4 animate-spin text-[#0e6305]" />
              Saving your feedback…
            </div>
          )}

          {/* --- Phase: error saving initial vote --- */}
          {phase === "error" && (
            <div className="mt-5 rounded-lg border border-rose-200 bg-rose-50 p-4 flex items-start gap-3">
              <AlertCircle className="w-5 h-5 text-rose-600 shrink-0 mt-0.5" />
              <div className="flex-1 min-w-0">
                <p className="text-sm font-semibold text-rose-900">
                  We couldn&apos;t save your vote.
                </p>
                <p className="text-xs text-rose-800 mt-0.5">
                  Please check your connection and try again.
                </p>
                <button
                  type="button"
                  onClick={handleRetry}
                  className="mt-3 inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-rose-600 text-white text-xs font-bold hover:bg-rose-700 transition"
                >
                  Try again
                </button>
              </div>
            </div>
          )}

          {/* --- Phase: collect optional comment --- */}
          {phase === "commenting" && rating && (
            <div className="mt-5 rounded-xl bg-white border border-slate-200 p-4 md:p-5">
              <div className="flex items-center gap-2 mb-3">
                {rating === "up" ? (
                  <ThumbsUp className="w-4 h-4 text-emerald-600" />
                ) : (
                  <ThumbsDown className="w-4 h-4 text-rose-600" />
                )}
                <p className="text-sm font-semibold text-slate-900">
                  {rating === "up"
                    ? "Awesome — what did you like most?"
                    : "Sorry about that. What were you trying to do?"}
                </p>
                <span className="ml-auto text-[10px] uppercase tracking-wider font-bold text-slate-400">
                  Optional
                </span>
              </div>

              <label className="sr-only" htmlFor="kb-feedback-comment">
                Your feedback
              </label>
              <textarea
                id="kb-feedback-comment"
                value={comment}
                onChange={(e) => setComment(e.target.value.slice(0, 2000))}
                rows={3}
                placeholder={
                  rating === "up"
                    ? "e.g. The step-by-step instructions were very clear."
                    : "e.g. I couldn't find information about X, or the steps didn't work for me."
                }
                className="w-full rounded-lg border border-slate-300 focus:border-[#0e6305] focus:ring-2 focus:ring-emerald-200 outline-none p-3 text-sm resize-y placeholder:text-slate-400"
              />
              <div className="text-right text-[11px] text-slate-400 mt-1">
                {comment.length}/2000
              </div>

              {rating === "down" && (
                <div className="mt-2">
                  <label
                    className="block text-xs font-semibold text-slate-600 mb-1"
                    htmlFor="kb-feedback-email"
                  >
                    Email (optional — if you&apos;d like us to follow up)
                  </label>
                  <input
                    id="kb-feedback-email"
                    type="email"
                    value={email}
                    onChange={(e) => setEmail(e.target.value.slice(0, 255))}
                    placeholder="you@example.com"
                    className="w-full rounded-lg border border-slate-300 focus:border-[#0e6305] focus:ring-2 focus:ring-emerald-200 outline-none px-3 py-2 text-sm placeholder:text-slate-400"
                  />
                </div>
              )}

              <div className="mt-4 flex flex-wrap items-center gap-2">
                <button
                  type="button"
                  onClick={() => handleSubmitComment(true)}
                  disabled={!comment.trim()}
                  className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-[#0e6305] text-white text-sm font-bold hover:bg-[#0a4a04] transition disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <MessageSquare className="w-4 h-4" />
                  Send feedback
                </button>
                <button
                  type="button"
                  onClick={() => handleSubmitComment(false)}
                  className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-white border border-slate-300 text-slate-700 text-sm font-semibold hover:bg-slate-50 transition"
                >
                  Skip
                </button>
                <span className="text-xs text-slate-500 ml-auto">
                  Your rating was already saved — this is just extra detail.
                </span>
              </div>
            </div>
          )}

          {/* --- Phase: done --- */}
          {phase === "done" && rating && (
            <div className="mt-5 rounded-xl bg-emerald-50 border border-emerald-200 p-4 flex items-start gap-3">
              <CheckCircle2 className="w-5 h-5 text-emerald-600 shrink-0 mt-0.5" />
              <div className="flex-1 min-w-0">
                <p className="text-sm font-bold text-emerald-900">
                  {rating === "up"
                    ? "Thanks for the thumbs up! 🎉"
                    : "Thanks — we'll use this to improve the article."}
                </p>
                <p className="text-xs text-emerald-800 mt-0.5">
                  {rating === "up"
                    ? "Glad this article helped. Share it with a teammate if it saved you time."
                    : "Your feedback is recorded. Our docs team reviews low-rated articles weekly."}
                </p>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}