"use client";

import Link from "next/link";
import { useCallback, useEffect, useMemo, useState } from "react";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { Field, Input, Select, Textarea } from "@/components/ui/Field";
import { PageContentSkeleton } from "@/components/ui/Skeleton";
import { SubmissionContentViewer } from "@/components/teacher/SubmissionContentViewer";
import { ApiError, apiGet, apiPatch, apiPost } from "@/lib/api";

interface FeedbackBrief {
  comment?: string | null;
  score?: number | string | null;
  returned_for_revision?: boolean;
  revision_deadline?: string | null;
  full_score_override?: boolean;
}

export interface SubmissionBrief {
  id: number;
  assignment_step_id?: number | null;
  status: string;
  score?: number | string | null;
  content?: string | null;
  file_path?: string | null;
  payload?: Record<string, unknown> | null;
  is_late?: boolean;
  submitted_at?: string | null;
  feedback?: FeedbackBrief | null;
  user?: { id: number; name: string } | null;
  step?: {
    id: number;
    title: string;
    max_score?: number | string | null;
    late_penalty_percent?: number;
  } | null;
}

interface SubmissionRow {
  enrollment_id: number;
  student_code?: string | null;
  first_name?: string | null;
  last_name?: string | null;
  submission?: SubmissionBrief | null;
  step_submissions?: SubmissionBrief[];
}

interface AssignmentStepBrief {
  id: number;
  title: string;
  step_type: string;
  auto_check: boolean;
  max_score?: number | string | null;
  late_penalty_percent?: number;
}

interface SubmissionsPayload {
  assignment: {
    id: number;
    title: string;
    max_score?: number | string | null;
    allow_late_submission?: boolean;
    late_penalty_percent?: number;
  };
  steps: AssignmentStepBrief[];
  students: SubmissionRow[];
  grading_queue: SubmissionBrief[];
}

function studentName(row: SubmissionRow): string {
  const parts = [row.first_name, row.last_name].filter(Boolean);
  return parts.length ? parts.join(" ") : row.student_code ?? `#${row.enrollment_id}`;
}

function formatDate(value?: string | null): string {
  if (!value) return "—";
  try {
    return new Date(value).toLocaleString("fa-IR");
  } catch {
    return value;
  }
}

function statusLabelFa(status?: string | null): string {
  switch (status) {
    case "graded":
      return "نمره‌دهی شده";
    case "submitted":
      return "ارسال شده";
    case "resubmitted":
      return "ارسال مجدد";
    case "returned":
      return "عودت برای اصلاح";
    case "completed":
      return "تکمیل شده";
    case "draft":
      return "پیش‌نویس";
    default:
      return status ? status : "ارسال نشده";
  }
}

function flattenSubmissions(data: SubmissionsPayload | null): SubmissionBrief[] {
  if (!data) return [];
  const fromStudents = data.students.flatMap((r) =>
    r.step_submissions?.length ? r.step_submissions : r.submission ? [r.submission] : [],
  );
  const map = new Map<number, SubmissionBrief>();
  [...(data.grading_queue ?? []), ...fromStudents].forEach((s) => map.set(s.id, s));
  return Array.from(map.values());
}

function findStudentForSubmission(data: SubmissionsPayload | null, subId: number): SubmissionRow | null {
  if (!data) return null;
  return (
    data.students.find((row) =>
      (row.step_submissions ?? []).some((s) => s.id === subId) || row.submission?.id === subId,
    ) ?? null
  );
}

export function AssignmentGradingWorkspace({
  assignmentId,
  initialSubmissionId,
  backHref,
}: {
  assignmentId: number;
  classRoomId: number;
  initialSubmissionId?: number | null;
  backHref: string;
}) {
  const [data, setData] = useState<SubmissionsPayload | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedId, setSelectedId] = useState<number | null>(initialSubmissionId ?? null);
  const [sidebarTab, setSidebarTab] = useState<"queue" | "all">("queue");
  const [stepFilter, setStepFilter] = useState<string>("all");
  const [search, setSearch] = useState("");
  const [scores, setScores] = useState<Record<number, string>>({});
  const [comments, setComments] = useState<Record<number, string>>({});
  const [overrides, setOverrides] = useState<Record<number, boolean>>({});
  const [revisionHours, setRevisionHours] = useState<Record<number, string>>({});
  const [saving, setSaving] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const payload = await apiGet<SubmissionsPayload>(
        `/assignments/${assignmentId}/submissions`,
      );
      setData(payload);

      const initialScores: Record<number, string> = {};
      const initialComments: Record<number, string> = {};
      const initialHours: Record<number, string> = {};
      const initialOverrides: Record<number, boolean> = {};
      flattenSubmissions(payload).forEach((sub) => {
        if (sub.score != null) initialScores[sub.id] = String(sub.score);
        if (sub.feedback?.comment) initialComments[sub.id] = sub.feedback.comment;
        if (sub.feedback?.full_score_override) initialOverrides[sub.id] = true;
        initialHours[sub.id] = "24";
      });
      setScores(initialScores);
      setComments(initialComments);
      setOverrides(initialOverrides);
      setRevisionHours(initialHours);

      setSelectedId((prev) => {
        if (prev && flattenSubmissions(payload).some((s) => s.id === prev)) return prev;
        if (initialSubmissionId && flattenSubmissions(payload).some((s) => s.id === initialSubmissionId)) {
          return initialSubmissionId;
        }
        return payload.grading_queue[0]?.id ?? flattenSubmissions(payload)[0]?.id ?? null;
      });
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در بارگذاری");
    } finally {
      setLoading(false);
    }
  }, [assignmentId, initialSubmissionId]);

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

  const allSubs = useMemo(() => flattenSubmissions(data), [data]);

  const queueIds = useMemo(
    () => new Set((data?.grading_queue ?? []).map((s) => s.id)),
    [data],
  );

  const sidebarItems = useMemo(() => {
    let items = sidebarTab === "queue" ? (data?.grading_queue ?? []) : allSubs;
    if (stepFilter !== "all") {
      items = items.filter((s) => String(s.assignment_step_id ?? s.step?.id) === stepFilter);
    }
    if (search.trim()) {
      const q = search.trim().toLowerCase();
      items = items.filter((sub) => {
        const row = findStudentForSubmission(data, sub.id);
        const name = row ? studentName(row).toLowerCase() : (sub.user?.name ?? "").toLowerCase();
        return name.includes(q) || (sub.step?.title ?? "").toLowerCase().includes(q);
      });
    }
    return items;
  }, [allSubs, data, queueIds, search, sidebarTab, stepFilter]);

  const selected = allSubs.find((s) => s.id === selectedId) ?? null;
  const selectedStudent = selected ? findStudentForSubmission(data, selected.id) : null;
  const maxScore = Number(data?.assignment.max_score ?? 20);
  const stepMax = Number(selected?.step?.max_score ?? maxScore);
  const penalty = selected?.step?.late_penalty_percent ?? 0;
  const canGrade = selected
    ? ["submitted", "resubmitted", "returned", "graded"].includes(selected.status)
    : false;

  const navigableQueue = sidebarItems;
  const currentIndex = selected ? navigableQueue.findIndex((s) => s.id === selected.id) : -1;

  const goTo = (sub: SubmissionBrief) => {
    setSelectedId(sub.id);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const goPrev = () => {
    if (currentIndex > 0) goTo(navigableQueue[currentIndex - 1]);
  };

  const goNext = () => {
    if (currentIndex >= 0 && currentIndex < navigableQueue.length - 1) {
      goTo(navigableQueue[currentIndex + 1]);
    }
  };

  const grade = async () => {
    if (!selected) return;
    const raw = scores[selected.id];
    if (raw === undefined || raw === "") return;
    setSaving(true);
    setError(null);
    try {
      await apiPatch(`/assignment-submissions/${selected.id}/grade`, {
        score: Number(raw),
        comment: comments[selected.id]?.trim() || null,
        full_score_override: Boolean(overrides[selected.id]),
      });
      await load();
      if (currentIndex >= 0 && currentIndex < navigableQueue.length - 1) {
        goTo(navigableQueue[currentIndex + 1]);
      }
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در ثبت نمره");
    } finally {
      setSaving(false);
    }
  };

  const returnForRevision = async () => {
    if (!selected) return;
    setSaving(true);
    setError(null);
    try {
      await apiPost(`/assignment-submissions/${selected.id}/return-for-revision`, {
        hours: Number(revisionHours[selected.id] || 24),
        comment: comments[selected.id]?.trim() || null,
      });
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در عودت");
    } finally {
      setSaving(false);
    }
  };

  if (loading) return <PageContentSkeleton rows={8} />;

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <Link href={backHref} className="text-sm text-teal-700 hover:underline">
            ← بازگشت به تکالیف
          </Link>
          <h1 className="mt-1 text-xl font-bold">{data?.assignment.title ?? "تصحیح تکلیف"}</h1>
          <p className="mt-1 text-sm text-[var(--muted)]">
            {data?.steps.length ?? 0} مرحله · صف تصحیح: {data?.grading_queue.length ?? 0} · کل ارسال‌ها:{" "}
            {allSubs.length}
          </p>
        </div>
        <div className="flex flex-wrap gap-2">
          <span className="rounded-lg bg-amber-50 px-3 py-1.5 text-sm text-amber-800">
            {data?.grading_queue.length ?? 0} در انتظار تصحیح
          </span>
          <span className="rounded-lg bg-emerald-50 px-3 py-1.5 text-sm text-emerald-800">
            {allSubs.filter((s) => s.status === "graded").length} تصحیح‌شده
          </span>
        </div>
      </div>

      {error ? <Alert tone="error">{error}</Alert> : null}

      <div className="grid gap-4 lg:grid-cols-[300px_1fr]">
        <aside className="space-y-3 rounded-2xl border border-[var(--border)] bg-white p-3 lg:sticky lg:top-28 lg:max-h-[calc(100vh-8rem)] lg:overflow-y-auto">
          <div className="flex gap-1 rounded-lg bg-slate-100 p-1">
            <button
              type="button"
              onClick={() => setSidebarTab("queue")}
              className={`flex-1 rounded-md px-2 py-1.5 text-xs font-medium ${
                sidebarTab === "queue" ? "bg-white text-teal-800 shadow-sm" : "text-slate-600"
              }`}
            >
              صف ({data?.grading_queue.length ?? 0})
            </button>
            <button
              type="button"
              onClick={() => setSidebarTab("all")}
              className={`flex-1 rounded-md px-2 py-1.5 text-xs font-medium ${
                sidebarTab === "all" ? "bg-white text-teal-800 shadow-sm" : "text-slate-600"
              }`}
            >
              همه ({allSubs.length})
            </button>
          </div>

          <Input
            placeholder="جستجوی دانش‌آموز…"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="text-sm"
          />

          {(data?.steps.length ?? 0) > 1 ? (
            <Select value={stepFilter} onChange={(e) => setStepFilter(e.target.value)} className="text-sm">
              <option value="all">همه مراحل</option>
              {data?.steps.map((step) => (
                <option key={step.id} value={String(step.id)}>
                  {step.title}
                </option>
              ))}
            </Select>
          ) : null}

          <ul className="space-y-1">
            {sidebarItems.length === 0 ? (
              <li className="px-2 py-4 text-center text-xs text-[var(--muted)]">موردی یافت نشد.</li>
            ) : (
              sidebarItems.map((sub) => {
                const row = findStudentForSubmission(data, sub.id);
                const name = row ? studentName(row) : sub.user?.name ?? `#${sub.id}`;
                const active = sub.id === selectedId;
                return (
                  <li key={sub.id}>
                    <button
                      type="button"
                      onClick={() => goTo(sub)}
                      className={`w-full rounded-xl px-3 py-2.5 text-right transition ${
                        active ? "bg-teal-50 ring-1 ring-teal-200" : "hover:bg-slate-50"
                      }`}
                    >
                      <div className="font-semibold text-sm text-slate-800">{name}</div>
                      <div className="mt-0.5 text-xs text-slate-500">
                        {sub.step?.title ?? "—"} · {statusLabelFa(sub.status)}
                        {sub.score != null ? ` · ${sub.score}` : ""}
                      </div>
                      {queueIds.has(sub.id) ? (
                        <span className="mt-1 inline-block rounded bg-amber-100 px-1.5 py-0.5 text-[10px] text-amber-800">
                          نیازمند تصحیح
                        </span>
                      ) : null}
                    </button>
                  </li>
                );
              })
            )}
          </ul>
        </aside>

        <main className="min-w-0 space-y-4">
          {!selected ? (
            <div className="rounded-2xl border border-dashed border-[var(--border)] bg-white p-10 text-center text-sm text-[var(--muted)]">
              یک ارسال از فهرست انتخاب کنید.
            </div>
          ) : (
            <>
              <div className="rounded-2xl border border-[var(--border)] bg-white p-4">
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div>
                    <h2 className="text-lg font-bold">
                      {selectedStudent ? studentName(selectedStudent) : selected.user?.name ?? "دانش‌آموز"}
                    </h2>
                    <p className="mt-1 text-sm text-[var(--muted)]">
                      مرحله: {selected.step?.title ?? "—"} · {statusLabelFa(selected.status)} ·{" "}
                      {formatDate(selected.submitted_at)}
                    </p>
                  </div>
                  <div className="flex flex-wrap gap-2 text-xs">
                    <span className="rounded-lg bg-slate-100 px-2 py-1">بارم: {stepMax}</span>
                    {selected.is_late ? (
                      <span className="rounded-lg bg-amber-100 px-2 py-1 text-amber-800">تأخیر</span>
                    ) : null}
                    {selected.score != null ? (
                      <span className="rounded-lg bg-emerald-100 px-2 py-1 text-emerald-800">
                        نمره: {selected.score}
                      </span>
                    ) : null}
                  </div>
                </div>
              </div>

              <div className="rounded-2xl border border-[var(--border)] bg-slate-50/50 p-4">
                <SubmissionContentViewer
                  submissionId={selected.id}
                  content={selected.content}
                  filePath={selected.file_path}
                  payload={selected.payload}
                  feedback={selected.feedback}
                  submittedAt={selected.submitted_at}
                  isLate={selected.is_late}
                  status={statusLabelFa(selected.status)}
                />
              </div>

              {canGrade ? (
                <div className="rounded-2xl border border-[var(--border)] bg-white p-4">
                  <h3 className="mb-3 font-bold">تصحیح و بازخورد</h3>

                  {selected.is_late && penalty > 0 ? (
                    <Alert tone="warning">
                      ارسال با تأخیر — {penalty}٪ از نمره کسر می‌شود. برای نمره کامل، گزینه زیر را بزنید.
                    </Alert>
                  ) : null}

                  <div className="mt-3 space-y-3">
                    <div className="flex flex-wrap items-end gap-3">
                      <Field label={`نمره (از ${stepMax})`}>
                        <Input
                          type="number"
                          min={0}
                          max={stepMax}
                          className="max-w-[120px]"
                          value={scores[selected.id] ?? ""}
                          onChange={(e) =>
                            setScores((prev) => ({ ...prev, [selected.id]: e.target.value }))
                          }
                        />
                      </Field>
                      {selected.is_late ? (
                        <label className="mb-2 flex items-center gap-2 text-sm">
                          <input
                            type="checkbox"
                            checked={Boolean(overrides[selected.id])}
                            onChange={(e) =>
                              setOverrides((prev) => ({ ...prev, [selected.id]: e.target.checked }))
                            }
                          />
                          نمره کامل (نادیده گرفتن جریمه)
                        </label>
                      ) : null}
                    </div>

                    <Field label="توضیح / بازخورد">
                      <Textarea
                        rows={4}
                        value={comments[selected.id] ?? ""}
                        onChange={(e) =>
                          setComments((prev) => ({ ...prev, [selected.id]: e.target.value }))
                        }
                        placeholder="نکات تصحیح، توضیحات یا راهنمایی برای دانش‌آموز…"
                      />
                    </Field>

                    <div className="flex flex-wrap items-end gap-2">
                      <Button onClick={() => void grade()} loading={saving}>
                        ثبت نمره
                      </Button>
                      {["submitted", "resubmitted"].includes(selected.status) ? (
                        <>
                          <Field label="مهلت اصلاح (ساعت)">
                            <Input
                              type="number"
                              min={1}
                              max={168}
                              className="max-w-[88px]"
                              value={revisionHours[selected.id] ?? "24"}
                              onChange={(e) =>
                                setRevisionHours((prev) => ({
                                  ...prev,
                                  [selected.id]: e.target.value,
                                }))
                              }
                            />
                          </Field>
                          <Button variant="secondary" onClick={() => void returnForRevision()} loading={saving}>
                            عودت برای اصلاح
                          </Button>
                        </>
                      ) : null}
                    </div>
                  </div>
                </div>
              ) : null}

              <div className="flex flex-wrap justify-between gap-2">
                <Button variant="secondary" onClick={goPrev} disabled={currentIndex <= 0}>
                  ← قبلی
                </Button>
                <span className="self-center text-xs text-[var(--muted)]">
                  {currentIndex >= 0 ? `${currentIndex + 1} از ${navigableQueue.length}` : ""}
                </span>
                <Button variant="secondary" onClick={goNext} disabled={currentIndex >= navigableQueue.length - 1}>
                  بعدی →
                </Button>
              </div>
            </>
          )}
        </main>
      </div>
    </div>
  );
}
