"use client";

import Image from "next/image";
import { useEffect, useMemo, useState, useTransition } from "react";

type MediaItem = {
  id: string;
  url: string;
  alt?: string | null;
  mimeType?: string | null;
  createdAt?: string | null;
};

type TargetType =
  | "COMPANY_GALLERY"
  | "SUBMISSION_GALLERY"
  | "REAL_ESTATE_GALLERY"
  | "CAR_GALLERY"
  | "MAGAZINE_ARTICLE_COVER"
  | "AD_CREATIVE_MEDIA";

type TargetOption = {
  id: string;
  label: string;
};

type MediaCommandCenterProps = {
  initialItems: MediaItem[];
  targets: Record<TargetType, TargetOption[]>;
};

const TARGET_LABELS: Record<TargetType, string> = {
  COMPANY_GALLERY: "Galerija kompanije / mesta",
  SUBMISSION_GALLERY: "Galerija prijave",
  REAL_ESTATE_GALLERY: "Galerija nekretnine",
  CAR_GALLERY: "Galerija automobila",
  MAGAZINE_ARTICLE_COVER: "Cover magazin članka",
  AD_CREATIVE_MEDIA: "Medija za kreativu",
};

function toCsv(items: MediaItem[]) {
  const headers = ["id", "url", "alt", "mimeType", "createdAt"];
  const rows = items.map((item) =>
    [item.id, item.url, item.alt ?? "", item.mimeType ?? "", item.createdAt ?? ""]
      .map((value) => `"${String(value).replaceAll('"', '""')}"`)
      .join(","),
  );

  return [headers.join(","), ...rows].join("\n");
}

function downloadFile(filename: string, content: string, type: string) {
  const blob = new Blob([content], { type });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  anchor.click();
  URL.revokeObjectURL(url);
}

async function fetchLibrary(search: string, limit: number) {
  const response = await fetch(`/api/admin/media?limit=${limit}&q=${encodeURIComponent(search)}`);
  const payload = (await response.json()) as {
    items?: MediaItem[];
    message?: string;
  };

  if (!response.ok) {
    throw new Error(payload.message || "Učitavanje media biblioteke nije uspelo.");
  }

  return payload.items ?? [];
}

export function MediaCommandCenter({
  initialItems,
  targets,
}: MediaCommandCenterProps) {
  const [items, setItems] = useState(initialItems);
  const [search, setSearch] = useState("");
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [targetType, setTargetType] = useState<TargetType>("COMPANY_GALLERY");
  const [targetId, setTargetId] = useState("");
  const [message, setMessage] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();

  const currentTargets = useMemo(() => targets[targetType] ?? [], [targetType, targets]);
  const selectedItems = items.filter((item) => selectedIds.includes(item.id));
  const allSelected = items.length > 0 && selectedIds.length === items.length;
  const singleMediaTarget =
    targetType === "MAGAZINE_ARTICLE_COVER" || targetType === "AD_CREATIVE_MEDIA";

  useEffect(() => {
    if (!currentTargets.length) {
      setTargetId("");
      return;
    }

    if (currentTargets.some((item) => item.id === targetId)) {
      return;
    }

    setTargetId(currentTargets[0]?.id ?? "");
  }, [currentTargets, targetId]);

  function toggleSelection(id: string) {
    setSelectedIds((current) =>
      current.includes(id) ? current.filter((item) => item !== id) : [...current, id],
    );
  }

  function toggleAll() {
    setSelectedIds(allSelected ? [] : items.map((item) => item.id));
  }

  function handleRefresh(nextSearch = search) {
    startTransition(async () => {
      try {
        const nextItems = await fetchLibrary(nextSearch, 48);
        setItems(nextItems);
        setSelectedIds((current) => current.filter((id) => nextItems.some((item) => item.id === id)));
        setMessage(null);
      } catch (error) {
        setMessage(
          error instanceof Error ? error.message : "Medijska biblioteka trenutno nije dostupna.",
        );
      }
    });
  }

  function handleExportJson() {
    if (!selectedItems.length) {
      setMessage("Izaberi makar jedan medijski fajl za izvoz.");
      return;
    }

    downloadFile(
      `media-export-${Date.now()}.json`,
      JSON.stringify(selectedItems, null, 2),
      "application/json;charset=utf-8",
    );
    setMessage(`JSON izvoz je pripremljen za ${selectedItems.length} fajlova.`);
  }

  function handleExportCsv() {
    if (!selectedItems.length) {
      setMessage("Izaberi makar jedan medijski fajl za izvoz.");
      return;
    }

    downloadFile(
      `media-export-${Date.now()}.csv`,
      toCsv(selectedItems),
      "text/csv;charset=utf-8",
    );
    setMessage(`CSV izvoz je pripremljen za ${selectedItems.length} fajlova.`);
  }

  function handleAttach() {
    startTransition(async () => {
      try {
        const response = await fetch("/api/admin/media/attach", {
          method: "POST",
          headers: {
            "content-type": "application/json",
          },
          body: JSON.stringify({
            mediaIds: selectedIds,
            targetType,
            targetId,
          }),
        });

        const payload = (await response.json()) as { message?: string };

        if (!response.ok) {
          throw new Error(payload.message || "Masovno povezivanje medije nije uspelo.");
        }

        setMessage(
          singleMediaTarget
            ? "Izabrani fajl je vezan za ciljano polje."
            : `Izabrani fajlovi su povezani sa ciljem (${selectedIds.length}).`,
        );
      } catch (error) {
        setMessage(error instanceof Error ? error.message : "Masovno povezivanje medije nije uspelo.");
      }
    });
  }

  return (
    <div className="space-y-6">
      <div className="admin-toolbar rounded-[2rem]">
        <div className="flex flex-col gap-4 border-b border-border px-5 py-4 xl:flex-row xl:items-start xl:justify-between">
          <div className="max-w-3xl">
            <p className="eyebrow">Medijski komandni centar</p>
            <h3 className="mt-2 text-2xl font-semibold text-foreground">
              Masovno povezivanje i izvoz
            </h3>
            <p className="mt-3 text-sm leading-7 text-muted-foreground">
              Izaberi više asseta, eksportuj ih kao JSON/CSV ili ih jednim potezom prikači na profil, prijavu, nekretninu, automobil, magazin ili kreativu.
            </p>
          </div>
          <div className="flex flex-wrap gap-3">
            <button type="button" onClick={handleExportJson} className="ghost-button">
              Izvezi JSON
            </button>
            <button type="button" onClick={handleExportCsv} className="ghost-button">
              Izvezi CSV
            </button>
          </div>
        </div>

        <div className="grid gap-6 border-b border-border px-5 py-5 xl:grid-cols-[minmax(0,1fr)_420px]">
          <div className="space-y-3">
            <label className="field-shell">
              <span className="field-label">Pretraga media biblioteke</span>
              <div className="flex gap-3">
                <input
                  value={search}
                  onChange={(event) => setSearch(event.target.value)}
                  className="input-premium mt-0"
                  placeholder="URL, alt tekst ili MIME tip"
                />
                <button
                  type="button"
                  onClick={() => handleRefresh()}
                  disabled={isPending}
                  className="ghost-button whitespace-nowrap"
                >
                  {isPending ? "Osvežavanje..." : "Osveži"}
                </button>
              </div>
            </label>
            <div className="flex flex-wrap gap-3">
              <span className="admin-chip">Ukupno prikazano: {items.length}</span>
              <span className="admin-chip">Označeno: {selectedIds.length}</span>
              {singleMediaTarget ? (
                <span className="admin-chip">Koristi se prvi izabrani fajl</span>
              ) : null}
            </div>
          </div>

          <div className="rounded-[1.5rem] border border-border bg-white/80 p-4">
            <div className="grid gap-3">
              <select
                value={targetType}
                onChange={(event) => setTargetType(event.target.value as TargetType)}
                aria-label="Tip media targeta"
                className="inline-select"
              >
                {Object.entries(TARGET_LABELS).map(([value, label]) => (
                  <option key={value} value={value}>
                    {label}
                  </option>
                ))}
              </select>
              <select
                value={targetId}
                onChange={(event) => setTargetId(event.target.value)}
                aria-label="Cilj medije"
                className="inline-select"
              >
                {currentTargets.length ? null : <option value="">Nema dostupnih targeta</option>}
                {currentTargets.map((target) => (
                  <option key={target.id} value={target.id}>
                    {target.label}
                  </option>
                ))}
              </select>
              <button
                type="button"
                onClick={handleAttach}
                disabled={isPending || selectedIds.length === 0 || !targetId}
                className="primary-button"
              >
                {isPending ? "Povezivanje..." : "Prikači izabrane assete"}
              </button>
              <p className="text-sm text-muted-foreground">
                Za cover i cilj kreativa koristi se prvi izabrani fajl. Za galerije se dodaju svi označeni fajlovi.
              </p>
            </div>
          </div>
        </div>

        {message ? (
          <div className="border-b border-border px-5 py-4 text-sm text-muted-foreground">
            {message}
          </div>
        ) : null}

        <div className="px-5 py-5">
          <div className="mb-4 flex items-center justify-between gap-3">
            <div className="text-sm text-muted-foreground">
              Označi assete koje želiš da eksportuješ ili vežeš na ciljnu stavku.
            </div>
            <label className="inline-flex items-center gap-2 text-sm font-medium text-foreground">
              <input
                type="checkbox"
                checked={allSelected}
                onChange={toggleAll}
                aria-label="Označi sve assete"
              />
              Označi sve
            </label>
          </div>

          <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
            {items.map((item) => (
              <button
                key={item.id}
                type="button"
                onClick={() => toggleSelection(item.id)}
                aria-label={`Medijski fajl ${item.alt || item.id}`}
                aria-pressed={selectedIds.includes(item.id)}
                className="overflow-hidden rounded-[1.5rem] border border-border bg-white/90 p-3 text-left shadow-[0_12px_32px_rgba(22,22,22,0.06)] transition hover:-translate-y-0.5"
              >
                <div className="relative h-40 overflow-hidden rounded-[1.2rem] bg-muted">
                  <Image
                    src={item.url}
                    alt={item.alt || "Medijski sadržaj"}
                    fill
                    className="object-cover"
                  />
                </div>
                <div className="mt-3">
                  <div className="flex items-center justify-between gap-2">
                    <div className="line-clamp-1 text-sm font-semibold text-foreground">
                      {item.alt || "Bez alt teksta"}
                    </div>
                    <span className="admin-chip">
                      {selectedIds.includes(item.id) ? "Izabrano" : "Izaberi"}
                    </span>
                  </div>
                  <div className="mt-2 line-clamp-2 text-xs text-muted-foreground">
                    {item.url}
                  </div>
                  <div className="mt-3 flex flex-wrap gap-2">
                    <span className="admin-chip">{item.mimeType || "image/*"}</span>
                    {item.createdAt ? (
                      <span className="admin-chip">{item.createdAt.slice(0, 10)}</span>
                    ) : null}
                  </div>
                </div>
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
