"use client";

import { useEffect, useState } from "react";
import { ApiError, apiDownloadFile, apiFetchBlob } from "@/lib/api";

export interface MediaAttachment {
  path?: string;
  name?: string;
  mime?: string | null;
}

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

interface SubmissionContentViewerProps {
  submissionId: number;
  content?: string | null;
  filePath?: string | null;
  payload?: Record<string, unknown> | null;
  feedback?: SubmissionFeedback | null;
  submittedAt?: string | null;
  isLate?: boolean;
  status?: string;
  compact?: boolean;
}

type MediaType = "photo" | "voice" | "video" | "file";

function isImageAttachment(att?: MediaAttachment | null): boolean {
  if (!att?.path && !att?.name) return false;
  if (att.mime?.startsWith("image/")) return true;
  const name = att.name?.toLowerCase() ?? "";
  return /\.(jpe?g|png|gif|webp|bmp|heic|heif)$/.test(name);
}

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

function ImageLightbox({ src, alt, onClose }: { src: string; alt: string; onClose: () => void }) {
  return (
    <div
      className="fixed inset-0 z-[70] flex items-center justify-center bg-black/85 p-4"
      onClick={onClose}
    >
      <button
        type="button"
        className="absolute left-4 top-4 rounded-full bg-white/15 px-3 py-1 text-sm text-white hover:bg-white/25"
        onClick={onClose}
      >
        بستن
      </button>
      <img
        src={src}
        alt={alt}
        className="max-h-[92vh] max-w-full rounded-lg object-contain shadow-2xl"
        onClick={(e) => e.stopPropagation()}
      />
    </div>
  );
}

function MediaPreview({
  submissionId,
  type,
  attachment,
  label,
  compact,
}: {
  submissionId: number;
  type: MediaType;
  attachment?: MediaAttachment | null;
  label: string;
  compact?: boolean;
}) {
  const [objectUrl, setObjectUrl] = useState<string | null>(null);
  const [mime, setMime] = useState<string>("");
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [lightbox, setLightbox] = useState(false);

  useEffect(() => {
    let active = true;
    let url: string | null = null;

    const load = async () => {
      setLoading(true);
      setError(null);
      try {
        const result = await apiFetchBlob(
          `/assignment-submissions/${submissionId}/media/${type}`,
        );
        if (!active) return;
        url = URL.createObjectURL(result.blob);
        setObjectUrl(url);
        setMime(result.mime);
      } catch (err) {
        if (!active) return;
        setError(err instanceof ApiError ? err.message : "خطا در بارگذاری");
      } finally {
        if (active) setLoading(false);
      }
    };

    void load();

    return () => {
      active = false;
      if (url) URL.revokeObjectURL(url);
    };
  }, [submissionId, type]);

  const name = attachment?.name ?? label;
  const effectiveMime = attachment?.mime ?? mime;
  const isImage = type === "photo" || effectiveMime.startsWith("image/") || isImageAttachment(attachment);
  const isVideo = effectiveMime.startsWith("video/") || type === "video";
  const isAudio = effectiveMime.startsWith("audio/") || type === "voice";

  return (
    <>
      <div className="rounded-xl border border-[var(--border)] bg-white p-3">
        <div className="mb-2 flex items-center justify-between gap-2">
          <span className="text-xs font-medium text-slate-600">{label}</span>
          <button
            type="button"
            className="text-xs text-primary hover:underline"
            onClick={() =>
              void apiDownloadFile(
                `/assignment-submissions/${submissionId}/media/${type}`,
                attachment?.name ?? label,
              )
            }
          >
            دانلود
          </button>
        </div>

        {loading ? <p className="text-xs text-slate-400">در حال بارگذاری…</p> : null}
        {error ? <p className="text-xs text-orange-600">{error}</p> : null}

        {objectUrl && isImage ? (
          <button type="button" className="block w-full" onClick={() => setLightbox(true)}>
            <img
              src={objectUrl}
              alt={name}
              className={`w-full rounded-lg object-contain ${
                compact ? "max-h-48" : "max-h-[min(520px,70vh)]"
              }`}
            />
            {!compact ? (
              <span className="mt-1 block text-center text-xs text-slate-400">برای بزرگ‌نمایی کلیک کنید</span>
            ) : null}
          </button>
        ) : null}

        {objectUrl && isVideo ? (
          <video
            src={objectUrl}
            controls
            className={`w-full rounded-lg ${compact ? "max-h-48" : "max-h-[min(420px,60vh)]"}`}
          />
        ) : null}

        {objectUrl && isAudio && !isVideo ? (
          <audio src={objectUrl} controls className="w-full" />
        ) : null}

        {objectUrl && !isImage && !isVideo && !isAudio ? (
          <p className="text-sm text-slate-600">{name}</p>
        ) : null}
      </div>

      {lightbox && objectUrl ? (
        <ImageLightbox src={objectUrl} alt={name} onClose={() => setLightbox(false)} />
      ) : null}
    </>
  );
}

export function SubmissionContentViewer({
  submissionId,
  content,
  filePath,
  payload,
  feedback,
  submittedAt,
  isLate,
  status,
  compact = false,
}: SubmissionContentViewerProps) {
  const text =
    (typeof payload?.text === "string" ? payload.text : null) ??
    content ??
    null;

  const photo = payload?.photo as MediaAttachment | undefined;
  const voice = payload?.voice as MediaAttachment | undefined;
  const video = payload?.video as MediaAttachment | undefined;
  const file = payload?.file as MediaAttachment | undefined;
  const fileIsImage = isImageAttachment(file);
  const hasGenericFile = Boolean((file?.path && !fileIsImage) || (filePath && !fileIsImage));

  if (!text && !photo?.path && !voice?.path && !video?.path && !file?.path && !filePath) {
    return <p className="text-sm text-[var(--muted)]">محتوای ارسالی ثبت نشده است.</p>;
  }

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center gap-2 text-xs text-slate-500">
        {submittedAt ? <span>ارسال: {formatDate(submittedAt)}</span> : null}
        {status ? <span className="rounded-md bg-slate-100 px-2 py-0.5">{status}</span> : null}
        {isLate ? <span className="rounded-md bg-amber-100 px-2 py-0.5 text-amber-800">تأخیر</span> : null}
      </div>

      {feedback?.comment || feedback?.score != null ? (
        <div className="rounded-xl border border-teal-100 bg-teal-50/60 p-3">
          <span className="mb-1 block text-xs font-semibold text-teal-800">بازخورد قبلی</span>
          {feedback.score != null ? (
            <p className="text-sm font-medium text-teal-900">نمره: {feedback.score}</p>
          ) : null}
          {feedback.comment ? (
            <p className="mt-1 whitespace-pre-wrap text-sm text-teal-900/90">{feedback.comment}</p>
          ) : null}
          {feedback.returned_for_revision && feedback.revision_deadline ? (
            <p className="mt-1 text-xs text-teal-700">
              مهلت اصلاح: {formatDate(feedback.revision_deadline)}
            </p>
          ) : null}
        </div>
      ) : null}

      <h5 className="text-sm font-semibold text-slate-800">محتوای ارسالی</h5>

      {text ? (
        <div className="rounded-xl border border-[var(--border)] bg-white p-3">
          <span className="mb-1.5 block text-xs font-medium text-slate-600">متن</span>
          <p className="whitespace-pre-wrap text-sm leading-relaxed text-slate-800">{text}</p>
        </div>
      ) : null}

      {photo?.path ? (
        <MediaPreview submissionId={submissionId} type="photo" attachment={photo} label="عکس" compact={compact} />
      ) : null}

      {fileIsImage && file?.path ? (
        <MediaPreview submissionId={submissionId} type="photo" attachment={file} label="عکس" compact={compact} />
      ) : null}

      {video?.path ? (
        <MediaPreview submissionId={submissionId} type="video" attachment={video} label="ویدیو" compact={compact} />
      ) : null}

      {voice?.path ? (
        <MediaPreview submissionId={submissionId} type="voice" attachment={voice} label="صوت" compact={compact} />
      ) : null}

      {hasGenericFile ? (
        <MediaPreview
          submissionId={submissionId}
          type="file"
          attachment={file ?? (filePath ? { path: filePath, name: "فایل" } : null)}
          label="فایل"
          compact={compact}
        />
      ) : null}
    </div>
  );
}
