"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { ConfirmDialog } from "@/components/ui/ConfirmDialog";
import { Field, Input } from "@/components/ui/Field";
import { PageContentSkeleton } from "@/components/ui/Skeleton";
import { TeacherPanel } from "@/components/teacher/ui/TeacherPanel";
import { TeacherModal } from "@/components/teacher/ui/TeacherModal";
import { ResourceAccessModal } from "@/components/teacher/ResourceAccessModal";
import { ResourceClassPickerModal } from "@/components/teacher/ResourceClassPickerModal";
import { ResourceLibrarySearchModal } from "@/components/teacher/ResourceLibrarySearchModal";
import { ResourceShareModal } from "@/components/teacher/ResourceShareModal";
import { ResourceTagPicker } from "@/components/teacher/ResourceTagPicker";
import { SyllabusSearchSelect, type SyllabusPayload } from "@/components/teacher/SyllabusSearchSelect";
import { TeacherSearchBar } from "@/components/teacher/ui/TeacherSearchBar";
import { TeacherStatGrid } from "@/components/teacher/ui/TeacherStatGrid";
import { ApiError, apiDelete, apiDownloadFile, apiFetchBlob, apiGet, apiPatch, apiPostFormData } from "@/lib/api";

interface ResourceItem {
  id: number;
  title?: string | null;
  original_name: string;
  tags: string[];
  file_size_bytes: number;
  download_count: number;
  created_at: string;
  mime_type?: string | null;
  shared_class_count?: number;
  access_status?: "shared" | "this_class_only";
  can_manage?: boolean;
  syllabus_topic_ids?: number[];
  syllabus_chapter_ids?: number[];
}

interface ResourcesResponse {
  resources: ResourceItem[];
  stats: {
    files_count: number;
    downloads_count: number;
    tags_count: number;
    total_bytes: number;
  };
  tags: string[];
}

function formatBytes(n: number): string {
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} کیلوبایت`;
  return `${(n / (1024 * 1024)).toFixed(1)} مگابایت`;
}

function fileTypeLabel(mime?: string | null, name?: string): string {
  const lower = `${mime ?? ""} ${name ?? ""}`.toLowerCase();
  if (lower.includes("pdf")) return "PDF";
  if (lower.includes("word") || lower.endsWith(".doc") || lower.endsWith(".docx")) return "Word";
  if (lower.includes("sheet") || lower.endsWith(".xls") || lower.endsWith(".xlsx")) return "Excel";
  if (lower.includes("image") || /\.(png|jpe?g|gif|webp)$/.test(lower)) return "تصویر";
  if (lower.includes("video") || /\.(mp4|mkv|webm)$/.test(lower)) return "ویدیو";
  if (lower.includes("audio")) return "صوت";
  if (lower.includes("zip") || lower.includes("rar")) return "فشرده";
  return mime?.split("/")[1]?.toUpperCase() || "فایل";
}

function accessStatusLabel(resource: ResourceItem): string {
  const count = resource.shared_class_count ?? 1;
  if (count <= 1) return "فقط این کلاس";
  return `مشترک با ${count} کلاس`;
}

export function ClassResourcesTab({
  classRoomId,
  subjectId,
  scheduleId,
  classLabel,
}: {
  classRoomId: number;
  subjectId?: number | null;
  scheduleId?: number | null;
  classLabel?: string | null;
}) {
  const [data, setData] = useState<ResourcesResponse | null>(null);
  const [searchOpen, setSearchOpen] = useState(false);
  const [q, setQ] = useState("");
  const [debouncedQ, setDebouncedQ] = useState("");
  const [loading, setLoading] = useState(true);
  const [uploadOpen, setUploadOpen] = useState(false);
  const [file, setFile] = useState<File | null>(null);
  const [title, setTitle] = useState("");
  const [tags, setTags] = useState<string[]>([]);
  const [shareClassIds, setShareClassIds] = useState<number[]>([]);
  const [topicIds, setTopicIds] = useState<number[]>([]);
  const [chapterIds, setChapterIds] = useState<number[]>([]);
  const [syllabus, setSyllabus] = useState<SyllabusPayload | null>(null);
  const [pickerOpen, setPickerOpen] = useState(false);
  const [availableTags, setAvailableTags] = useState<string[]>([]);
  const [uploading, setUploading] = useState(false);
  const [shareResource, setShareResource] = useState<ResourceItem | null>(null);
  const [editResource, setEditResource] = useState<ResourceItem | null>(null);
  const [editTitle, setEditTitle] = useState("");
  const [editTags, setEditTags] = useState<string[]>([]);
  const [editTopicIds, setEditTopicIds] = useState<number[]>([]);
  const [editChapterIds, setEditChapterIds] = useState<number[]>([]);
  const [savingTags, setSavingTags] = useState(false);
  const [accessResource, setAccessResource] = useState<ResourceItem | null>(null);
  const [deleteResource, setDeleteResource] = useState<ResourceItem | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const currentClassLabel = classLabel || `کلاس ${classRoomId}`;

  const load = useCallback(async (opts?: { silent?: boolean }) => {
    if (!opts?.silent) setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams();
      if (subjectId) params.set("subject_id", String(subjectId));
      if (debouncedQ.trim()) params.set("q", debouncedQ.trim());
      const payload = await apiGet<ResourcesResponse>(
        `/teacher/classes/${classRoomId}/resources?${params.toString()}`,
      );
      setData(payload);
      setAvailableTags(payload.tags ?? []);
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا");
    } finally {
      setLoading(false);
    }
  }, [classRoomId, debouncedQ, subjectId]);

  useEffect(() => {
    const timer = window.setTimeout(() => setDebouncedQ(q), 300);
    return () => window.clearTimeout(timer);
  }, [q]);

  useEffect(() => {
    void load({ silent: data != null });
    // data is only used to skip the first-load skeleton
    // eslint-disable-next-line react-hooks/exhaustive-deps -- avoid refetch loop
  }, [load]);

  useEffect(() => {
    if (!subjectId) {
      setSyllabus({ book: null, chapters: [] });
      return;
    }
    void apiGet<SyllabusPayload>(`/teacher/classes/${classRoomId}/syllabus?subject_id=${subjectId}`)
      .then(setSyllabus)
      .catch(() => setSyllabus({ book: null, chapters: [] }));
  }, [classRoomId, subjectId]);

  const hasSyllabus = Boolean(syllabus?.chapters.length);

  const openUpload = () => {
    setTags([]);
    setFile(null);
    setTitle("");
    setShareClassIds([classRoomId]);
    setTopicIds([]);
    setChapterIds([]);
    setUploadOpen(true);
  };

  const upload = async () => {
    if (!file || !title.trim()) return;
    setUploading(true);
    setError(null);
    try {
      const form = new FormData();
      form.append("file", file);
      form.append("title", title.trim());
      if (subjectId) form.append("subject_id", String(subjectId));
      tags.forEach((tag) => form.append("tags[]", tag));
      shareClassIds.forEach((id) => form.append("class_ids[]", String(id)));
      topicIds.forEach((id) => form.append("syllabus_topic_ids[]", String(id)));
      chapterIds.forEach((id) => form.append("syllabus_chapter_ids[]", String(id)));
      await apiPostFormData(`/teacher/classes/${classRoomId}/resources`, form);
      setUploadOpen(false);
      setFile(null);
      setTags([]);
      setTitle("");
      setTopicIds([]);
      setChapterIds([]);
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا");
    } finally {
      setUploading(false);
    }
  };

  const download = async (resource: ResourceItem) => {
    try {
      await apiDownloadFile(
        `/teacher/resources/${resource.id}/download`,
        resource.original_name,
      );
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در دانلود");
    }
  };

  const viewFile = async (resource: ResourceItem) => {
    try {
      const { blob } = await apiFetchBlob(`/teacher/resources/${resource.id}/download?inline=1`);
      const url = URL.createObjectURL(blob);
      window.open(url, "_blank", "noopener,noreferrer");
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در مشاهده فایل");
    }
  };

  const confirmDelete = async () => {
    if (!deleteResource) return;
    setDeleting(true);
    try {
      await apiDelete(`/teacher/resources/${deleteResource.id}`);
      setDeleteResource(null);
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در حذف");
    } finally {
      setDeleting(false);
    }
  };

  const openEdit = (resource: ResourceItem) => {
    setEditResource(resource);
    setEditTitle(resource.title || "");
    setEditTags(resource.tags ?? []);
    setEditTopicIds(resource.syllabus_topic_ids ?? []);
    setEditChapterIds(resource.syllabus_chapter_ids ?? []);
  };

  const saveEdit = async () => {
    if (!editResource || !editTitle.trim()) return;
    setSavingTags(true);
    setError(null);
    try {
      await apiPatch(`/teacher/resources/${editResource.id}`, {
        tags: editTags,
        title: editTitle.trim(),
        syllabus_topic_ids: editTopicIds,
        syllabus_chapter_ids: editChapterIds,
      });
      setEditResource(null);
      setEditTags([]);
      await load();
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در ذخیره");
    } finally {
      setSavingTags(false);
    }
  };

  const stats = data?.stats;
  const resources = data?.resources ?? [];
  const extraShareCount = Math.max(0, shareClassIds.filter((id) => id !== classRoomId).length);
  const searchTerm = q.trim();

  const emptyMessage = useMemo(() => {
    if (searchTerm) return `منبعی با عبارت «${searchTerm}» یافت نشد.`;
    return "هنوز منبعی برای این کلاس آپلود نشده است.";
  }, [searchTerm]);

  return (
    <div className="space-y-4">
      {error ? <Alert tone="error">{error}</Alert> : null}

      <TeacherStatGrid
        items={[
          { key: "files", label: "فایل‌ها", value: stats?.files_count ?? 0 },
          { key: "downloads", label: "دانلودها", value: stats?.downloads_count ?? 0 },
          { key: "tags", label: "تگ‌ها", value: stats?.tags_count ?? 0 },
          { key: "size", label: "حجم", value: formatBytes(stats?.total_bytes ?? 0) },
        ]}
      />

      <div className="flex flex-wrap items-center gap-2">
        <div className="min-w-0 flex-1">
          <TeacherSearchBar
            value={q}
            onChange={setQ}
            placeholder="جستجو بر اساس عنوان، تگ یا نوع فایل…"
          />
        </div>
        <Button onClick={openUpload}>افزودن منبع به کلاس</Button>
      </div>

      {loading && !data ? (
        <PageContentSkeleton rows={4} />
      ) : resources.length === 0 ? (
        <TeacherPanel>
          <p className="py-8 text-center text-sm text-slate-500">{emptyMessage}</p>
        </TeacherPanel>
      ) : (
        <TeacherPanel padded={false}>
          <div className="overflow-x-auto">
            <table className="min-w-full text-sm">
              <thead className="bg-slate-50 text-slate-500">
                <tr>
                  <th className="px-4 py-3 text-right font-semibold">عنوان فایل</th>
                  <th className="px-4 py-3 text-right font-semibold">نوع</th>
                  <th className="px-4 py-3 text-right font-semibold">حجم</th>
                  <th className="px-4 py-3 text-right font-semibold">تاریخ ایجاد</th>
                  <th className="px-4 py-3 text-right font-semibold">تگ‌ها</th>
                  <th className="px-4 py-3 text-right font-semibold">کلاس‌ها</th>
                  <th className="px-4 py-3 text-right font-semibold">وضعیت دسترسی</th>
                  <th className="px-4 py-3 text-right font-semibold">عملیات</th>
                </tr>
              </thead>
              <tbody>
                {resources.map((r) => (
                  <tr key={r.id} className="border-t border-[var(--border)]">
                    <td className="px-4 py-2">
                      <div className="font-medium text-slate-800">{r.title || r.original_name}</div>
                      <div className="text-xs text-slate-400">{r.original_name}</div>
                    </td>
                    <td className="px-4 py-2">{fileTypeLabel(r.mime_type, r.original_name)}</td>
                    <td className="px-4 py-2">{formatBytes(r.file_size_bytes)}</td>
                    <td className="px-4 py-2">{new Date(r.created_at).toLocaleDateString("fa-IR")}</td>
                    <td className="px-4 py-2">
                      {r.tags?.length ? (
                        <div className="flex flex-wrap gap-1">
                          {r.tags.map((tag) => (
                            <button
                              key={tag}
                              type="button"
                              onClick={() => setQ(tag)}
                              className="rounded-full bg-teal-50 px-2 py-0.5 text-xs font-medium text-teal-800 hover:bg-teal-100"
                            >
                              #{tag}
                            </button>
                          ))}
                        </div>
                      ) : (
                        <span className="text-slate-400">—</span>
                      )}
                    </td>
                    <td className="px-4 py-2">{r.shared_class_count ?? 1}</td>
                    <td className="px-4 py-2">{accessStatusLabel(r)}</td>
                    <td className="px-4 py-2">
                      <div className="flex flex-wrap gap-1">
                        <Button variant="ghost" className="px-2 py-1 text-xs" onClick={() => void viewFile(r)}>
                          مشاهده
                        </Button>
                        <Button variant="ghost" className="px-2 py-1 text-xs" onClick={() => void download(r)}>
                          دانلود
                        </Button>
                        <Button
                          variant="ghost"
                          className="px-2 py-1 text-xs text-teal-700"
                          onClick={() => setAccessResource(r)}
                        >
                          مدیریت دسترسی
                        </Button>
                        {r.can_manage ? (
                          <Button
                            variant="ghost"
                            className="px-2 py-1 text-xs text-slate-600"
                            onClick={() => openEdit(r)}
                          >
                            ویرایش
                          </Button>
                        ) : null}
                        <Button
                          variant="ghost"
                          className="px-2 py-1 text-xs text-slate-600"
                          onClick={() => setShareResource(r)}
                        >
                          ارسال به گروه
                        </Button>
                        {r.can_manage ? (
                          <Button
                            variant="ghost"
                            className="px-2 py-1 text-xs text-red-600"
                            onClick={() => setDeleteResource(r)}
                          >
                            حذف
                          </Button>
                        ) : null}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </TeacherPanel>
      )}

      <ResourceShareModal
        open={shareResource != null}
        onClose={() => setShareResource(null)}
        resource={shareResource}
        classRoomId={classRoomId}
        subjectId={subjectId}
        scheduleId={scheduleId}
      />

      <ResourceAccessModal
        open={accessResource != null}
        onClose={() => setAccessResource(null)}
        resourceId={accessResource?.id ?? null}
        resourceTitle={accessResource?.title || accessResource?.original_name || "منبع"}
        currentClassId={classRoomId}
        canManage={Boolean(accessResource?.can_manage)}
        onChanged={() => void load()}
      />

      <ResourceLibrarySearchModal
        open={searchOpen}
        onClose={() => setSearchOpen(false)}
        classRoomId={classRoomId}
        classLabel={currentClassLabel}
        onGranted={() => void load()}
      />

      {editResource ? (
        <TeacherModal
          open
          onClose={() => {
            setEditResource(null);
            setEditTags([]);
          }}
          title="ویرایش منبع"
          subtitle={editResource.original_name}
          footer={
            <div className="flex gap-2">
              <Button block onClick={() => void saveEdit()} loading={savingTags} disabled={!editTitle.trim()}>
                ذخیره
              </Button>
              <Button
                variant="secondary"
                block
                onClick={() => {
                  setEditResource(null);
                  setEditTags([]);
                }}
              >
                انصراف
              </Button>
            </div>
          }
        >
          <div className="space-y-3">
            <Field label="عنوان فایل">
              <Input
                value={editTitle}
                onChange={(e) => setEditTitle(e.target.value)}
                placeholder="مثال: خلاصه درس چهارم"
              />
            </Field>
            <div className="space-y-1.5">
              <div className="text-sm font-medium text-foreground/85">سرفصل (اختیاری)</div>
              {hasSyllabus && syllabus ? (
                <SyllabusSearchSelect
                  syllabus={syllabus}
                  topicIds={editTopicIds}
                  chapterIds={editChapterIds}
                  emptyLabel="انتخاب سرفصل"
                  onChange={({ topicIds: nextTopics, chapterIds: nextChapters }) => {
                    setEditTopicIds(nextTopics);
                    setEditChapterIds(nextChapters);
                  }}
                />
              ) : (
                <p className="rounded-xl border border-dashed border-slate-200 bg-slate-50 px-3.5 py-2.5 text-sm text-slate-500">
                  {subjectId
                    ? "برای این درس هنوز سرفصلی در بخش برنامه درسی ثبت نشده است."
                    : "ابتدا درس را انتخاب کنید."}
                </p>
              )}
            </div>
            <Field label="تگ‌ها">
              <ResourceTagPicker value={editTags} onChange={setEditTags} suggestions={availableTags} />
            </Field>
          </div>
        </TeacherModal>
      ) : null}

      {uploadOpen ? (
        <TeacherModal
          open
          onClose={() => setUploadOpen(false)}
          title="افزودن منبع به کلاس"
          size="lg"
          footer={
            <div className="flex gap-2">
              <Button block onClick={() => void upload()} loading={uploading} disabled={!file || !title.trim()}>
                آپلود
              </Button>
              <Button variant="secondary" block onClick={() => setUploadOpen(false)}>
                انصراف
              </Button>
            </div>
          }
        >
          <div className="space-y-3">
            <Button
              variant="secondary"
              block
              onClick={() => {
                setUploadOpen(false);
                setSearchOpen(true);
              }}
            >
              استفاده از منابع قبلی
            </Button>
            <Field label="فایل">
              <Input type="file" onChange={(e) => setFile(e.target.files?.[0] ?? null)} />
              {file ? <p className="mt-1 text-xs text-slate-500">نام فایل: {file.name}</p> : null}
            </Field>
            <Field label="عنوان فایل">
              <Input
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                placeholder="مثال: خلاصه درس چهارم"
              />
            </Field>
            <div className="space-y-1.5">
              <div className="text-sm font-medium text-foreground/85">سرفصل (اختیاری)</div>
              {hasSyllabus && syllabus ? (
                <SyllabusSearchSelect
                  syllabus={syllabus}
                  topicIds={topicIds}
                  chapterIds={chapterIds}
                  emptyLabel="انتخاب سرفصل"
                  onChange={({ topicIds: nextTopics, chapterIds: nextChapters }) => {
                    setTopicIds(nextTopics);
                    setChapterIds(nextChapters);
                  }}
                />
              ) : (
                <p className="rounded-xl border border-dashed border-slate-200 bg-slate-50 px-3.5 py-2.5 text-sm text-slate-500">
                  {subjectId
                    ? "برای این درس هنوز سرفصلی در بخش برنامه درسی ثبت نشده است."
                    : "ابتدا درس را انتخاب کنید."}
                </p>
              )}
            </div>
            <Field label="تگ‌ها">
              <ResourceTagPicker value={tags} onChange={setTags} suggestions={availableTags} />
              <p className="mt-1 text-xs text-slate-500">
                از تگ‌های قبلی انتخاب کنید یا تگ جدید بسازید. یک فایل می‌تواند چند تگ داشته باشد.
              </p>
            </Field>
            <div className="rounded-xl border border-slate-200 bg-slate-50/80 p-3">
              <h4 className="text-sm font-bold text-slate-800">اشتراک‌گذاری با کلاس‌ها</h4>
              <p className="mt-1 text-xs text-slate-500">این فایل برای دانش‌آموزان کدام کلاس‌ها قابل مشاهده باشد؟</p>
              <p className="mt-2 text-sm text-slate-700">
                کلاس فعلی: <span className="font-medium">{currentClassLabel}</span>
              </p>
              {extraShareCount > 0 ? (
                <p className="mt-1 text-xs text-teal-700">{extraShareCount} کلاس دیگر هم انتخاب شده است.</p>
              ) : null}
              <Button
                variant="secondary"
                className="mt-3"
                onClick={() => setPickerOpen(true)}
              >
                + اشتراک‌گذاری با کلاس‌های دیگر
              </Button>
            </div>
          </div>
        </TeacherModal>
      ) : null}

      <ResourceClassPickerModal
        open={pickerOpen}
        onClose={() => setPickerOpen(false)}
        selectedIds={shareClassIds}
        lockedIds={[classRoomId]}
        onConfirm={setShareClassIds}
      />

      <ConfirmDialog
        open={deleteResource != null}
        title="حذف منبع"
        message="با حذف این فایل، دانش‌آموزان همه کلاس‌های دارای دسترسی دیگر نمی‌توانند آن را مشاهده یا دانلود کنند."
        confirmLabel="حذف فایل"
        loading={deleting}
        onCancel={() => setDeleteResource(null)}
        onConfirm={() => void confirmDelete()}
      />
    </div>
  );
}
