import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { getInstructorDesk, gradeSubmission, staffDecideCredit, updateAcademyAssignment } from "@/lib/server/api-academy";
import { creditLine, INSTRUCTOR_POWERS, STAFF_ONLY_POWERS } from "@/lib/coach-powers";
import { useRoleStore } from "@/lib/role-store";
import { formatDate } from "@/lib/utils";

export type EditableAssignment = {
  id: string;
  title: string;
  prompt: string;
  due_at: string | null;
  points: number;
  course_code?: string;
  course_title: string;
  instructor_name?: string | null;
};

export function AssignmentEditorList({
  items,
  onSaved,
}: {
  items: EditableAssignment[];
  onSaved?: () => void;
}) {
  const email = useRoleStore((s) => s.email);
  const role = useRoleStore((s) => s.role);
  const [edit, setEdit] = useState<EditableAssignment | null>(null);
  const [title, setTitle] = useState("");
  const [prompt, setPrompt] = useState("");
  const [due, setDue] = useState("");
  const [busy, setBusy] = useState(false);

  function open(a: EditableAssignment) {
    setEdit(a);
    setTitle(a.title);
    setPrompt(a.prompt);
    setDue(a.due_at ? a.due_at.slice(0, 10) : "");
  }

  async function save() {
    if (!edit) return;
    setBusy(true);
    try {
      await updateAcademyAssignment({
        data: { id: edit.id, title, prompt, due_at: due || undefined, email, role },
      });
      toast.success("Assignment updated. Students see the new prompt on their desk.");
      setEdit(null);
      onSaved?.();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not save the assignment.");
    } finally {
      setBusy(false);
    }
  }

  if (!items.length) {
    return <p className="text-sm text-muted-foreground">No assignments on the books yet.</p>;
  }

  return (
    <>
      <ul className="space-y-3">
        {items.map((a) => (
          <li key={a.id} className="rounded-lg bg-muted/60 px-3 py-3">
            <div className="flex flex-wrap items-start justify-between gap-2">
              <div>
                <p className="text-sm font-semibold">{a.title}</p>
                <p className="text-xs text-navy">
                  {a.course_code ? `${a.course_code} · ` : ""}
                  {a.course_title}
                  {a.instructor_name ? ` · assigned by ${a.instructor_name}` : ""}
                </p>
                <p className="mt-1 text-sm text-navy">{a.prompt}</p>
                <p className="mt-1 text-xs text-muted-foreground">
                  Due {a.due_at ? formatDate(a.due_at) : "—"} · {a.points} pts
                </p>
              </div>
              <Button size="sm" variant="gold" onClick={() => open(a)}>
                Edit assignment
              </Button>
            </div>
          </li>
        ))}
      </ul>
      <Dialog open={Boolean(edit)} onOpenChange={(o) => !o && setEdit(null)}>
        {edit ? (
          <DialogContent
            title="Edit assignment"
            description="Students see this prompt. Coaches and Super Admin can change it. The original student work is still theirs to submit."
          >
            <div className="space-y-3">
              <div>
                <Label htmlFor="asg-title">Title</Label>
                <Input id="asg-title" value={title} onChange={(e) => setTitle(e.target.value)} className="mt-1" />
              </div>
              <div>
                <Label htmlFor="asg-prompt">What the student must do</Label>
                <textarea
                  id="asg-prompt"
                  value={prompt}
                  onChange={(e) => setPrompt(e.target.value)}
                  rows={5}
                  className="mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
                />
              </div>
              <div>
                <Label htmlFor="asg-due">Due date</Label>
                <Input id="asg-due" type="date" value={due} onChange={(e) => setDue(e.target.value)} className="mt-1" />
              </div>
              <div className="flex justify-end gap-2">
                <Button variant="outline" onClick={() => setEdit(null)}>
                  Cancel
                </Button>
                <Button variant="gold" disabled={busy} onClick={() => void save()}>
                  {busy ? "Saving…" : "Save assignment"}
                </Button>
              </div>
            </div>
          </DialogContent>
        ) : null}
      </Dialog>
    </>
  );
}

export function StaffAcademyCard() {
  const email = useRoleStore((s) => s.email);
  const [desk, setDesk] = useState<Awaited<ReturnType<typeof getInstructorDesk>> | null>(null);
  const [busy, setBusy] = useState<string | null>(null);

  async function load() {
    setDesk(await getInstructorDesk({ data: { email } }));
  }

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

  async function decide(memberId: string, decision: "approved" | "returned") {
    setBusy(memberId);
    try {
      await staffDecideCredit({ data: { email, memberId, decision } });
      toast.success(decision === "approved" ? "Credit approved. Student and coach both see it." : "Returned to the coach.");
      await load();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not update credit.");
    } finally {
      setBusy(null);
    }
  }

  const pending = desk?.pendingCredits ?? [];

  return (
    <Card className="mb-6">
      <CardContent className="pt-5">
        <h2 className="font-display text-xl">Academy — Super Admin</h2>
        <p className="mt-1 mb-4 text-sm text-navy">
          Instructors own the students (roster, gradebook, recommendations). You own the institution (credit approval,
          grants, org profile). You can still override a grade or edit any assignment.
        </p>
        <div className="mb-5 grid gap-4 sm:grid-cols-2">
          <div>
            <p className="text-[11px] font-semibold tracking-[0.16em] text-gold-ink uppercase">Coach already can</p>
            <ul className="mt-2 list-disc space-y-1 pl-5 text-sm text-navy">
              {INSTRUCTOR_POWERS.map((p) => (
                <li key={p}>{p}</li>
              ))}
            </ul>
          </div>
          <div>
            <p className="text-[11px] font-semibold tracking-[0.16em] text-gold-ink uppercase">Only you</p>
            <ul className="mt-2 list-disc space-y-1 pl-5 text-sm text-navy">
              {STAFF_ONLY_POWERS.map((p) => (
                <li key={p}>{p}</li>
              ))}
            </ul>
          </div>
        </div>
        <h3 className="font-display text-lg">Credit waiting on you</h3>
        <p className="mt-1 mb-3 text-sm text-navy">
          Step 2 of 2. Coach recommended internship or college credit. Approve to attest, or return it. The registrar
          still posts the credit.
        </p>
        {pending.length === 0 ? (
          <p className="mb-4 text-sm text-navy">No credit recommendations in the queue.</p>
        ) : (
          <ul className="mb-5 space-y-3">
            {pending.map((m) => (
              <li key={m.id} className="rounded-lg bg-muted/60 px-3 py-3">
                <p className="text-sm font-semibold text-navy">{m.full_name}</p>
                <p className="text-sm text-navy">{creditLine(m.credit_status, m.credit_stage)}</p>
                {m.credit_note ? <p className="mt-1 text-xs text-navy">{m.credit_note}</p> : null}
                <div className="mt-2 flex flex-wrap gap-2">
                  <Button size="sm" variant="gold" disabled={busy === m.id} onClick={() => void decide(m.id, "approved")}>
                    Approve
                  </Button>
                  <Button size="sm" variant="outline" disabled={busy === m.id} onClick={() => void decide(m.id, "returned")}>
                    Return to coach
                  </Button>
                </div>
              </li>
            ))}
          </ul>
        )}
        <h3 className="mb-2 font-display text-lg">Gradebook override</h3>
        <p className="mb-3 text-sm text-navy">
          You can restage a grade the coach posted. The student sees the new number.
        </p>
        {desk ? <StaffGradeList email={email} items={desk.reviewQueue} onSaved={load} /> : null}
        <h3 className="mt-5 mb-2 font-display text-lg">Assignments you can edit</h3>
        {desk ? <AssignmentEditorList items={desk.assignments} onSaved={() => void load()} /> : <p className="text-sm">Loading…</p>}
      </CardContent>
    </Card>
  );
}

function StaffGradeList({
  email,
  items,
  onSaved,
}: {
  email: string;
  items: Awaited<ReturnType<typeof getInstructorDesk>>["reviewQueue"];
  onSaved: () => Promise<void>;
}) {
  const [open, setOpen] = useState<string | null>(null);
  const [score, setScore] = useState("90");
  const [note, setNote] = useState("");
  const [busy, setBusy] = useState(false);

  async function save(id: string) {
    setBusy(true);
    try {
      await gradeSubmission({ data: { email, submissionId: id, score: Number(score), feedback: note } });
      toast.success("Override posted to the student gradebook.");
      setOpen(null);
      await onSaved();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Could not post the grade.");
    } finally {
      setBusy(false);
    }
  }

  if (!items.length) return <p className="text-sm text-navy">No papers in the book.</p>;
  return (
    <ul className="mb-2 space-y-2">
      {items.map((s) => (
        <li key={s.id} className="rounded-lg bg-muted/60 px-3 py-3">
          <div className="flex flex-wrap items-start justify-between gap-2">
            <div>
              <p className="text-sm font-semibold text-navy">{s.title}</p>
              <p className="text-xs text-navy">
                {s.full_name} · {s.course_title}
                {s.status === "graded" ? ` · ${s.score}` : " · waiting"}
              </p>
            </div>
            <Button
              size="sm"
              variant="outline"
              onClick={() => {
                setOpen(open === s.id ? null : s.id);
                setScore(String(s.score ?? 90));
                setNote(s.feedback ?? "");
              }}
            >
              Override
            </Button>
          </div>
          {open === s.id ? (
            <div className="mt-2 flex flex-wrap gap-2">
              <Input className="w-20" value={score} onChange={(e) => setScore(e.target.value.replace(/[^\d]/g, ""))} />
              <Input className="min-w-[12rem] flex-1" value={note} onChange={(e) => setNote(e.target.value)} />
              <Button size="sm" variant="gold" disabled={busy} onClick={() => void save(s.id)}>
                Post
              </Button>
            </div>
          ) : null}
        </li>
      ))}
    </ul>
  );
}
