"use client";

import { useState, useTransition } from "react";

type AdminUser = {
  id: string;
  discordId: string;
  user?: {
    name?: string | null;
    email?: string | null;
    discordUsername?: string | null;
  } | null;
};

type Grade = {
  id: string;
  name: string;
  price: number;
  description: string;
};

type Event = {
  id: string;
  title: string;
  description: string;
  eventDate: string;
};

type AdminDashboardProps = {
  initialAdmins: AdminUser[];
  initialGrades: Grade[];
  initialEvents: Event[];
};

const requestJson = async <T,>(
  url: string,
  options: RequestInit
): Promise<T> => {
  const res = await fetch(url, {
    headers: { "Content-Type": "application/json" },
    ...options,
  });
  const data = (await res.json().catch(() => ({}))) as T & {
    error?: string;
  };

  if (!res.ok) {
    throw new Error(data.error ?? "Request failed");
  }

  return data;
};

const toInputDate = (iso: string) => {
  return new Date(iso).toISOString().slice(0, 16);
};

export default function AdminDashboard({
  initialAdmins,
  initialGrades,
  initialEvents,
}: AdminDashboardProps) {
  const [admins, setAdmins] = useState<AdminUser[]>(initialAdmins);
  const [grades, setGrades] = useState<Grade[]>(initialGrades);
  const [events, setEvents] = useState<Event[]>(initialEvents);
  const [notice, setNotice] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();

  const handleAddAdmin = (form: FormData) => {
    const discordId = form.get("discordId")?.toString().trim();
    if (!discordId) return;

    startTransition(async () => {
      try {
        const admin = await requestJson<AdminUser>("/api/admin/admins", {
          method: "POST",
          body: JSON.stringify({ discordId }),
        });
        setAdmins((prev) => [admin, ...prev]);
        setNotice("Admin added");
      } catch (error) {
        setNotice((error as Error).message);
      }
    });
  };

  const handleAddGrade = (form: FormData) => {
    const name = form.get("name")?.toString().trim();
    const price = Number(form.get("price"));
    const description = form.get("description")?.toString().trim();

    if (!name || Number.isNaN(price) || !description) return;

    startTransition(async () => {
      try {
        const grade = await requestJson<Grade>("/api/admin/grades", {
          method: "POST",
          body: JSON.stringify({ name, price, description }),
        });
        setGrades((prev) => [...prev, grade]);
        setNotice("Grade added");
      } catch (error) {
        setNotice((error as Error).message);
      }
    });
  };

  const handleAddEvent = (form: FormData) => {
    const title = form.get("title")?.toString().trim();
    const description = form.get("description")?.toString().trim();
    const eventDate = form.get("eventDate")?.toString();

    if (!title || !description || !eventDate) return;

    startTransition(async () => {
      try {
        const event = await requestJson<Event>("/api/admin/events", {
          method: "POST",
          body: JSON.stringify({
            title,
            description,
            eventDate: new Date(eventDate).toISOString(),
          }),
        });
        setEvents((prev) => [...prev, event]);
        setNotice("Event added");
      } catch (error) {
        setNotice((error as Error).message);
      }
    });
  };

  return (
    <div className="space-y-10">
      <div className="rounded-3xl border border-white/10 bg-white/5 p-6 backdrop-blur">
        <h2 className="text-lg font-semibold text-white">Admin access</h2>
        <p className="mt-2 text-sm text-slate-300">
          Manage admins, grades, and events. Changes are applied live.
        </p>
        {notice ? (
          <div className="mt-4 rounded-2xl border border-white/10 bg-white/10 px-4 py-3 text-xs text-cyan-200">
            {notice}
          </div>
        ) : null}
      </div>

      <section className="grid gap-6 lg:grid-cols-[1.1fr_0.9fr]">
        <div className="rounded-3xl border border-white/10 bg-white/5 p-6 backdrop-blur">
          <h3 className="text-base font-semibold text-white">Admins</h3>
          <form
            onSubmit={(event) => {
              event.preventDefault();
              handleAddAdmin(new FormData(event.currentTarget));
              event.currentTarget.reset();
            }}
            className="mt-4 flex flex-col gap-3 md:flex-row"
          >
            <input
              name="discordId"
              placeholder="Discord ID"
              className="flex-1 rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <button
              type="submit"
              className="rounded-2xl border border-white/10 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-white"
              disabled={isPending}
            >
              Add admin
            </button>
          </form>
          <div className="mt-4 space-y-3">
            {admins.map((admin) => (
              <AdminRow
                key={admin.id}
                admin={admin}
                onDelete={(id) =>
                  setAdmins((prev) => prev.filter((item) => item.id !== id))
                }
              />
            ))}
          </div>
        </div>
        <div className="rounded-3xl border border-white/10 bg-white/5 p-6 backdrop-blur">
          <h3 className="text-base font-semibold text-white">Create grade</h3>
          <form
            onSubmit={(event) => {
              event.preventDefault();
              handleAddGrade(new FormData(event.currentTarget));
              event.currentTarget.reset();
            }}
            className="mt-4 space-y-3"
          >
            <input
              name="name"
              placeholder="Name"
              className="w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <input
              name="price"
              type="number"
              placeholder="Price"
              className="w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <textarea
              name="description"
              placeholder="Description"
              className="min-h-30 w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <button
              type="submit"
              className="w-full rounded-2xl border border-white/10 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-white"
              disabled={isPending}
            >
              Add grade
            </button>
          </form>
        </div>
      </section>

      <section className="rounded-3xl border border-white/10 bg-white/5 p-6 backdrop-blur">
        <h3 className="text-base font-semibold text-white">Grades</h3>
        <div className="mt-4 space-y-4">
          {grades.map((grade) => (
            <GradeRow
              key={grade.id}
              grade={grade}
              onUpdate={(updated) =>
                setGrades((prev) =>
                  prev.map((item) =>
                    item.id === updated.id ? updated : item
                  )
                )
              }
              onDelete={(id) =>
                setGrades((prev) => prev.filter((item) => item.id !== id))
              }
            />
          ))}
        </div>
      </section>

      <section className="grid gap-6 lg:grid-cols-[1fr_1.1fr]">
        <div className="rounded-3xl border border-white/10 bg-white/5 p-6 backdrop-blur">
          <h3 className="text-base font-semibold text-white">Create event</h3>
          <form
            onSubmit={(event) => {
              event.preventDefault();
              handleAddEvent(new FormData(event.currentTarget));
              event.currentTarget.reset();
            }}
            className="mt-4 space-y-3"
          >
            <input
              name="title"
              placeholder="Title"
              className="w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <input
              name="eventDate"
              type="datetime-local"
              className="w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <textarea
              name="description"
              placeholder="Description"
              className="min-h-30 w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
            />
            <button
              type="submit"
              className="w-full rounded-2xl border border-white/10 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-white"
              disabled={isPending}
            >
              Add event
            </button>
          </form>
        </div>
        <div className="rounded-3xl border border-white/10 bg-white/5 p-6 backdrop-blur">
          <h3 className="text-base font-semibold text-white">Events</h3>
          <div className="mt-4 space-y-4">
            {events.map((event) => (
              <EventRow
                key={event.id}
                event={event}
                onUpdate={(updated) =>
                  setEvents((prev) =>
                    prev.map((item) =>
                      item.id === updated.id ? updated : item
                    )
                  )
                }
                onDelete={(id) =>
                  setEvents((prev) => prev.filter((item) => item.id !== id))
                }
              />
            ))}
          </div>
        </div>
      </section>
    </div>
  );
}

function AdminRow({
  admin,
  onDelete,
}: {
  admin: AdminUser;
  onDelete: (id: string) => void;
}) {
  const [isPending, startTransition] = useTransition();

  const handleDelete = () => {
    startTransition(async () => {
      try {
        await requestJson<{ ok: boolean }>(`/api/admin/admins/${admin.id}`, {
          method: "DELETE",
        });
        onDelete(admin.id);
      } catch {
        // no-op
      }
    });
  };

  return (
    <div className="flex flex-col gap-3 rounded-2xl border border-white/10 bg-slate-950/40 p-4 md:flex-row md:items-center md:justify-between">
      <div>
        <p className="text-sm font-semibold text-white">
          {admin.user?.discordUsername ?? admin.user?.name ?? "Unknown"}
        </p>
        <p className="text-xs text-slate-400">{admin.discordId}</p>
      </div>
      <button
        type="button"
        onClick={handleDelete}
        className="rounded-full border border-white/10 px-3 py-1 text-[10px] uppercase tracking-[0.3em] text-white/80"
        disabled={isPending}
      >
        Remove
      </button>
    </div>
  );
}

function GradeRow({
  grade,
  onUpdate,
  onDelete,
}: {
  grade: Grade;
  onUpdate: (grade: Grade) => void;
  onDelete: (id: string) => void;
}) {
  const [draft, setDraft] = useState(grade);
  const [isPending, startTransition] = useTransition();

  const handleSave = () => {
    startTransition(async () => {
      try {
        const updated = await requestJson<Grade>(
          `/api/admin/grades/${grade.id}`,
          {
            method: "PATCH",
            body: JSON.stringify({
              name: draft.name,
              price: draft.price,
              description: draft.description,
            }),
          }
        );
        onUpdate(updated);
      } catch {
        // no-op
      }
    });
  };

  const handleDelete = () => {
    startTransition(async () => {
      try {
        await requestJson<{ ok: boolean }>(`/api/admin/grades/${grade.id}`, {
          method: "DELETE",
        });
        onDelete(grade.id);
      } catch {
        // no-op
      }
    });
  };

  return (
    <div className="rounded-2xl border border-white/10 bg-slate-950/40 p-4">
      <div className="grid gap-3 md:grid-cols-[1fr_160px]">
        <input
          value={draft.name}
          onChange={(event) =>
            setDraft((prev) => ({ ...prev, name: event.target.value }))
          }
          className="rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
        />
        <input
          type="number"
          value={draft.price}
          onChange={(event) =>
            setDraft((prev) => ({
              ...prev,
              price: Number(event.target.value),
            }))
          }
          className="rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
        />
      </div>
      <textarea
        value={draft.description}
        onChange={(event) =>
          setDraft((prev) => ({ ...prev, description: event.target.value }))
        }
        className="mt-3 min-h-25 w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
      />
      <div className="mt-3 flex flex-wrap gap-3">
        <button
          type="button"
          onClick={handleSave}
          className="rounded-full border border-white/10 px-3 py-1 text-[10px] uppercase tracking-[0.3em] text-white/80"
          disabled={isPending}
        >
          Save
        </button>
        <button
          type="button"
          onClick={handleDelete}
          className="rounded-full border border-white/10 px-3 py-1 text-[10px] uppercase tracking-[0.3em] text-white/80"
          disabled={isPending}
        >
          Delete
        </button>
      </div>
    </div>
  );
}

function EventRow({
  event,
  onUpdate,
  onDelete,
}: {
  event: Event;
  onUpdate: (event: Event) => void;
  onDelete: (id: string) => void;
}) {
  const [draft, setDraft] = useState({
    ...event,
    eventDate: toInputDate(event.eventDate),
  });
  const [isPending, startTransition] = useTransition();

  const handleSave = () => {
    startTransition(async () => {
      try {
        const updated = await requestJson<Event>(
          `/api/admin/events/${event.id}`,
          {
            method: "PATCH",
            body: JSON.stringify({
              title: draft.title,
              description: draft.description,
              eventDate: new Date(draft.eventDate).toISOString(),
            }),
          }
        );
        onUpdate(updated);
      } catch {
        // no-op
      }
    });
  };

  const handleDelete = () => {
    startTransition(async () => {
      try {
        await requestJson<{ ok: boolean }>(`/api/admin/events/${event.id}`, {
          method: "DELETE",
        });
        onDelete(event.id);
      } catch {
        // no-op
      }
    });
  };

  return (
    <div className="rounded-2xl border border-white/10 bg-slate-950/40 p-4">
      <input
        value={draft.title}
        onChange={(eventValue) =>
          setDraft((prev) => ({ ...prev, title: eventValue.target.value }))
        }
        className="w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
      />
      <input
        type="datetime-local"
        value={draft.eventDate}
        onChange={(eventValue) =>
          setDraft((prev) => ({ ...prev, eventDate: eventValue.target.value }))
        }
        className="mt-3 w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
      />
      <textarea
        value={draft.description}
        onChange={(eventValue) =>
          setDraft((prev) => ({ ...prev, description: eventValue.target.value }))
        }
        className="mt-3 min-h-25 w-full rounded-2xl border border-white/10 bg-slate-950/60 px-4 py-2 text-sm text-white"
      />
      <div className="mt-3 flex flex-wrap gap-3">
        <button
          type="button"
          onClick={handleSave}
          className="rounded-full border border-white/10 px-3 py-1 text-[10px] uppercase tracking-[0.3em] text-white/80"
          disabled={isPending}
        >
          Save
        </button>
        <button
          type="button"
          onClick={handleDelete}
          className="rounded-full border border-white/10 px-3 py-1 text-[10px] uppercase tracking-[0.3em] text-white/80"
          disabled={isPending}
        >
          Delete
        </button>
      </div>
    </div>
  );
}
