"use client";

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

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

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 : "ارسال نشده";
  }
}

export function AssignmentSubmissionsPanel({
  open,
  assignmentId,
  classRoomId,
  queryString = "",
  onClose,
  onGraded,
}: {
  open: boolean;
  assignmentId: number | null;
  classRoomId?: number;
  queryString?: string;
  onClose: () => void;
  onGraded: () => void;
}) {
  const [data, setData] = useState<SubmissionsPayload | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  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 [savingId, setSavingId] = useState<number | null>(null);
  const [tab, setTab] = useState<"queue" | "students">("queue");
  const [selectedSubId, setSelectedSubId] = useState<number | null>(null);

  const load = useCallback(async () => {
    if (!assignmentId) return;
    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> = {};
      [...(payload.grading_queue ?? []), ...(payload.students.flatMap((s) => s.step_submissions ?? []) )].forEach(
        (sub) => {
          if (sub.score != null) initialScores[sub.id] = String(sub.score);
          if (sub.feedback?.comment) initialComments[sub.id] = sub.feedback.comment;
          initialHours[sub.id] = "24";
        },
      );
      setScores(initialScores);
      setComments(initialComments);
      setRevisionHours(initialHours);
      setTab((payload.grading_queue?.length ?? 0) > 0 ? "queue" : "students");
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در بارگذاری");
    } finally {
      setLoading(false);
    }
  }, [assignmentId]);

  useEffect(() => {
    if (open && assignmentId) {
      void load();
    }
  }, [open, assignmentId, load]);

  if (!open) return null;

  const maxScore = Number(data?.assignment.max_score ?? 20);

  const grade = async (sub: SubmissionBrief) => {
    const raw = scores[sub.id];
    if (raw === undefined || raw === "") return;
    setSavingId(sub.id);
    setError(null);
    try {
      await apiPatch(`/assignment-submissions/${sub.id}/grade`, {
        score: Number(raw),
        comment: comments[sub.id]?.trim() || null,
        full_score_override: Boolean(overrides[sub.id]),
      });
      onGraded();
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در ثبت نمره");
    } finally {
      setSavingId(null);
    }
  };

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

  const renderGradeControls = (sub: SubmissionBrief) => {
    const stepMax = Number(sub.step?.max_score ?? maxScore);
    const penalty = sub.step?.late_penalty_percent ?? 0;
    const canGrade = ["submitted", "resubmitted", "returned", "graded"].includes(sub.status);

    return (
      <div className="space-y-2 rounded-xl border border-[var(--border)] bg-slate-50/80 p-3">
        {sub.is_late && penalty > 0 ? (
          <Alert tone="warning">
            ارسال با تأخیر — {penalty}٪ از نمره کسر می‌شود. برای نمره کامل، گزینه زیر را بزنید.
          </Alert>
        ) : null}
        <SubmissionContentViewer
          submissionId={sub.id}
          content={sub.content}
          filePath={sub.file_path}
          payload={sub.payload}
          feedback={sub.feedback}
          submittedAt={sub.submitted_at}
          isLate={sub.is_late}
          status={statusLabelFa(sub.status)}
          compact
        />
        {canGrade ? (
          <>
            <div className="flex flex-wrap items-end gap-2">
              <Field label={`نمره (از ${stepMax})`}>
                <Input
                  type="number"
                  min={0}
                  max={stepMax}
                  className="max-w-[100px]"
                  value={scores[sub.id] ?? ""}
                  onChange={(e) =>
                    setScores((prev) => ({ ...prev, [sub.id]: e.target.value }))
                  }
                />
              </Field>
              {sub.is_late ? (
                <label className="mb-2 flex items-center gap-2 text-sm">
                  <input
                    type="checkbox"
                    checked={Boolean(overrides[sub.id])}
                    onChange={(e) =>
                      setOverrides((prev) => ({ ...prev, [sub.id]: e.target.checked }))
                    }
                  />
                  نمره کامل (نادیده گرفتن جریمه)
                </label>
              ) : null}
            </div>
            <Field label="توضیح / بازخورد">
              <Textarea
                rows={2}
                value={comments[sub.id] ?? ""}
                onChange={(e) =>
                  setComments((prev) => ({ ...prev, [sub.id]: e.target.value }))
                }
              />
            </Field>
            <div className="flex flex-wrap items-end gap-2">
              <Button
                className="text-sm"
                loading={savingId === sub.id}
                onClick={() => grade(sub)}
                disabled={sub.status === "graded" && !scores[sub.id]}
              >
                ثبت نمره
              </Button>
              {["submitted", "resubmitted"].includes(sub.status) ? (
                <>
                  <Field label="مهلت اصلاح (ساعت)">
                    <Input
                      type="number"
                      min={1}
                      max={168}
                      className="max-w-[88px]"
                      value={revisionHours[sub.id] ?? "24"}
                      onChange={(e) =>
                        setRevisionHours((prev) => ({ ...prev, [sub.id]: e.target.value }))
                      }
                    />
                  </Field>
                  <Button
                    variant="secondary"
                    className="text-sm"
                    loading={savingId === sub.id}
                    onClick={() => returnForRevision(sub)}
                  >
                    عودت برای اصلاح
                  </Button>
                </>
              ) : null}
            </div>
          </>
        ) : null}
      </div>
    );
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
      <div
        role="dialog"
        aria-modal="true"
        className="flex max-h-[90vh] w-full max-w-4xl flex-col rounded-2xl border border-[var(--border)] bg-white shadow-xl"
      >
        <div className="flex items-start justify-between border-b border-[var(--border)] p-5">
          <div>
            <h3 className="text-lg font-bold">مطالب ارسالی و تصحیح</h3>
            <p className="mt-1 text-sm text-[var(--muted)]">{data?.assignment.title}</p>
            {classRoomId && assignmentId ? (
              <Link
                href={`/teacher/classes/${classRoomId}/assignments/${assignmentId}/grading${queryString}`}
                className="mt-2 inline-flex text-sm font-medium text-teal-700 hover:underline"
              >
                باز کردن صفحه کامل تصحیح ←
              </Link>
            ) : null}
            {data?.steps?.length ? (
              <p className="mt-1 text-xs text-[var(--muted)]">
                {data.steps.length} مرحله · صف تصحیح: {data.grading_queue?.length ?? 0}
              </p>
            ) : null}
          </div>
          <button
            type="button"
            className="text-xl text-[var(--muted)] hover:text-foreground"
            onClick={onClose}
            aria-label="بستن"
          >
            ×
          </button>
        </div>

        <div className="flex gap-2 border-b border-[var(--border)] px-5 pt-3">
          <button
            type="button"
            className={`border-b-2 px-3 pb-2 text-sm ${
              tab === "queue"
                ? "border-primary font-bold text-primary"
                : "border-transparent text-[var(--muted)]"
            }`}
            onClick={() => setTab("queue")}
          >
            صف تصحیح ({data?.grading_queue?.length ?? 0})
          </button>
          <button
            type="button"
            className={`border-b-2 px-3 pb-2 text-sm ${
              tab === "students"
                ? "border-primary font-bold text-primary"
                : "border-transparent text-[var(--muted)]"
            }`}
            onClick={() => setTab("students")}
          >
            همه دانش‌آموزان
          </button>
        </div>

        <div className="flex-1 overflow-y-auto p-5">
          {error ? <Alert tone="error">{error}</Alert> : null}
          {loading ? (
            <PageContentSkeleton rows={4} />
          ) : tab === "queue" ? (
            <div className="space-y-4">
              {(data?.grading_queue ?? []).length === 0 ? (
                <p className="text-sm text-[var(--muted)]">موردی در صف تصحیح نیست.</p>
              ) : (
                (data?.grading_queue ?? []).map((sub) => (
                  <article
                    key={sub.id}
                    className="rounded-2xl border border-[var(--border)] bg-white p-4"
                  >
                    <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
                      <div>
                        <h4 className="font-bold">{sub.user?.name ?? `کاربر #${sub.id}`}</h4>
                        <p className="text-xs text-[var(--muted)]">
                          مرحله: {sub.step?.title ?? "—"} · {statusLabelFa(sub.status)} ·{" "}
                          {formatDate(sub.submitted_at)}
                          {sub.is_late ? " · تأخیر" : ""}
                        </p>
                      </div>
                      <span className="rounded-lg bg-amber-50 px-2 py-0.5 text-xs text-amber-800">
                        نیازمند تصحیح
                      </span>
                    </div>
                    {renderGradeControls(sub)}
                  </article>
                ))
              )}
            </div>
          ) : (
            <div className="space-y-4">
              <div className="overflow-x-auto rounded-xl border border-[var(--border)]">
              <table className="min-w-full text-sm">
                <thead className="bg-slate-50 text-[var(--muted)]">
                  <tr>
                    <th className="px-3 py-2 text-right font-medium">دانش‌آموز</th>
                    <th className="px-3 py-2 text-right font-medium">وضعیت مراحل</th>
                    <th className="px-3 py-2 text-right font-medium">آخرین ارسال</th>
                    <th className="px-3 py-2 text-right font-medium">عملیات</th>
                  </tr>
                </thead>
                <tbody>
                  {(data?.students ?? []).map((row) => {
                    const subs = row.step_submissions?.length
                      ? row.step_submissions
                      : row.submission
                        ? [row.submission]
                        : [];
                    const latest = subs[subs.length - 1];
                    const gradable = subs.find((s) =>
                      ["submitted", "resubmitted", "returned", "graded"].includes(s.status),
                    );

                    return (
                      <tr key={row.enrollment_id} className="border-t border-[var(--border)] align-top">
                        <td className="px-3 py-2">{studentName(row)}</td>
                        <td className="px-3 py-2">
                          {subs.length === 0 ? (
                            <span className="text-[var(--muted)]">ارسال نشده</span>
                          ) : (
                            <ul className="space-y-1">
                              {subs.map((s) => (
                                <li key={s.id} className="text-xs">
                                  {statusLabelFa(s.status)}
                                  {s.score != null ? ` · ${s.score}` : ""}
                                  {s.is_late ? " · تأخیر" : ""}
                                </li>
                              ))}
                            </ul>
                          )}
                        </td>
                        <td className="px-3 py-2">{formatDate(latest?.submitted_at)}</td>
                        <td className="px-3 py-2">
                          {gradable ? (
                            <Button
                              variant="secondary"
                              className="text-xs"
                              onClick={() => setSelectedSubId(gradable.id)}
                            >
                              مشاهده / تصحیح
                            </Button>
                          ) : (
                            <span className="text-xs text-[var(--muted)]">—</span>
                          )}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
              </div>

              {selectedSubId ? (
                (() => {
                  const sub = (data?.students ?? [])
                    .flatMap((r) => r.step_submissions ?? (r.submission ? [r.submission] : []))
                    .find((s) => s.id === selectedSubId);
                  if (!sub) return null;
                  return (
                    <article className="rounded-2xl border border-[var(--border)] bg-slate-50/50 p-4">
                      <div className="mb-3 flex items-center justify-between gap-2">
                        <h4 className="font-bold">جزئیات ارسال</h4>
                        <button
                          type="button"
                          className="text-sm text-[var(--muted)] hover:text-foreground"
                          onClick={() => setSelectedSubId(null)}
                        >
                          بستن
                        </button>
                      </div>
                      {renderGradeControls(sub)}
                    </article>
                  );
                })()
              ) : null}
            </div>
          )}
        </div>

        <div className="border-t border-[var(--border)] p-4 text-left">
          <Button variant="secondary" onClick={onClose}>
            بستن
          </Button>
        </div>
      </div>
    </div>
  );
}

export function UploadAssignmentMaterialsModal({
  open,
  assignmentId,
  onClose,
  onUploaded,
}: {
  open: boolean;
  assignmentId: number | null;
  onClose: () => void;
  onUploaded: () => void;
}) {
  const [file, setFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (open) {
      setFile(null);
      setError(null);
    }
  }, [open]);

  if (!open || !assignmentId) return null;

  const upload = async () => {
    if (!file) {
      setError("فایل را انتخاب کنید.");
      return;
    }
    setUploading(true);
    setError(null);
    try {
      const form = new FormData();
      form.append("file", file);
      await apiPostFormData(`/assignments/${assignmentId}/materials`, form);
      onUploaded();
      onClose();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در آپلود");
    } finally {
      setUploading(false);
    }
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
      <div className="w-full max-w-md rounded-2xl border border-[var(--border)] bg-white p-5 shadow-xl">
        <h3 className="text-lg font-bold">بارگذاری مطالب</h3>
        {error ? (
          <div className="mt-3">
            <Alert tone="error">{error}</Alert>
          </div>
        ) : null}
        <div className="mt-4">
          <Field label="فایل مرجع (PDF، DOC، …)">
            <Input type="file" onChange={(e) => setFile(e.target.files?.[0] ?? null)} />
          </Field>
        </div>
        <div className="mt-5 flex justify-end gap-2">
          <Button variant="secondary" onClick={onClose} disabled={uploading}>
            انصراف
          </Button>
          <Button onClick={upload} loading={uploading}>
            آپلود
          </Button>
        </div>
      </div>
    </div>
  );
}
