"use client";

import { useEffect, useState, useCallback, useMemo } from "react";
import { useSearchParams, useRouter } from "next/navigation";
import { createClient } from "@/lib/supabase/client";
import Card, { CardHeader } from "@/components/ui/Card";
import Spinner from "@/components/ui/Spinner";
import { Select } from "@/components/ui/Select";
import { useToast } from "@/components/ui/Toast";
import { formatDate } from "@/lib/format";
import { Star, MessageSquareText, Plus, Send } from "lucide-react";
import { Field, Textarea } from "@/components/ui/Input";
import Button from "@/components/ui/Button";

type Row = {
  id: string;
  rating: number;
  comment: string | null;
  created_at: string;
  program: string;
  program_id: string;
  volunteer: string;
  is_edited?: boolean;
};

type ProgramOption = {
  id: string;
  title: string;
};

function Stars({ value }: { value: number }) {
  return (
    <span className="inline-flex items-center gap-0.5">
      {[1, 2, 3, 4, 5].map((n) => (
        <Star
          key={n}
          size={15}
          className={n <= value ? "fill-warning text-warning" : "text-sand-dark"}
        />
      ))}
    </span>
  );
}

function StarRatingInput({ value, onChange }: { value: number; onChange: (v: number) => void }) {
  return (
    <div className="flex gap-1">
      {[1, 2, 3, 4, 5].map((n) => (
        <button
          key={n}
          type="button"
          onClick={() => onChange(n)}
          className="p-1 hover:scale-110 transition-transform"
        >
          <Star
            size={24}
            className={n <= value ? "fill-warning text-warning" : "text-sand-dark"}
          />
        </button>
      ))}
    </div>
  );
}

function useIsMobileViewport() {
  const [isMobile, setIsMobile] = useState(false);
  useEffect(() => {
    const check = () => setIsMobile(window.innerWidth < 768);
    check();
    window.addEventListener("resize", check);
    return () => window.removeEventListener("resize", check);
  }, []);
  return isMobile;
}

export default function FeedbackPage() {
  const supabase = createClient();
  const searchParams = useSearchParams();
  const router = useRouter();
  const { notify } = useToast();
  const isViewportMobile = useIsMobileViewport();
  const isPreviewMobile = searchParams.get("preview") === "mobile";
  const isMobile = isViewportMobile || isPreviewMobile;

  const [loading, setLoading] = useState(true);
  const [userRole, setUserRole] = useState<"admin" | "volunteer">("volunteer");
  const [userId, setUserId] = useState("");

  // Admin states
  const [rows, setRows] = useState<Row[]>([]);
  const [programFilter, setProgramFilter] = useState("");
  const [ratingFilter, setRatingFilter] = useState("");

  // Volunteer states
  const [eligiblePrograms, setEligiblePrograms] = useState<ProgramOption[]>([]);
  const [myFeedbackList, setMyFeedbackList] = useState<Row[]>([]);
  const [submitting, setSubmitting] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [feedbackForm, setFeedbackForm] = useState({
    program_id: "",
    rating: 5,
    comment: "",
  });

  const load = useCallback(async () => {
    const { data: userRes } = await supabase.auth.getUser();
    if (!userRes.user) {
      router.push("/login");
      return;
    }
    setUserId(userRes.user.id);

    const { data: profile } = await supabase
      .from("profiles")
      .select("role")
      .eq("id", userRes.user.id)
      .single();

    if (!profile) return;
    setUserRole(profile.role);

    if (profile.role === "admin") {
      const { data, error } = await supabase
        .from("feedback")
        .select("id, rating, comment, created_at, program_id, is_edited, programs(title), profiles(full_name)")
        .order("created_at", { ascending: false });

      if (error) {
        notify(error.message, "error");
        setLoading(false);
        return;
      }
      setRows(
        (data ?? []).map((f: any) => ({
          id: f.id,
          rating: f.rating ?? 0,
          comment: f.comment,
          created_at: f.created_at,
          program_id: f.program_id,
          program: f.programs?.title ?? "Unknown program",
          volunteer: f.profiles?.full_name ?? "Anonymous",
          is_edited: f.is_edited ?? false,
        }))
      );
    } else {
      // Volunteer: load feedback they have submitted, and programs they are approved for
      const [myFbRes, approvedProgsRes] = await Promise.all([
        supabase
          .from("feedback")
          .select("id, rating, comment, created_at, program_id, is_edited, programs(title), profiles(full_name)")
          .eq("volunteer_id", userRes.user.id)
          .order("created_at", { ascending: false }),
        supabase
          .from("applications")
          .select("program_id, programs(id, title, status)")
          .eq("volunteer_id", userRes.user.id)
          .eq("status", "approved")
      ]);

      const myFeedback = (myFbRes.data ?? []).map((f: any) => ({
        id: f.id,
        rating: f.rating ?? 0,
        comment: f.comment,
        created_at: f.created_at,
        program_id: f.program_id,
        program: f.programs?.title ?? "Unknown program",
        volunteer: f.profiles?.full_name ?? "Me",
        is_edited: f.is_edited ?? false,
      }));
      setMyFeedbackList(myFeedback);

      // Student is eligible to leave feedback for programs they joined (status approved) and which are completed
      const eligible = (approvedProgsRes.data ?? [])
        .map((app: any) => app.programs)
        .filter((prog: any) => prog && prog.status === "completed")
        .map((prog: any) => ({
          id: prog.id,
          title: prog.title
        }));

      setEligiblePrograms(eligible);
    }
    setLoading(false);
  }, [supabase, router, notify]);

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

  // Submit Feedback
  async function submitFeedback(e: React.FormEvent) {
    e.preventDefault();
    if (!feedbackForm.program_id) return notify("Select a program to review.", "error");
    setSubmitting(true);

    let error;
    if (editingId) {
      // Update existing feedback
      const { error: err } = await supabase
        .from("feedback")
        .update({
          rating: feedbackForm.rating,
          comment: feedbackForm.comment || null,
          is_edited: true,
        })
        .eq("id", editingId);
      error = err;
    } else {
      // Create new feedback
      const { error: err } = await supabase.from("feedback").insert({
        program_id: feedbackForm.program_id,
        volunteer_id: userId,
        rating: feedbackForm.rating,
        comment: feedbackForm.comment || null,
      });
      error = err;
    }

    setSubmitting(false);

    if (error) {
      notify(error.message, "error");
    } else {
      if (editingId) {
        notify("Feedback updated successfully!");
      } else {
        notify("Feedback submitted. Thank you for your response!");
      }
      setFeedbackForm({ program_id: "", rating: 5, comment: "" });
      setEditingId(null);
      load();
    }
  }

  async function deleteFeedback(id: string) {
    if (!confirm("Are you sure you want to delete this feedback?")) return;
    const { error } = await supabase.from("feedback").delete().eq("id", id);
    if (error) {
      notify(error.message, "error");
    } else {
      notify("Feedback deleted successfully.");
      load();
    }
  }

  function startEdit(f: Row) {
    setFeedbackForm({
      program_id: f.program_id,
      rating: f.rating,
      comment: f.comment || "",
    });
    setEditingId(f.id);
  }

  function cancelEdit() {
    setFeedbackForm({
      program_id: "",
      rating: 5,
      comment: "",
    });
    setEditingId(null);
  }

  // Admin filters
  const adminPrograms = useMemo(() => {
    const m = new Map<string, string>();
    rows.forEach((r) => m.set(r.program_id, r.program));
    return Array.from(m, ([id, title]) => ({ id, title }));
  }, [rows]);

  const filteredRows = useMemo(() => {
    let result = rows;
    if (programFilter) {
      result = result.filter((r) => r.program_id === programFilter);
    }
    if (ratingFilter) {
      result = result.filter((r) => r.rating === Number(ratingFilter));
    }
    return result;
  }, [rows, programFilter, ratingFilter]);

  const summary = useMemo(() => {
    if (!filteredRows.length) return { avg: 0, count: 0, dist: [0, 0, 0, 0, 0] };
    const dist = [0, 0, 0, 0, 0];
    let sum = 0;
    filteredRows.forEach((r) => {
      sum += r.rating;
      if (r.rating >= 1 && r.rating <= 5) dist[r.rating - 1]++;
    });
    return { avg: sum / filteredRows.length, count: filteredRows.length, dist };
  }, [filteredRows]);

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

  // RENDER ADMIN REVIEW VIEW
  if (userRole === "admin") {
    return (
      <div className="space-y-6">
        <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h1 className={`${isMobile ? "text-xl font-bold" : "text-2xl font-extrabold"} text-ink`}>
              View Feedback
            </h1>
            <p className="text-sm text-muted">Ratings and comments from completed programs.</p>
          </div>
          <div className="flex gap-2">
            <Select value={programFilter} onChange={(e) => setProgramFilter(e.target.value)} className="w-48">
              <option value="">All programs</option>
              {adminPrograms.map((p) => (
                <option key={p.id} value={p.id}>
                  {p.title}
                </option>
              ))}
            </Select>
            <Select value={ratingFilter} onChange={(e) => setRatingFilter(e.target.value)} className="w-36">
              <option value="">All ratings</option>
              <option value="5">5 Stars</option>
              <option value="4">4 Stars</option>
              <option value="3">3 Stars</option>
              <option value="2">2 Stars</option>
              <option value="1">1 Star</option>
            </Select>
          </div>
        </div>

        <div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
          <Card className="flex flex-col items-center justify-center p-6 text-center">
            <p className="text-sm font-medium text-muted">Average rating</p>
            <p className="mt-2 text-5xl font-extrabold text-emerald">{summary.avg.toFixed(1)}</p>
            <div className="mt-2">
              <Stars value={Math.round(summary.avg)} />
            </div>
            <p className="mt-2 text-xs text-muted">from {summary.count} response(s)</p>
          </Card>

          <Card className="lg:col-span-2">
            <CardHeader title="Rating distribution" />
            <div className="space-y-2.5 p-5">
              {[5, 4, 3, 2, 1].map((star) => {
                const n = summary.dist[star - 1];
                const pct = summary.count ? (n / summary.count) * 100 : 0;
                return (
                  <div key={star} className="flex items-center gap-3">
                    <span className="flex w-10 items-center gap-1 text-sm text-muted">
                      {star} <Star size={12} className="fill-warning text-warning" />
                    </span>
                    <div className="h-2.5 flex-1 overflow-hidden rounded-full bg-sand">
                      <div className="h-full rounded-full bg-emerald" style={{ width: `${pct}%` }} />
                    </div>
                    <span className="w-8 text-right text-sm text-muted">{n}</span>
                  </div>
                );
              })}
            </div>
          </Card>
        </div>

        <Card>
          <CardHeader title={`Comments (${filteredRows.length})`} />
          <ul className="divide-y divide-sand-dark/40">
            {filteredRows.length ? (
              filteredRows.map((f) => (
                <li key={f.id} className="px-5 py-4">
                  <div className="flex items-center justify-between gap-3">
                    <div className="flex items-center gap-3">
                      <Stars value={f.rating} />
                      <span className="text-sm font-semibold text-ink">{f.volunteer}</span>
                    </div>
                    <span className="text-xs text-muted">{formatDate(f.created_at)}</span>
                  </div>
                  <div className="flex items-center gap-2 mt-1">
                    <p className="text-xs font-medium text-teal">{f.program}</p>
                    {f.is_edited && (
                      <span className="text-[9px] text-muted font-semibold bg-sand px-1.5 py-0.5 rounded italic border border-sand-dark/30">
                        Edited
                      </span>
                    )}
                  </div>
                  {f.comment && <p className="mt-2 text-sm text-ink">{f.comment}</p>}
                </li>
              ))
            ) : (
              <li className="flex flex-col items-center gap-2 px-5 py-12 text-center text-sm text-muted">
                <MessageSquareText size={24} className="text-sand-dark" />
                No feedback yet.
              </li>
            )}
          </ul>
        </Card>
      </div>
    );
  }

  // RENDER VOLUNTEER SUBMISSION VIEW
  return (
    <div className="space-y-6">
      <div>
        <h1 className={`${isMobile ? "text-xl font-bold" : "text-2xl font-extrabold"} text-ink`}>
          Program Feedback
        </h1>
        <p className="text-sm text-muted">Share your experience and thoughts about programs you joined.</p>
      </div>

      <div className={`grid grid-cols-1 gap-6 ${isMobile ? "" : "lg:grid-cols-3"}`}>
        {/* Feedback Submission Form */}
        <div className="lg:col-span-1">
          <Card>
            <CardHeader title={editingId ? "Edit Feedback" : "Submit Feedback"} />
            <form onSubmit={submitFeedback} className="p-5 space-y-4">
              <Field label="Choose Program">
                <Select
                  value={feedbackForm.program_id}
                  onChange={(e) => setFeedbackForm({ ...feedbackForm, program_id: e.target.value })}
                  required
                  disabled={!!editingId}
                >
                  <option value="">Select program...</option>
                  {eligiblePrograms.map((p) => (
                    <option key={p.id} value={p.id}>
                      {p.title}
                    </option>
                  ))}
                  {editingId && (
                    <option value={feedbackForm.program_id}>
                      {myFeedbackList.find(f => f.id === editingId)?.program ?? "Selected Program"}
                    </option>
                  )}
                </Select>
              </Field>

              <Field label="Rating">
                <StarRatingInput
                  value={feedbackForm.rating}
                  onChange={(rating) => setFeedbackForm({ ...feedbackForm, rating })}
                />
              </Field>

              <Field label="Comments / Suggestions">
                <Textarea
                  rows={4}
                  placeholder="What went well? What can be improved?"
                  value={feedbackForm.comment || ""}
                  onChange={(e) => setFeedbackForm({ ...feedbackForm, comment: e.target.value })}
                />
              </Field>

              <div className="flex gap-2">
                {editingId && (
                  <Button type="button" variant="secondary" onClick={cancelEdit} className="flex-1">
                    Cancel
                  </Button>
                )}
                <Button type="submit" disabled={submitting} className="flex-1 flex items-center justify-center gap-2">
                  <Send size={15} /> {submitting ? "Sending..." : editingId ? "Update" : "Submit"}
                </Button>
              </div>
            </form>
          </Card>
        </div>

        {/* Previous Feedback List */}
        <div className="lg:col-span-2">
          <Card>
            <CardHeader title={`My responses (${myFeedbackList.length})`} />
            <ul className="divide-y divide-sand-dark/40 max-h-[500px] overflow-y-auto">
              {myFeedbackList.length > 0 ? (
                myFeedbackList.map((f) => (
                  <li key={f.id} className="p-4 space-y-2 bg-white hover:bg-sand/10 transition-colors">
                    <div className="flex justify-between items-center gap-2">
                      <Stars value={f.rating} />
                      <div className="flex items-center gap-2">
                        {f.is_edited && (
                          <span className="text-[9px] text-muted bg-sand px-1.5 py-0.5 rounded italic border border-sand-dark/30">
                            Edited
                          </span>
                        )}
                        <span className="text-[10px] text-muted">{formatDate(f.created_at)}</span>
                      </div>
                    </div>
                    <div className="flex justify-between items-start gap-3">
                      <div className="flex-1">
                        <p className="text-xs font-bold text-ink">{f.program}</p>
                        {f.comment && <p className="text-xs text-muted leading-relaxed italic mt-0.5">"{f.comment}"</p>}
                      </div>
                      <div className="flex gap-2 shrink-0">
                        <button
                          type="button"
                          onClick={() => startEdit(f)}
                          className="text-xs font-bold text-emerald hover:underline px-1 py-0.5"
                        >
                          Edit
                        </button>
                        <button
                          type="button"
                          onClick={() => deleteFeedback(f.id)}
                          className="text-xs font-bold text-error hover:underline px-1 py-0.5"
                        >
                          Delete
                        </button>
                      </div>
                    </div>
                  </li>
                ))
              ) : (
                <li className="py-16 text-center text-xs text-muted">You haven't submitted any feedback yet.</li>
              )}
            </ul>
          </Card>
        </div>
      </div>
    </div>
  );
}
