"use client";

import { useState } from "react";
import type { Review } from "@/lib/mock-data";
import { clientExecute } from "@/lib/api/client";
import { ApiError } from "@/lib/api/shared";
import { Spinner } from "@/components/Loading";

const PER_PAGE = 5;

type SortOption = "recent" | "highest" | "lowest" | "helpful";

// ─── Star rating display ──────────────────────────────────────────────────────
function Stars({ rating, size = "sm", interactive = false, onRate }: {
  rating: number; size?: "sm" | "md" | "lg";
  interactive?: boolean; onRate?: (n: number) => void;
}) {
  const [hover, setHover] = useState(0);
  const sz = { sm: "w-4 h-4", md: "w-5 h-5", lg: "w-7 h-7" }[size];
  const active = interactive ? hover || rating : rating;

  return (
    <div className="flex items-center gap-0.5">
      {[1, 2, 3, 4, 5].map((s) => (
        <svg
          key={s}
          viewBox="0 0 24 24"
          className={`${sz} ${interactive ? "cursor-pointer transition-transform hover:scale-110" : ""}`}
          fill={s <= active ? "#D7A23E" : "none"}
          stroke="#D7A23E"
          strokeWidth="1.5"
          onClick={() => interactive && onRate?.(s)}
          onMouseEnter={() => interactive && setHover(s)}
          onMouseLeave={() => interactive && setHover(0)}
        >
          <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
        </svg>
      ))}
    </div>
  );
}

// ─── Rating breakdown bar ─────────────────────────────────────────────────────
function RatingBar({ star, count, total }: { star: number; count: number; total: number }) {
  const pct = total > 0 ? Math.round((count / total) * 100) : 0;
  return (
    <div className="flex items-center gap-3 text-sm">
      <span className="text-ink-soft w-4 text-right">{star}</span>
      <svg viewBox="0 0 24 24" className="w-3.5 h-3.5 shrink-0" fill="#D7A23E" stroke="none">
        <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
      </svg>
      <div className="flex-1 bg-mist rounded-full h-2 overflow-hidden">
        <div className="bg-gold h-2 rounded-full transition-all" style={{ width: `${pct}%` }} />
      </div>
      <span className="text-xs text-ink-soft w-6">{count}</span>
    </div>
  );
}

// ─── Single review card ───────────────────────────────────────────────────────
function ReviewCard({ review, onHelpful }: { review: Review & { helpfulVoted?: boolean }; onHelpful: (id: string) => void }) {
  return (
    <div className="bg-white border border-mist rounded-md p-5">
      <div className="flex items-start gap-4 mb-3">
        <div className="w-10 h-10 rounded-full bg-forest/10 flex items-center justify-center text-forest font-semibold text-sm shrink-0">
          {review.guestInitial}
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex flex-wrap items-center gap-2">
            <span className="font-semibold text-sm text-forest-deep">{review.guestName}</span>
            {review.verified && (
              <span className="font-mono text-[9px] uppercase tracking-widest bg-[#E8F2EC] text-forest border border-forest/20 px-2 py-0.5 rounded-pill">
                Verified stay
              </span>
            )}
          </div>
          <div className="flex items-center gap-2 mt-0.5">
            <Stars rating={review.rating} size="sm" />
            <span className="text-xs text-ink-soft">{review.date}</span>
          </div>
        </div>
      </div>

      {review.title && (
        <div className="font-semibold text-sm text-ink mb-1.5">{review.title}</div>
      )}
      <p className="text-sm text-ink-soft leading-relaxed">{review.body}</p>

      <div className="flex items-center gap-3 mt-4 pt-3 border-t border-mist">
        <button
          onClick={() => !review.helpfulVoted && onHelpful(review.id)}
          disabled={review.helpfulVoted}
          title={review.helpfulVoted ? "You marked this as helpful" : "Mark as helpful"}
          className={`flex items-center gap-1.5 text-xs transition-colors rounded-pill px-3 py-1.5 border ${
            review.helpfulVoted
              ? "text-forest border-forest bg-[#E8F2EC] cursor-default font-semibold"
              : "text-ink-soft border-mist hover:text-forest hover:border-forest hover:bg-sage cursor-pointer"
          }`}
        >
          <svg viewBox="0 0 24 24" fill={review.helpfulVoted ? "#1E4A3D" : "none"} stroke="currentColor" strokeWidth="2" className="w-3.5 h-3.5">
            <path d="M14 9V5a3 3 0 00-3-3l-4 9v11h11.28a2 2 0 002-1.7l1.38-9a2 2 0 00-2-2.3H14z" strokeLinejoin="round"/>
            <path d="M7 22H4a2 2 0 01-2-2v-7a2 2 0 012-2h3" strokeLinejoin="round"/>
          </svg>
          {review.helpfulVoted ? "Marked helpful" : `Helpful (${review.helpful})`}
        </button>
      </div>
    </div>
  );
}

// ─── Write a review modal ─────────────────────────────────────────────────────
function WriteReviewModal({ targetName, onSubmit, onClose }: {
  targetName: string;
  onSubmit: (review: { rating: number; title: string; body: string }) => Promise<void>;
  onClose: () => void;
}) {
  const [rating,  setRating]  = useState(0);
  const [title,   setTitle]   = useState("");
  const [body,    setBody]    = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const ratingLabels = ["", "Poor", "Fair", "Good", "Very good", "Excellent"];

  async function handleSubmit() {
    if (!rating || !body.trim()) return;
    setSubmitting(true);
    setError(null);
    try {
      await onSubmit({ rating, title, body });
    } catch (e) {
      setError(e instanceof ApiError ? e.message : "Couldn't submit your review. Please try again.");
      setSubmitting(false);
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-ink/40 backdrop-blur-sm px-4 py-6 overflow-y-auto">
      <div className="bg-white rounded-xl border border-mist shadow-card-hover w-full max-w-lg my-auto">
        <div className="flex justify-between items-center px-6 py-5 border-b border-mist">
          <div>
            <h3 className="font-display font-semibold text-xl text-forest-deep">Write a review</h3>
            <p className="text-xs text-ink-soft mt-0.5">{targetName}</p>
          </div>
          <button onClick={onClose} className="text-ink-soft hover:text-ink text-2xl leading-none">×</button>
        </div>

        <div className="p-6 flex flex-col gap-5">
          {/* Star rating */}
          <div>
            <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-3">Your rating</label>
            <div className="flex items-center gap-4">
              <Stars rating={rating} size="lg" interactive onRate={setRating} />
              {rating > 0 && (
                <span className="text-sm font-semibold text-gold-deep">{ratingLabels[rating]}</span>
              )}
            </div>
          </div>

          {/* Title */}
          <div>
            <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">Review title (optional)</label>
            <input
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              placeholder="e.g. Great stay, would recommend"
              className="w-full border border-mist rounded-sm px-4 py-3 text-sm bg-white text-ink focus:outline-2 focus:outline-gold focus:border-forest"
            />
          </div>

          {/* Body */}
          <div>
            <label className="block font-mono text-xs uppercase tracking-widest text-ink-soft mb-2">Your review</label>
            <textarea
              value={body}
              onChange={(e) => setBody(e.target.value)}
              placeholder="Share your experience — what did you like? What could be improved?"
              rows={4}
              className="w-full border border-mist rounded-sm px-4 py-3 text-sm bg-white text-ink focus:outline-2 focus:outline-gold focus:border-forest resize-none"
            />
            <p className="text-xs text-ink-soft mt-1">{body.length}/500 characters</p>
          </div>

          <div className="bg-sage border border-mist rounded-sm px-4 py-3 text-xs text-ink-soft">
            Reviews are only accepted from verified guests who have completed a stay or tenancy through Villa. Your name will be shown publicly.
          </div>
        </div>

        {error && <p className="px-6 text-sm text-red-600 -mt-1 mb-1">{error}</p>}
        <div className="flex justify-between items-center px-6 pb-5 border-t border-mist pt-4">
          <button onClick={onClose} className="inline-flex items-center justify-center font-semibold text-sm px-5 py-2.5 rounded-pill border border-mist text-forest hover:bg-forest hover:border-forest hover:text-white transition-colors">
            Cancel
          </button>
          <button
            disabled={!rating || !body.trim() || submitting}
            onClick={handleSubmit}
            className="inline-flex items-center gap-2 font-semibold text-sm px-6 py-2.5 rounded-pill bg-forest text-white hover:bg-forest-deep transition-colors disabled:opacity-40"
          >
            {submitting ? (
              <><Spinner size="sm" /> Submitting…</>
            ) : "Submit review"}
          </button>
        </div>
      </div>
    </div>
  );
}

// ─── Main ReviewsSection component ───────────────────────────────────────────
interface ReviewsSectionProps {
  targetId: string;
  targetName: string;
  targetType: "accommodation" | "property";
  initialReviews: Review[];
  averageRating: number;
  showWriteReview?: boolean; // only for verified past guests
}

export default function ReviewsSection({
  targetId,
  targetName,
  targetType,
  initialReviews,
  averageRating,
  showWriteReview = false,
}: ReviewsSectionProps) {
  const [reviewList,   setReviewList]   = useState(initialReviews);
  const [helpfulVotes, setHelpfulVotes] = useState<Set<string>>(new Set());
  const [showModal,    setShowModal]    = useState(false);
  const [submitted,    setSubmitted]    = useState(false);
  const [filterStar,   setFilterStar]   = useState(0);
  const [sortBy,       setSortBy]       = useState<SortOption>("recent");
  const [page,         setPage]         = useState(1);

  const total       = reviewList.length;
  const avgRating   = total > 0
    ? Math.round((reviewList.reduce((s, r) => s + r.rating, 0) / total) * 10) / 10
    : averageRating;

  const starCounts = [5, 4, 3, 2, 1].map((s) => ({
    star: s,
    count: reviewList.filter((r) => r.rating === s).length,
  }));

  // Filter
  const filtered = filterStar > 0
    ? reviewList.filter((r) => r.rating === filterStar)
    : reviewList;

  // Sort
  const sorted = [...filtered].sort((a, b) => {
    if (sortBy === "highest") return b.rating - a.rating;
    if (sortBy === "lowest")  return a.rating - b.rating;
    if (sortBy === "helpful") return b.helpful - a.helpful;
    return 0; // "recent" — keep insertion order (newest first from state)
  });

  // Paginate
  const totalPages = Math.max(1, Math.ceil(sorted.length / PER_PAGE));
  const safePage   = Math.min(page, totalPages);
  const paged      = sorted.slice((safePage - 1) * PER_PAGE, safePage * PER_PAGE);

  function resetPage() { setPage(1); }

  function handleHelpful(id: string) {
    if (helpfulVotes.has(id)) return;
    setHelpfulVotes((prev) => new Set(prev).add(id));
    setReviewList((prev) => prev.map((r) => r.id === id ? { ...r, helpful: r.helpful + 1 } : r));
    clientExecute("review.mark-helpful", { id }).catch(() => { /* optimistic; ignore */ });
  }

  async function handleSubmitReview({ rating, title, body }: { rating: number; title: string; body: string }) {
    // Throws on failure so WriteReviewModal can show the error (e.g. "only guests
    // with a completed stay can review").
    const created = await clientExecute<Review>("review.create", {
      targetId, targetType, rating, title: title || undefined, body,
    });
    setReviewList((prev) => [created, ...prev]);
    setShowModal(false);
    setSubmitted(true);
  }

  return (
    <section>
      {/* Header */}
      <div className="flex flex-wrap items-center justify-between gap-4 mb-6">
        <h2 className="font-display font-semibold text-xl text-forest-deep">
          Reviews {total > 0 && <span className="text-ink-soft font-normal text-lg">({total})</span>}
        </h2>
        {showWriteReview && !submitted && (
          <button
            onClick={() => setShowModal(true)}
            className="inline-flex items-center gap-2 font-semibold text-sm px-5 py-2.5 rounded-pill border border-forest text-forest hover:bg-forest hover:text-white transition-colors"
          >
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-4 h-4">
              <path d="M12 20h9M16.5 3.5a2.121 2.121 0 013 3L7 19l-4 1 1-4L16.5 3.5z" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            Write a review
          </button>
        )}
        {submitted && (
          <span className="inline-flex items-center gap-1.5 text-sm text-forest font-semibold">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-4 h-4">
              <path d="M5 12l5 5 9-11" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            Review submitted — thank you!
          </span>
        )}
      </div>

      {total === 0 ? (
        <div className="bg-white border border-mist rounded-md py-12 text-center">
          <svg viewBox="0 0 24 24" fill="none" stroke="#DCE6DD" strokeWidth="1.4" className="w-12 h-12 mx-auto mb-4">
            <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
          </svg>
          <p className="text-sm text-ink-soft">No reviews yet. Be the first to share your experience.</p>
        </div>
      ) : (
        <div className="grid grid-cols-1 lg:grid-cols-[220px_1fr] gap-8 items-start">
          {/* Left — summary */}
          <div className="bg-white border border-mist rounded-md p-5">
            <div className="text-center mb-5 pb-5 border-b border-mist">
              <div className="font-display font-bold text-5xl text-forest-deep mb-1">{avgRating.toFixed(1)}</div>
              <Stars rating={avgRating} size="md" />
              <div className="text-xs text-ink-soft mt-2">{total} review{total !== 1 ? "s" : ""}</div>
            </div>
            <div className="flex flex-col gap-2.5">
              {starCounts.map(({ star, count }) => (
                <button
                  key={star}
                  onClick={() => { setFilterStar(filterStar === star ? 0 : star); resetPage(); }}
                  className={`w-full transition-opacity ${filterStar > 0 && filterStar !== star ? "opacity-40" : ""}`}
                >
                  <RatingBar star={star} count={count} total={total} />
                </button>
              ))}
            </div>
            {filterStar > 0 && (
              <button onClick={() => { setFilterStar(0); resetPage(); }} className="w-full mt-3 text-xs text-forest font-semibold hover:underline">
                Clear filter
              </button>
            )}
          </div>

          {/* Right — sort + review cards */}
          <div className="flex flex-col gap-4">
            {/* Sort + count bar */}
            <div className="flex flex-wrap items-center justify-between gap-3">
              <p className="text-sm text-ink-soft">
                {filterStar > 0
                  ? <><strong className="text-ink">{filtered.length}</strong> review{filtered.length !== 1 ? "s" : ""} with {filterStar} star{filterStar !== 1 ? "s" : ""}</>
                  : <><strong className="text-ink">{total}</strong> review{total !== 1 ? "s" : ""}</>
                }
              </p>
              <select
                value={sortBy}
                onChange={(e) => { setSortBy(e.target.value as SortOption); resetPage(); }}
                className="text-xs border border-mist rounded-sm px-3 py-2 bg-white text-ink focus:outline-2 focus:outline-gold"
              >
                <option value="recent">Most recent</option>
                <option value="highest">Highest rated</option>
                <option value="lowest">Lowest rated</option>
                <option value="helpful">Most helpful</option>
              </select>
            </div>

            {paged.map((r) => (
              <ReviewCard
                key={r.id}
                review={{ ...r, helpfulVoted: helpfulVotes.has(r.id) }}
                onHelpful={handleHelpful}
              />
            ))}

            {/* Pagination — smart ellipsis for large counts */}
            {totalPages > 1 && (
              <div className="flex flex-col gap-3 pt-2 border-t border-mist">
                {/* Progress indicator */}
                <div className="flex items-center justify-between text-xs text-ink-soft">
                  <span>Showing <strong className="text-ink">{(safePage - 1) * PER_PAGE + 1}–{Math.min(safePage * PER_PAGE, sorted.length)}</strong> of <strong className="text-ink">{sorted.length}</strong> review{sorted.length !== 1 ? "s" : ""}</span>
                  <span className="font-mono">Page {safePage} of {totalPages}</span>
                </div>
                {/* Progress bar */}
                <div className="w-full bg-mist rounded-full h-1.5 overflow-hidden">
                  <div className="bg-forest h-1.5 rounded-full transition-all" style={{ width: `${(safePage / totalPages) * 100}%` }} />
                </div>
                {/* Page buttons with ellipsis */}
                <div className="flex items-center gap-1">
                  {/* Prev */}
                  <button onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={safePage === 1}
                    className="w-8 h-8 flex items-center justify-center rounded-sm border border-mist bg-white text-ink-soft hover:border-forest hover:text-forest transition-colors disabled:opacity-30 disabled:cursor-not-allowed">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-3.5 h-3.5"><path d="M15 18l-6-6 6-6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  </button>

                  {/* Smart page numbers */}
                  {(() => {
                    const pages: (number | "…")[] = [];
                    if (totalPages <= 7) {
                      for (let i = 1; i <= totalPages; i++) pages.push(i);
                    } else {
                      const set = new Set([1, totalPages, safePage - 1, safePage, safePage + 1].filter(n => n >= 1 && n <= totalPages));
                      const sorted2 = Array.from(set).sort((a, b) => a - b);
                      sorted2.forEach((n, i) => {
                        if (i > 0 && (n as number) - (sorted2[i - 1] as number) > 1) pages.push("…");
                        pages.push(n);
                      });
                    }
                    return pages.map((p, i) => p === "…" ? (
                      <span key={`e${i}`} className="w-8 h-8 flex items-center justify-center text-xs text-ink-soft">…</span>
                    ) : (
                      <button key={p} onClick={() => setPage(p as number)}
                        className={`w-8 h-8 flex items-center justify-center rounded-sm border text-xs font-mono font-medium transition-colors ${
                          p === safePage ? "bg-forest border-forest text-white" : "border-mist bg-white text-ink-soft hover:border-forest hover:text-forest"
                        }`}>
                        {p}
                      </button>
                    ));
                  })()}

                  {/* Next */}
                  <button onClick={() => setPage((p) => Math.min(totalPages, p + 1))} disabled={safePage === totalPages}
                    className="w-8 h-8 flex items-center justify-center rounded-sm border border-mist bg-white text-ink-soft hover:border-forest hover:text-forest transition-colors disabled:opacity-30 disabled:cursor-not-allowed">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="w-3.5 h-3.5"><path d="M9 18l6-6-6-6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                  </button>
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* Write review modal */}
      {showModal && (
        <WriteReviewModal
          targetName={targetName}
          onSubmit={handleSubmitReview}
          onClose={() => setShowModal(false)}
        />
      )}
    </section>
  );
}
