"use client";

import { useState, useEffect, useRef, useTransition, useCallback } from "react";
import { Image as ImageIcon, Upload, Trash2, Loader2, Plus, AlertCircle } from "lucide-react";

interface Screenshot {
  id: string;
  attributes: {
    fileName: string;
    fileSize: number;
    uploadOperations: UploadOperation[] | null;
    assetDeliveryState: {
      state: "COMPLETE" | "FAILED" | "UPLOAD_COMPLETE" | "AWAITING_UPLOAD";
      errors?: { code: string; description: string }[];
    } | null;
    templateUrl: string | null;
  };
}

interface UploadOperation {
  method: string;
  url: string;
  length: number;
  offset: number;
  requestHeaders: { name: string; value: string }[];
}

interface ScreenshotManagerProps {
  versionId: string;
  versionString: string;
}

export default function ScreenshotManager({ versionId, versionString }: ScreenshotManagerProps) {
  const [localizationId, setLocalizationId] = useState<string | null>(null);
  const [screenshots, setScreenshots] = useState<Screenshot[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);
  const [dragging, setDragging] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const [, startTransition] = useTransition();

  const fetchScreenshots = useCallback(async (locId: string) => {
    setError(null);
    const res = await fetch(`/api/asc/screenshots?localizationId=${locId}`);
    const d = await res.json();
    if (!res.ok) { setError(d.error ?? "Ekran görüntüleri yüklenemedi"); return; }
    setScreenshots(d.screenshots ?? []);
  }, []);

  useEffect(() => {
    setLoading(true);
    // Step 1: resolve the first localization id for this version
    fetch(`/api/asc/localizations?versionId=${versionId}`)
      .then((r) => r.json())
      .then(async (d) => {
        const locs = d.data ?? [];
        if (locs.length === 0) { setLoading(false); return; }
        const firstId: string = locs[0].id;
        setLocalizationId(firstId);
        await fetchScreenshots(firstId);
      })
      .catch((e) => setError(e.message))
      .finally(() => setLoading(false));
  }, [versionId, fetchScreenshots]);

  async function uploadFile(file: File) {
    if (!localizationId) return;
    setUploading(true);
    setError(null);
    try {
      // Step 1: Reserve
      const reserveRes = await fetch(`/api/asc/screenshots`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ localizationId, fileName: file.name, fileSize: file.size }),
      });
      const reserveData = await reserveRes.json();
      if (!reserveRes.ok) { setError(reserveData.error ?? "Yükleme başlatılamadı"); return; }

      const screenshotId: string = reserveData.data?.id;
      const uploadOps: UploadOperation[] = reserveData.data?.attributes?.uploadOperations ?? [];

      // Step 2: Upload each part
      for (const op of uploadOps) {
        const slice = file.slice(op.offset, op.offset + op.length);
        const headers: Record<string, string> = {};
        for (const h of op.requestHeaders) headers[h.name] = h.value;
        await fetch(op.url, { method: op.method, headers, body: slice });
      }

      // Step 3: Commit
      const commitRes = await fetch(`/api/asc/screenshots/commit`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ screenshotId }),
      });
      if (!commitRes.ok) {
        const d = await commitRes.json();
        setError(d.error ?? "Yükleme tamamlanamadı");
        return;
      }

      await fetchScreenshots(localizationId);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Bilinmeyen hata");
    } finally {
      setUploading(false);
    }
  }

  function handleFiles(files: FileList | null) {
    if (!files || files.length === 0) return;
    startTransition(() => {
      Array.from(files).forEach((f) => uploadFile(f));
    });
  }

  async function handleDelete(id: string) {
    setDeletingId(id);
    setError(null);
    try {
      const res = await fetch(`/api/asc/screenshots?screenshotId=${id}`, { method: "DELETE" });
      if (!res.ok) {
        const d = await res.json();
        setError(d.error ?? "Silinemedi");
      } else {
        setScreenshots((prev) => prev.filter((s) => s.id !== id));
      }
    } finally {
      setDeletingId(null);
    }
  }

  function onDragOver(e: React.DragEvent) { e.preventDefault(); setDragging(true); }
  function onDragLeave() { setDragging(false); }
  function onDrop(e: React.DragEvent) {
    e.preventDefault();
    setDragging(false);
    handleFiles(e.dataTransfer.files);
  }

  return (
    <section className="rounded-2xl border border-white/5 bg-white/[0.03] overflow-hidden">
      {/* Header */}
      <div className="flex items-center justify-between px-6 py-4 border-b border-white/5">
        <h2 className="font-bold text-sm flex items-center gap-2">
          <ImageIcon size={15} className="text-sky-400" />
          Ekran Görüntüleri
          <span className="text-[10px] text-slate-500 font-normal">iPhone 6.5″ · v{versionString}</span>
          <span className="text-[10px] bg-sky-500/10 text-sky-400 border border-sky-500/20 rounded-full px-2 py-0.5">
            {screenshots.length}/10
          </span>
        </h2>

        <button
          onClick={() => fileInputRef.current?.click()}
          disabled={uploading || screenshots.length >= 10 || !localizationId}
          className="flex items-center gap-1.5 px-3 py-2 rounded-lg bg-sky-600/20 hover:bg-sky-600/30 border border-sky-500/20 text-xs font-semibold text-sky-300 hover:text-sky-200 transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
        >
          {uploading ? <Loader2 size={12} className="animate-spin" /> : <Plus size={12} />}
          Ekle
        </button>

        <input
          ref={fileInputRef}
          type="file"
          accept="image/png,image/jpeg"
          multiple
          className="hidden"
          onChange={(e) => handleFiles(e.target.files)}
        />
      </div>

      {/* Body */}
      <div className="p-6">
        {error && (
          <div className="flex items-center gap-2 text-xs text-red-400 bg-red-400/10 rounded-lg px-4 py-2 mb-4">
            <AlertCircle size={13} />
            {error}
          </div>
        )}

        {loading ? (
          <div className="flex items-center justify-center py-12">
            <Loader2 size={22} className="animate-spin text-slate-500" />
          </div>
        ) : !localizationId ? (
          <p className="text-sm text-slate-500 text-center py-8">
            Bu sürüm için lokalizasyon bulunamadı.
          </p>
        ) : (
          <>
            {screenshots.length > 0 && (
              <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 mb-4">
                {screenshots.map((s) => {
                  const src = s.attributes.templateUrl;
                  const state = s.attributes.assetDeliveryState?.state;
                  return (
                    <div
                      key={s.id}
                      className="relative group rounded-xl overflow-hidden border border-white/8 bg-black/30 aspect-[9/19.5]"
                    >
                      {src ? (
                        // eslint-disable-next-line @next/next/no-img-element
                        <img src={src} alt={s.attributes.fileName} className="w-full h-full object-cover" />
                      ) : (
                        <div className="w-full h-full flex flex-col items-center justify-center gap-1 text-slate-600">
                          <ImageIcon size={20} />
                          <span className="text-[9px]">
                            {state === "AWAITING_UPLOAD" ? "Yükleniyor…" : state ?? "İşleniyor"}
                          </span>
                        </div>
                      )}

                      <div className="absolute inset-0 bg-black/60 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
                        <button
                          onClick={() => handleDelete(s.id)}
                          disabled={deletingId === s.id}
                          className="p-2 rounded-lg bg-red-500/20 hover:bg-red-500/40 text-red-400 hover:text-red-300 transition-colors"
                        >
                          {deletingId === s.id
                            ? <Loader2 size={14} className="animate-spin" />
                            : <Trash2 size={14} />}
                        </button>
                      </div>

                      {state && state !== "COMPLETE" && (
                        <div className="absolute bottom-1 left-1 right-1">
                          <span className="block text-center text-[9px] bg-black/70 text-amber-400 rounded px-1 py-0.5">
                            {state === "UPLOAD_COMPLETE" ? "İşleniyor…" : state}
                          </span>
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            )}

            {screenshots.length < 10 && (
              <div
                onDragOver={onDragOver}
                onDragLeave={onDragLeave}
                onDrop={onDrop}
                onClick={() => !uploading && fileInputRef.current?.click()}
                className={`border-2 border-dashed rounded-xl p-8 flex flex-col items-center gap-3 cursor-pointer transition-all ${
                  dragging ? "border-sky-500 bg-sky-500/10" : "border-white/10 hover:border-white/20 hover:bg-white/[0.02]"
                } ${uploading ? "pointer-events-none opacity-60" : ""}`}
              >
                {uploading ? <Loader2 size={24} className="animate-spin text-sky-400" /> : <Upload size={24} className="text-slate-500" />}
                <div className="text-center">
                  <p className="text-sm text-slate-400 font-medium">
                    {uploading ? "Yükleniyor…" : "PNG / JPEG sürükle veya tıkla"}
                  </p>
                  <p className="text-[11px] text-slate-600 mt-0.5">iPhone 6.5″ · Önerilen: 1242 × 2688 px</p>
                </div>
              </div>
            )}
          </>
        )}
      </div>
    </section>
  );
}
