"use client";

import { useRef, useState } from "react";
import { Alert } from "@/components/ui/Alert";
import { Button } from "@/components/ui/Button";
import { ApiError, apiDelete, apiPostFormData } from "@/lib/api";

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

export interface StepAttachment {
  type: MediaType;
  path: string;
  name: string;
  mime?: string | null;
  url?: string | null;
}

export interface PendingAttachment {
  file: File;
  type: MediaType;
  previewUrl?: string;
}

const TYPE_LABELS: Record<MediaType, string> = {
  photo: "عکس",
  video: "ویدیو",
  voice: "صوت",
  file: "فایل",
};

function inferType(file: File): MediaType {
  if (file.type.startsWith("image/")) return "photo";
  if (file.type.startsWith("video/")) return "video";
  if (file.type.startsWith("audio/")) return "voice";
  return "file";
}

function AttachmentPreview({
  attachment,
}: {
  attachment: StepAttachment | PendingAttachment;
}) {
  const isPending = "file" in attachment;
  const type = attachment.type;
  const name = isPending ? attachment.file.name : attachment.name;
  const url = isPending
    ? attachment.previewUrl ?? URL.createObjectURL(attachment.file)
    : attachment.url;

  if (type === "photo" && url) {
    return (
      <img src={url} alt={name} className="max-h-32 rounded-lg border border-[var(--border)]" />
    );
  }
  if (type === "video" && url) {
    return <video src={url} controls className="max-h-40 w-full rounded-lg" />;
  }
  if (type === "voice" && url) {
    return <audio src={url} controls className="w-full" />;
  }

  return (
    <div className="rounded-lg border border-[var(--border)] bg-white px-3 py-2 text-sm">
      {name}
    </div>
  );
}

export function StepAttachmentsEditor({
  stepId,
  attachments,
  pending,
  onAttachmentsChange,
  onPendingChange,
  disabled,
}: {
  stepId?: number;
  attachments: StepAttachment[];
  pending: PendingAttachment[];
  onAttachmentsChange: (next: StepAttachment[]) => void;
  onPendingChange: (next: PendingAttachment[]) => void;
  disabled?: boolean;
}) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [uploadType, setUploadType] = useState<MediaType>("file");
  const [uploading, setUploading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const pickFile = () => inputRef.current?.click();

  const addFile = async (file: File) => {
    const type = uploadType === "file" ? inferType(file) : uploadType;
    setError(null);

    if (stepId) {
      setUploading(true);
      try {
        const form = new FormData();
        form.append("file", file);
        form.append("type", type);
        const uploaded = await apiPostFormData<StepAttachment>(
          `/assignment-steps/${stepId}/attachments`,
          form,
        );
        onAttachmentsChange([...attachments, uploaded]);
      } catch (err) {
        setError(err instanceof ApiError ? err.message : "خطا در آپلود");
      } finally {
        setUploading(false);
      }
      return;
    }

    onPendingChange([
      ...pending,
      {
        file,
        type,
        previewUrl: URL.createObjectURL(file),
      },
    ]);
  };

  const removeSaved = async (path: string) => {
    if (!stepId) return;
    setError(null);
    try {
      await apiDelete(
        `/assignment-steps/${stepId}/attachments?path=${encodeURIComponent(path)}`,
      );
      onAttachmentsChange(attachments.filter((a) => a.path !== path));
    } catch (err) {
      setError(err instanceof ApiError ? err.message : "خطا در حذف");
    }
  };

  const removePending = (index: number) => {
    onPendingChange(pending.filter((_, i) => i !== index));
  };

  return (
    <div className="space-y-2">
      <div className="flex flex-wrap items-center gap-2">
        <span className="text-sm font-medium">پیوست‌های معلم</span>
        <select
          value={uploadType}
          onChange={(e) => setUploadType(e.target.value as MediaType)}
          className="rounded-lg border border-[var(--border)] px-2 py-1 text-sm"
          disabled={disabled || uploading}
        >
          {(Object.keys(TYPE_LABELS) as MediaType[]).map((value) => (
            <option key={value} value={value}>
              {TYPE_LABELS[value]}
            </option>
          ))}
        </select>
        <Button
          type="button"
          variant="secondary"
          className="text-sm"
          onClick={pickFile}
          loading={uploading}
          disabled={disabled}
        >
          افزودن
        </Button>
        <input
          ref={inputRef}
          type="file"
          className="hidden"
          accept={
            uploadType === "photo"
              ? "image/*"
              : uploadType === "video"
                ? "video/*"
                : uploadType === "voice"
                  ? "audio/*"
                  : undefined
          }
          onChange={(e) => {
            const file = e.target.files?.[0];
            if (file) void addFile(file);
            e.target.value = "";
          }}
        />
      </div>

      {!stepId && pending.length > 0 ? (
        <p className="text-xs text-[var(--muted)]">
          فایل‌ها پس از ذخیره تکلیف بارگذاری می‌شوند.
        </p>
      ) : null}

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

      {attachments.length || pending.length ? (
        <div className="space-y-2">
          {attachments.map((attachment) => (
            <div
              key={attachment.path}
              className="flex flex-wrap items-start justify-between gap-2 rounded-xl border border-[var(--border)] bg-white p-3"
            >
              <div className="min-w-0 flex-1 space-y-2">
                <span className="text-xs text-[var(--muted)]">{TYPE_LABELS[attachment.type]}</span>
                <AttachmentPreview attachment={attachment} />
              </div>
              <Button
                type="button"
                variant="ghost"
                className="text-xs text-red-600"
                disabled={disabled || uploading}
                onClick={() => void removeSaved(attachment.path)}
              >
                حذف
              </Button>
            </div>
          ))}
          {pending.map((attachment, pendingIndex) => (
            <div
              key={`pending-${pendingIndex}-${attachment.file.name}`}
              className="flex flex-wrap items-start justify-between gap-2 rounded-xl border border-[var(--border)] bg-white p-3"
            >
              <div className="min-w-0 flex-1 space-y-2">
                <span className="text-xs text-[var(--muted)]">{TYPE_LABELS[attachment.type]}</span>
                <AttachmentPreview attachment={attachment} />
              </div>
              <Button
                type="button"
                variant="ghost"
                className="text-xs text-red-600"
                disabled={disabled || uploading}
                onClick={() => removePending(pendingIndex)}
              >
                حذف
              </Button>
            </div>
          ))}
        </div>
      ) : (
        <p className="text-xs text-[var(--muted)]">عکس، ویدیو، صوت یا فایل اضافه کنید.</p>
      )}
    </div>
  );
}

export async function uploadPendingStepAttachments(
  stepId: number,
  pending: PendingAttachment[],
): Promise<void> {
  for (const item of pending) {
    const form = new FormData();
    form.append("file", item.file);
    form.append("type", item.type);
    await apiPostFormData(`/assignment-steps/${stepId}/attachments`, form);
  }
}
