"use client";

import { createPortal } from "react-dom";

import { useState } from "react";
import { X, Star, Loader2, PartyPopper } from "lucide-react";
import { Avatar } from "./Avatar";
import { sfx } from "@/lib/sfx";
import { firework } from "@/lib/particles";
import type { User } from "@/lib/types";
import clsx from "clsx";

const WORDS = ["", "Poor", "Fair", "Good", "Great", "Excellent"];

/** Rate a seller once. Feedback is final, so the copy says so up front. */
export function LeaveFeedbackModal({
  seller,
  onClose,
  onDone,
}: {
  seller: User;
  onClose: () => void;
  onDone: () => void;
}) {
  const [rating, setRating] = useState(0);
  const [hover, setHover] = useState(0);
  const [text, setText] = useState("");
  const [saving, setSaving] = useState(false);
  const [done, setDone] = useState(false);
  const [error, setError] = useState<string | null>(null);

  async function send(el: HTMLElement) {
    setSaving(true);
    setError(null);
    const res = await fetch(`/api/marketplace/seller/${seller.username}/reviews`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ rating, text }),
    }).catch(() => null);
    setSaving(false);

    if (!res || !res.ok) {
      const msg = res ? (await res.json().catch(() => null))?.error : null;
      setError(msg ?? "Couldn't send your feedback — please try again.");
      return;
    }

    firework(el, ["#fbbf24", "#e11d48", "#10b981", "#ffffff"]);
    sfx.fanfare();
    setDone(true);
    setTimeout(onDone, 1900);
  }

  const shown = hover || rating;

  return createPortal(
    <div className="nm-back" onClick={saving ? undefined : onClose}>
      <div className="fb-card" onClick={(e) => e.stopPropagation()}>
        {done ? (
          <div className="fb-done">
            <span className="fb-done-icon">
              <PartyPopper size={34} />
            </span>
            <b>Thank you!</b>
            <span>
              Your feedback for {seller.name.split(" ")[0]} is live — it helps the next
              buyer decide.
            </span>
          </div>
        ) : (
          <>
            <button onClick={onClose} className="fb-x">
              <X size={18} />
            </button>

            <div className="fb-head">
              <Avatar user={seller} size={64} />
              <b>How was your experience?</b>
              <span>Rate {seller.name} — feedback can&apos;t be changed later.</span>
            </div>

            <div className="fb-stars" onMouseLeave={() => setHover(0)}>
              {[1, 2, 3, 4, 5].map((n) => (
                <button
                  key={n}
                  onMouseEnter={() => setHover(n)}
                  onClick={() => {
                    setRating(n);
                    sfx.click();
                  }}
                  className={clsx("fb-star", n <= shown && "on")}
                >
                  <Star size={34} className={n <= shown ? "fill-current" : ""} />
                </button>
              ))}
            </div>
            <p className={clsx("fb-word", shown && "show")}>{WORDS[shown] || "\u00A0"}</p>

            <textarea
              value={text}
              onChange={(e) => setText(e.target.value.slice(0, 500))}
              rows={4}
              placeholder="What went well? Anything the next buyer should know?"
              className="fb-text"
            />

            {error && <p className="cl-error">{error}</p>}

            <button
              disabled={!rating || saving}
              onClick={(e) => send(e.currentTarget)}
              className={clsx("fb-send", (!rating || saving) && "off")}
            >
              {saving ? (
                <span className="inline-flex items-center gap-2">
                  <Loader2 size={15} className="animate-spin" /> Sending…
                </span>
              ) : (
                "Post feedback"
              )}
            </button>
          </>
        )}
      </div>
    </div>,
    document.body
  );
}
