"use client";

import { useEffect, useState, useCallback } from "react";
import { createClient } from "@/lib/supabase/client";
import Card from "@/components/ui/Card";
import Button from "@/components/ui/Button";
import Badge, { statusTone } from "@/components/ui/Badge";
import Spinner from "@/components/ui/Spinner";
import Modal from "@/components/ui/Modal";
import { useToast } from "@/components/ui/Toast";
import { Input } from "@/components/ui/Input";
import { formatDateTime, formatDate } from "@/lib/format";
import { MapPin, CalendarDays, Users, Award, Search } from "lucide-react";

export default function BrowsePrograms() {
  const supabase = createClient();
  const { notify } = useToast();

  const [loading, setLoading] = useState(true);
  const [uid, setUid] = useState<string>("");
  const [programs, setPrograms] = useState<any[]>([]);
  const [appliedIds, setAppliedIds] = useState<Record<string, string>>({}); // program_id -> status
  const [search, setSearch] = useState("");
  const [detail, setDetail] = useState<any | null>(null);
  const [applying, setApplying] = useState<string>("");

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

    const [progs, apps] = await Promise.all([
      supabase
        .from("programs")
        .select(
          "id, title, description, venue, start_at, end_at, slots, merit_value, status, program_skills(skills(name))"
        )
        .in("status", ["open", "closed"])
        .order("start_at", { ascending: true }),
      supabase.from("applications").select("program_id, status").eq("volunteer_id", u.user.id),
    ]);

    setPrograms(progs.data ?? []);
    const map: Record<string, string> = {};
    (apps.data ?? []).forEach((a: any) => (map[a.program_id] = a.status));
    setAppliedIds(map);
    setLoading(false);
  }, [supabase]);

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

  async function apply(programId: string) {
    setApplying(programId);
    const { error } = await supabase
      .from("applications")
      .insert({ program_id: programId, volunteer_id: uid });
    setApplying("");
    if (error) {
      notify(
        error.code === "23505" ? "You already applied to this program." : error.message,
        "error"
      );
      return;
    }
    notify("Application submitted! You'll be notified once it's reviewed.");
    setAppliedIds((m) => ({ ...m, [programId]: "pending" }));
    setDetail(null);
  }

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

  const filtered = programs.filter((p) =>
    `${p.title} ${p.venue ?? ""}`.toLowerCase().includes(search.toLowerCase())
  );

  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">Browse Programs</h1>
          <p className="text-sm text-muted">Find a program and apply to volunteer.</p>
        </div>
        <div className="relative w-full sm:max-w-xs">
          <Search size={16} className="absolute left-3 top-1/2 -translate-y-1/2 text-muted" />
          <Input
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            placeholder="Search programs…"
            className="pl-9"
          />
        </div>
      </div>

      {filtered.length === 0 ? (
        <Card>
          <p className="px-5 py-12 text-center text-sm text-muted">No programs found.</p>
        </Card>
      ) : (
        <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
          {filtered.map((p) => {
            const status = appliedIds[p.id];
            const skills: string[] = (p.program_skills ?? [])
              .map((ps: any) => ps.skills?.name)
              .filter(Boolean);
            return (
              <Card key={p.id} className="flex flex-col p-5">
                <div className="mb-2 flex items-start justify-between gap-2">
                  <h2 className="font-bold text-ink">{p.title}</h2>
                  <Badge tone={statusTone(p.status)}>{p.status}</Badge>
                </div>
                <div className="space-y-1.5 text-sm text-muted">
                  <p className="flex items-center gap-2">
                    <CalendarDays size={14} /> {formatDate(p.start_at)}
                  </p>
                  <p className="flex items-center gap-2">
                    <MapPin size={14} /> {p.venue || "TBA"}
                  </p>
                  <p className="flex items-center gap-2">
                    <Users size={14} /> {p.slots ?? "—"} slots
                  </p>
                  <p className="flex items-center gap-2">
                    <Award size={14} /> {p.merit_value ?? 0} merit points
                  </p>
                </div>
                {skills.length > 0 && (
                  <div className="mt-3 flex flex-wrap gap-1.5">
                    {skills.map((s) => (
                      <span
                        key={s}
                        className="rounded-full bg-sand px-2.5 py-1 text-xs font-medium text-muted"
                      >
                        {s}
                      </span>
                    ))}
                  </div>
                )}
                <div className="mt-4 flex gap-2 pt-2">
                  <Button variant="secondary" size="sm" onClick={() => setDetail(p)}>
                    Details
                  </Button>
                  {status ? (
                    <Badge tone={statusTone(status)}>
                      {status === "pending" ? "Applied · pending" : status}
                    </Badge>
                  ) : (
                    <Button
                      size="sm"
                      disabled={p.status !== "open" || applying === p.id}
                      onClick={() => apply(p.id)}
                    >
                      {applying === p.id ? "Applying…" : "Apply"}
                    </Button>
                  )}
                </div>
              </Card>
            );
          })}
        </div>
      )}

      <Modal open={!!detail} onClose={() => setDetail(null)} title={detail?.title ?? ""}>
        {detail && (
          <div className="space-y-4">
            <div className="grid grid-cols-2 gap-3 text-sm">
              <Info label="Starts" value={formatDateTime(detail.start_at)} />
              <Info label="Ends" value={formatDateTime(detail.end_at)} />
              <Info label="Venue" value={detail.venue || "TBA"} />
              <Info label="Slots" value={String(detail.slots ?? "—")} />
              <Info label="Merit" value={`${detail.merit_value ?? 0} pts`} />
              <Info label="Status" value={detail.status} />
            </div>
            {detail.description && (
              <div>
                <p className="mb-1 text-sm font-semibold text-ink">About</p>
                <p className="text-sm text-muted">{detail.description}</p>
              </div>
            )}
            <div className="flex justify-end gap-2 pt-2">
              {appliedIds[detail.id] ? (
                <Badge tone={statusTone(appliedIds[detail.id])}>
                  Already applied · {appliedIds[detail.id]}
                </Badge>
              ) : (
                <Button
                  disabled={detail.status !== "open" || applying === detail.id}
                  onClick={() => apply(detail.id)}
                >
                  {applying === detail.id ? "Applying…" : "Apply to volunteer"}
                </Button>
              )}
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}

function Info({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-card bg-sand/40 px-3 py-2">
      <p className="text-xs text-muted">{label}</p>
      <p className="font-semibold capitalize text-ink">{value}</p>
    </div>
  );
}
