"use client";

import { useCallback, useEffect, useState } from "react";
import { Star } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import DataService from "@/config/axios";
import { getApiErrorMessage } from "@/lib/api-error";
import { cn } from "@/lib/utils";
import { toast } from "sonner";

type Review = {
  _id: string;
  name: string;
  rating: number;
  title?: string;
  comment: string;
  createdAt: string;
};

type ReviewsResponse = {
  reviews: Review[];
  ratingValue: number | null;
  reviewCount: number;
};

function Stars({ value, className }: { value: number; className?: string }) {
  return (
    <span className={cn("inline-flex items-center", className)} aria-label={`${value} out of 5`}>
      {[1, 2, 3, 4, 5].map((n) => (
        <Star
          key={n}
          className={cn(
            "size-4",
            n <= Math.round(value) ? "fill-amber-400 text-amber-400" : "text-gray-300"
          )}
        />
      ))}
    </span>
  );
}

export default function ProductReviews({ slug }: { slug: string }) {
  const [data, setData] = useState<ReviewsResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [submitting, setSubmitting] = useState(false);
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [title, setTitle] = useState("");
  const [comment, setComment] = useState("");
  const [rating, setRating] = useState(0);
  const [hoverRating, setHoverRating] = useState(0);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await DataService.get(
        `/public/products/${encodeURIComponent(slug)}/reviews`
      );
      setData((res.data?.data as ReviewsResponse) || null);
    } catch {
      setData(null);
    } finally {
      setLoading(false);
    }
  }, [slug]);

  useEffect(() => {
    load();
  }, [load]);

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!name.trim() || !comment.trim()) {
      toast.error("Please add your name and a comment.");
      return;
    }
    if (rating < 1) {
      toast.error("Please select a star rating.");
      return;
    }
    setSubmitting(true);
    try {
      const res = await DataService.post(
        `/public/products/${encodeURIComponent(slug)}/reviews`,
        { name: name.trim(), email: email.trim(), title: title.trim(), comment: comment.trim(), rating }
      );
      toast.success(res.data?.message || "Thanks for your review!");
      setName("");
      setEmail("");
      setTitle("");
      setComment("");
      setRating(0);
    } catch (err) {
      toast.error(getApiErrorMessage(err, "Could not submit review."));
    } finally {
      setSubmitting(false);
    }
  };

  const reviews = data?.reviews ?? [];
  const ratingValue = data?.ratingValue ?? null;
  const reviewCount = data?.reviewCount ?? 0;

  return (
    <div className="space-y-8">
      {/* Summary */}
      <div className="flex flex-wrap items-center gap-3">
        {ratingValue != null ? (
          <>
            <span className="text-3xl font-bold text-slate-900">{ratingValue.toFixed(1)}</span>
            <Stars value={ratingValue} />
            <span className="text-sm text-gray-600">
              Based on {reviewCount} {reviewCount === 1 ? "review" : "reviews"}
            </span>
          </>
        ) : (
          <span className="text-sm text-gray-600">
            {loading ? "Loading reviews…" : "No reviews yet. Be the first to review this product."}
          </span>
        )}
      </div>

      {/* Existing reviews */}
      {reviews.length > 0 ? (
        <ul className="space-y-5">
          {reviews.map((r) => (
            <li key={r._id} className="border-b border-gray-100 pb-5 last:border-0">
              <div className="flex items-center justify-between gap-3">
                <span className="font-semibold text-slate-900">{r.name}</span>
                <span className="text-xs text-gray-400">
                  {new Date(r.createdAt).toLocaleDateString()}
                </span>
              </div>
              <Stars value={r.rating} className="mt-1" />
              {r.title ? <p className="mt-2 font-medium text-slate-800">{r.title}</p> : null}
              <p className="mt-1 text-sm leading-relaxed text-gray-600">{r.comment}</p>
            </li>
          ))}
        </ul>
      ) : null}

      {/* Submit form */}
      <form onSubmit={handleSubmit} className="rounded-xl border border-gray-200 p-5">
        <h3 className="mb-4 text-lg font-semibold text-slate-900">Write a review</h3>

        <div className="mb-4">
          <Label className="mb-1.5 block">Your rating</Label>
          <div className="flex items-center gap-1" onMouseLeave={() => setHoverRating(0)}>
            {[1, 2, 3, 4, 5].map((n) => (
              <button
                key={n}
                type="button"
                aria-label={`Rate ${n} star${n > 1 ? "s" : ""}`}
                onClick={() => setRating(n)}
                onMouseEnter={() => setHoverRating(n)}
                className="p-0.5"
              >
                <Star
                  className={cn(
                    "size-6 transition",
                    n <= (hoverRating || rating)
                      ? "fill-amber-400 text-amber-400"
                      : "text-gray-300"
                  )}
                />
              </button>
            ))}
          </div>
        </div>

        <div className="grid gap-4 sm:grid-cols-2">
          <div>
            <Label htmlFor="review-name" className="mb-1.5 block">
              Name <span className="text-red-500">*</span>
            </Label>
            <Input
              id="review-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Your name"
              required
            />
          </div>
          <div>
            <Label htmlFor="review-email" className="mb-1.5 block">
              Email <span className="text-gray-400">(optional, not shown)</span>
            </Label>
            <Input
              id="review-email"
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="you@example.com"
            />
          </div>
        </div>

        <div className="mt-4">
          <Label htmlFor="review-title" className="mb-1.5 block">
            Title <span className="text-gray-400">(optional)</span>
          </Label>
          <Input
            id="review-title"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder="Summarize your experience"
          />
        </div>

        <div className="mt-4">
          <Label htmlFor="review-comment" className="mb-1.5 block">
            Review <span className="text-red-500">*</span>
          </Label>
          <Textarea
            id="review-comment"
            value={comment}
            onChange={(e) => setComment(e.target.value)}
            placeholder="What did you like or dislike?"
            rows={4}
            required
          />
        </div>

        <div className="mt-4 flex items-center gap-3">
          <Button type="submit" disabled={submitting}>
            {submitting ? "Submitting…" : "Submit review"}
          </Button>
          <span className="text-xs text-gray-500">Reviews appear after approval.</span>
        </div>
      </form>
    </div>
  );
}
