"use client";

import { useEffect, useState, useCallback } from "react";
import { createClient } from "@/lib/supabase/client";
import Card, { CardHeader } from "@/components/ui/Card";
import Button from "@/components/ui/Button";
import Spinner from "@/components/ui/Spinner";
import Modal from "@/components/ui/Modal";
import { Field, Textarea } from "@/components/ui/Input";
import { Select } from "@/components/ui/Select";
import { useToast } from "@/components/ui/Toast";
import { formatDate } from "@/lib/format";
import { Star, MessageSquare, Plus, Trash2 } from "lucide-react";

function Stars({
  value,
  onChange,
  readonly = false,
}: {
  value: number;
  onChange?: (v: number) => void;
  readonly?: boolean;
}) {
  return (
    <div className="flex gap-1">
      {[1, 2, 3, 4, 5].map((s) => (
        <button
          key={s}
          type="button"
          disabled={readonly}
          onClick={() => onChange?.(s)}
          className={`transition-colors ${readonly ? "cursor-default" : "cursor-pointer hover:scale-110"}`}
        >
          <Star
            size={readonly ? 16 : 24}
            className={s <= value ? "fill-yellow-400 text-yellow-400" : "text-sand-dark"}
          />
        </button>
      ))}
    </div>
  );
}

export default function FeedbackPage() {
  const supabase = createClient();
  const { notify } = useToast();
  const [loading, setLoading] = useState(true);
  const [uid, setUid] = useState("");
  // Eligible programs: approved applications minus programs that already have an
  // un-deleted feedback row. Stored as id+title pairs so we can re-show after delete.
  const [programs, setPrograms] = useState<{ id: string; title: string }[]>([]);
  const [feedback, setFeedback] = useState<any[]>([]); // feedback already given
  const [open, setOpen] = useState(false);
  const [saving, setSaving] = useState(false);

  // Confirm-delete state
  const [deletingId, setDeletingId] = useState<string | null>(null);

  const [form, setForm] = useState({ program_id: "", rating: 5, comment: "" });

  const load = useCallback(async () => {
    const { data: u } = await supabase.auth.getUser();
    if (!u.user) return;
    setUid(u.user.id);

    const [apps, fb] = await Promise.all([
      supabase
        .from("applications")
        .select("program_id, programs(id, title)")
        .eq("volunteer_id", u.user.id)
        .eq("status", "approved"),
      supabase
        .from("feedback")
        .select("id, rating, comment, created_at, program_id, programs(title)")
        .eq("volunteer_id", u.user.id)
        .order("created_at", { ascending: false }),
    ]);

    // Exclude programs that already have a live feedback row (by program_id).
    // After a feedback row is deleted, that program is no longer in this set,
    // which is what allows re-submission.
    const feedbackProgramIds = new Set(
      (fb.data ?? []).map((f: any) => f.program_id).filter(Boolean)
    );

    setPrograms(
      (apps.data ?? [])
        .map((a: any) => a.programs)
        .filter(Boolean)
        .filter((p: any) => !feedbackProgramIds.has(p.id))
        // De-duplicate by id (in case of multiple applications)
        .filter(
          (p: any, idx: number, arr: any[]) =>
            arr.findIndex((q) => q.id === p.id) === idx
        )
    );
    setFeedback(fb.data ?? []);
    setLoading(false);
  }, [supabase]);

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

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (!form.program_id) return notify("Select a program.", "error");
    setSaving(true);
    const { error } = await supabase.from("feedback").insert({
      volunteer_id: uid,
      program_id: form.program_id,
      rating: form.rating,
      comment: form.comment || null,
    });
    setSaving(false);
    if (error) {
      if (error.code === "23505") {
        notify("You've already submitted feedback for this program.", "error");
      } else {
        notify(error.message, "error");
      }
      return;
    }
    notify("Thank you for your feedback!");
    setOpen(false);
    setForm({ program_id: "", rating: 5, comment: "" });
    load();
  }

  async function confirmDelete(id: string) {
    if (!confirm("Delete this feedback? You'll be able to submit a new one for the same program afterwards.")) {
      return;
    }
    setDeletingId(id);
    const { error } = await supabase.from("feedback").delete().eq("id", id);
    setDeletingId(null);
    if (error) {
      notify(error.message, "error");
      return;
    }
    notify("Feedback deleted. You can submit a new one for this program if you wish.");
    load();
  }

  if (loading) return <Spinner label="Loading feedback…" />;

  const avg =
    feedback.length > 0
      ? (feedback.reduce((s: number, f: any) => s + f.rating, 0) / feedback.length).toFixed(1)
      : "—";

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="text-2xl font-extrabold text-ink">Feedback</h1>
          <p className="text-sm text-muted">
            Share your experience with the programs you volunteered for.
          </p>
        </div>
        {programs.length > 0 && (
          <Button onClick={() => setOpen(true)}>
            <Plus size={16} /> Give Feedback
          </Button>
        )}
      </div>

      {/* Stats */}
      <div className="grid gap-4 sm:grid-cols-2">
        <Card className="flex items-center gap-4 p-5">
          <div className="flex h-12 w-12 items-center justify-center rounded-card bg-yellow-50 text-yellow-500">
            <Star size={24} className="fill-yellow-400" />
          </div>
          <div>
            <p className="text-2xl font-extrabold text-ink">{avg}</p>
            <p className="text-xs text-muted">Your average rating</p>
          </div>
        </Card>
        <Card className="flex items-center gap-4 p-5">
          <div className="flex h-12 w-12 items-center justify-center rounded-card bg-emerald-light text-emerald">
            <MessageSquare size={24} />
          </div>
          <div>
            <p className="text-2xl font-extrabold text-ink">{feedback.length}</p>
            <p className="text-xs text-muted">Reviews submitted</p>
          </div>
        </Card>
      </div>

      {/* Past feedback */}
      {feedback.length === 0 ? (
        <Card>
          <p className="px-5 py-12 text-center text-sm text-muted">
            You haven't given any feedback yet. After completing a program, come here to share your
            experience.
          </p>
        </Card>
      ) : (
        <div className="space-y-3">
          {feedback.map((f: any) => (
            <Card key={f.id} className="p-5">
              <div className="flex items-start justify-between gap-3">
                <div>
                  <p className="font-bold text-ink">{f.programs?.title ?? "Program"}</p>
                  <Stars value={f.rating} readonly />
                </div>
                <div className="flex flex-col items-end gap-2">
                  <span className="text-xs text-muted whitespace-nowrap">
                    {formatDate(f.created_at)}
                  </span>
                  <button
                    onClick={() => confirmDelete(f.id)}
                    disabled={deletingId === f.id}
                    className="flex items-center gap-1 rounded-card bg-red-50 px-2 py-1 text-xs font-semibold text-error hover:bg-red-100 transition-colors disabled:opacity-50"
                    title="Delete feedback"
                  >
                    <Trash2 size={12} />
                    {deletingId === f.id ? "Deleting…" : "Delete"}
                  </button>
                </div>
              </div>
              {f.comment && <p className="mt-2 text-sm text-muted">{f.comment}</p>}
            </Card>
          ))}
        </div>
      )}

      {/* Give feedback modal */}
      <Modal open={open} onClose={() => setOpen(false)} title="Give Feedback">
        <form onSubmit={submit} className="space-y-4">
          <Field label="Program">
            <Select
              value={form.program_id}
              onChange={(e) => setForm({ ...form, program_id: e.target.value })}
            >
              <option value="">Select a program…</option>
              {programs.map((p: any) => (
                <option key={p.id} value={p.id}>
                  {p.title}
                </option>
              ))}
            </Select>
          </Field>
          <Field label="Rating">
            <Stars value={form.rating} onChange={(v) => setForm({ ...form, rating: v })} />
          </Field>
          <Field label="Comment" hint="Optional">
            <Textarea
              rows={3}
              value={form.comment}
              onChange={(e) => setForm({ ...form, comment: e.target.value })}
              placeholder="How was your experience? Any suggestions?"
            />
          </Field>
          <div className="flex justify-end gap-2 pt-2">
            <Button type="button" variant="secondary" onClick={() => setOpen(false)}>
              Cancel
            </Button>
            <Button type="submit" disabled={saving}>
              {saving ? "Submitting…" : "Submit Feedback"}
            </Button>
          </div>
        </form>
      </Modal>
    </div>
  );
}