"use client";

import Image from "next/image";
import { useCallback, useEffect, useMemo, useRef, useState, useTransition } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { Spinner } from "@/components/common/Spinner";

import {
  extractPortalMediaPayload,
  getPortalMediaMaterialLabel,
  getPortalRequestStatusLabel,
  portalMediaMaterialMeta,
  portalRequestTypeMeta,
  resolvePortalMediaSources,
  type PortalMediaMaterialType,
  type PortalMediaSourceType,
} from "@/lib/portal-request-presenters";
import {
  captureNativePartnerPhoto,
  isNativePartnerApp,
  pickNativePartnerImages,
} from "@/lib/partner-capacitor";
import { getTierAdminLabel } from "@/lib/module-formatters";

type PlanOption = {
  id: string;
  nameSr: string;
  tier: string;
};

type PlacementOption = {
  id: string;
  label: string;
  payload?: string;
};

type PortalRequestItem = {
  id: string;
  type: string;
  status: string;
  title: string;
  message: string;
  payload?: unknown;
  createdAt: Date | string;
  requestedPlan?: { nameSr: string; tier: string } | null;
  requestedPlacement?: { label: string | null; position: string } | null;
  media: Array<{
    id: string;
    media: {
      id: string;
      url: string;
      alt: string | null;
      mimeType?: string | null;
      fileSize?: number | null;
    };
  }>;
};

type SelectedPortalFile = {
  id: string;
  file: File;
  origin: PortalMediaSourceType;
  previewUrl: string | null;
  isImage: boolean;
};

const defaultMediaMaterialType: PortalMediaMaterialType = "GALLERY";

function formatDate(value: Date | string) {
  return new Intl.DateTimeFormat("sr-Latn-RS", {
    day: "2-digit",
    month: "long",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(value));
}

function formatFileSize(fileSize: number) {
  if (fileSize < 1024 * 1024) {
    return `${Math.max(1, Math.round(fileSize / 102.4) / 10)} KB`;
  }

  return `${Math.round(fileSize / 104857.6) / 10} MB`;
}

function isImageFile(file: File) {
  return file.type.startsWith("image/");
}

function isRenderableImage(mimeType?: string | null, url?: string | null) {
  if (mimeType?.startsWith("image/")) {
    return true;
  }

  return Boolean(url && /\.(png|jpe?g|webp|gif|svg)$/i.test(url));
}

function makeUploadId(origin: PortalMediaSourceType, file: File, index: number) {
  return `${origin}-${file.name}-${file.lastModified}-${index}-${Math.random()
    .toString(36)
    .slice(2, 8)}`;
}

export function PortalRequestCenter({
  planOptions,
  placementOptions,
  requests,
}: {
  planOptions: PlanOption[];
  placementOptions: PlacementOption[];
  requests: PortalRequestItem[];
}) {
  const router = useRouter();
  const searchParams = useSearchParams();
  const [isPending, startTransition] = useTransition();
  const [message, setMessage] = useState<string | null>(null);
  const [draft, setDraft] = useState({
    type: "PROFILE_UPDATE",
    title: "",
    message: "",
    requestedPlanId: "",
    requestedPlacementId: "",
    payload: "",
  });
  const [mediaMaterialType, setMediaMaterialType] =
    useState<PortalMediaMaterialType>(defaultMediaMaterialType);
  const [files, setFiles] = useState<SelectedPortalFile[]>([]);
  const [nativeMediaEnabled, setNativeMediaEnabled] = useState(false);

  const previewUrlsRef = useRef<string[]>([]);
  const prefillKeyRef = useRef<string | null>(null);
  const cameraInputRef = useRef<HTMLInputElement | null>(null);
  const galleryInputRef = useRef<HTMLInputElement | null>(null);
  const documentInputRef = useRef<HTMLInputElement | null>(null);

  const summary = useMemo(
    () => ({
      total: requests.length,
      open: requests.filter((item) => item.status === "NEW" || item.status === "IN_REVIEW").length,
      approved: requests.filter((item) => item.status === "APPROVED" || item.status === "COMPLETED")
        .length,
    }),
    [requests],
  );

  const isMediaRequest = draft.type === "MEDIA_UPLOAD";
  const selectedMeta = portalRequestTypeMeta[draft.type as keyof typeof portalRequestTypeMeta];
  const needsPlanSelect = draft.type === "PLAN_CONFIRMATION" || draft.type === "PLAN_RENEWAL";
  const needsPlacementSelect = draft.type === "PLACEMENT_REQUEST";
  const selectedMaterialMeta = portalMediaMaterialMeta[mediaMaterialType];

  const fileSummary = useMemo(() => {
    const sourceLabels = [...new Set(files.map((item) => item.origin))]
      .map((origin) => resolvePortalMediaSources({ sources: [origin] }))
      .flat();

    return {
      count: files.length,
      imageCount: files.filter((item) => item.isImage).length,
      documentCount: files.filter((item) => !item.isImage).length,
      sourceLabels,
    };
  }, [files]);

  useEffect(() => {
    return () => {
      for (const url of previewUrlsRef.current) {
        URL.revokeObjectURL(url);
      }
      previewUrlsRef.current = [];
    };
  }, []);

  useEffect(() => {
    setNativeMediaEnabled(isNativePartnerApp());
  }, []);

  function updateDraft<K extends keyof typeof draft>(key: K, value: (typeof draft)[K]) {
    setDraft((current) => ({ ...current, [key]: value }));
  }

  const clearFiles = useCallback(() => {
    for (const item of files) {
      if (item.previewUrl) {
        URL.revokeObjectURL(item.previewUrl);
      }
    }
    previewUrlsRef.current = [];
    setFiles([]);
  }, [files]);

  const applyTemplate = useCallback(
    (type: keyof typeof portalRequestTypeMeta) => {
      const nextTitle =
        type === "PROFILE_UPDATE"
          ? "Zahtev za izmenu profila"
          : type === "MEDIA_UPLOAD"
            ? "Novi media materijali za profil"
            : type === "PLAN_CONFIRMATION"
              ? "Potvrda ili upgrade paketa"
              : type === "PLAN_RENEWAL"
                ? "Obnova postojećeg paketa"
                : type === "PLACEMENT_REQUEST"
                  ? "Zahtev za novo isticanje"
                  : "Operativna podrška";

      const nextMessage =
        type === "PROFILE_UPDATE"
          ? "Potrebna je izmena javnih informacija na profilu. U nastavku navodim šta treba da se koriguje ili dopuni."
          : type === "MEDIA_UPLOAD"
            ? "Dostavljam nove vizuale za profil. Molim da logo, cover, galerija ili dokument budu pregledani i objavljeni."
            : type === "PLAN_CONFIRMATION"
              ? "Želim potvrdu ili upgrade aktivnog paketa i pregled novih komercijalnih prava za profil."
              : type === "PLAN_RENEWAL"
                ? "Potrebna je obnova postojećeg paketa kako bi profil zadržao aktivnu vidljivost."
                : type === "PLACEMENT_REQUEST"
                  ? "Želim dodatno isticanje profila i komercijalnu poziciju u odgovarajućem modulu ili regionu."
                  : "Potrebna mi je pomoć oko portala, računa, oglasa ili statusa profila.";

      if (type !== "MEDIA_UPLOAD") {
        clearFiles();
      }

      setDraft({
        type,
        title: nextTitle,
        message: nextMessage,
        requestedPlanId:
          type === "PLAN_CONFIRMATION" || type === "PLAN_RENEWAL" ? draft.requestedPlanId : "",
        requestedPlacementId: type === "PLACEMENT_REQUEST" ? draft.requestedPlacementId : "",
        payload: "",
      });
    },
    [clearFiles, draft.requestedPlacementId, draft.requestedPlanId],
  );

  useEffect(() => {
    const nextType = searchParams.get("requestType");
    if (!nextType || !(nextType in portalRequestTypeMeta)) {
      prefillKeyRef.current = null;
      return;
    }

    const nextTitle = searchParams.get("requestTitle");
    const nextMessage = searchParams.get("requestMessage");
    const nextPlanId = searchParams.get("requestedPlanId");
    const nextPlacementId = searchParams.get("requestedPlacementId");
    const nextPayload = searchParams.get("payload");
    const prefillKey = [nextType, nextTitle, nextMessage, nextPlanId, nextPlacementId, nextPayload]
      .filter(Boolean)
      .join("::");

    if (prefillKeyRef.current === prefillKey) {
      return;
    }

    prefillKeyRef.current = prefillKey;

    applyTemplate(nextType as keyof typeof portalRequestTypeMeta);
    setDraft((current) => ({
      ...current,
      type: nextType,
      title: nextTitle || current.title,
      message: nextMessage || current.message,
      requestedPlanId: nextPlanId || current.requestedPlanId,
      requestedPlacementId: nextPlacementId || current.requestedPlacementId,
      payload: nextPayload || current.payload,
    }));
    router.replace("/portal#zahtevi", { scroll: false });
  }, [applyTemplate, router, searchParams]);

  function buildSelectedFiles(fileList: FileList | null, origin: PortalMediaSourceType) {
    if (!fileList?.length) {
      return [];
    }

    return Array.from(fileList).map((file, index) => {
      const image = isImageFile(file);
      const previewUrl = image ? URL.createObjectURL(file) : null;

      if (previewUrl) {
        previewUrlsRef.current.push(previewUrl);
      }

      return {
        id: makeUploadId(origin, file, index),
        file,
        origin,
        previewUrl,
        isImage: image,
      } satisfies SelectedPortalFile;
    });
  }

  function appendFiles(fileList: FileList | null, origin: PortalMediaSourceType) {
    const nextFiles = buildSelectedFiles(fileList, origin);
    if (!nextFiles.length) {
      return;
    }

    setFiles((current) => [...current, ...nextFiles]);
    setMessage(null);
  }

  function appendPreparedFiles(
    pickedFiles: Array<{
      file: File;
      previewUrl: string | null;
      isImage: boolean;
    }>,
    origin: PortalMediaSourceType,
  ) {
    if (!pickedFiles.length) {
      return;
    }

    for (const item of pickedFiles) {
      if (item.previewUrl) {
        previewUrlsRef.current.push(item.previewUrl);
      }
    }

    setFiles((current) => [
      ...current,
      ...pickedFiles.map((item, index) => ({
        id: makeUploadId(origin, item.file, index),
        file: item.file,
        origin,
        previewUrl: item.previewUrl,
        isImage: item.isImage,
      })),
    ]);
    setMessage(null);
  }

  async function handleNativeCamera() {
    try {
      appendPreparedFiles([await captureNativePartnerPhoto()], "CAMERA");
    } catch (error) {
      setMessage(
        error instanceof Error ? error.message : "Otvaranje native kamere nije uspelo.",
      );
    }
  }

  async function handleNativeGallery() {
    try {
      appendPreparedFiles(await pickNativePartnerImages(), "GALLERY");
    } catch (error) {
      setMessage(
        error instanceof Error ? error.message : "Otvaranje native galerije nije uspelo.",
      );
    }
  }

  function removeFile(id: string) {
    setFiles((current) => {
      const target = current.find((item) => item.id === id);
      if (target?.previewUrl) {
        URL.revokeObjectURL(target.previewUrl);
        previewUrlsRef.current = previewUrlsRef.current.filter((url) => url !== target.previewUrl);
      }

      return current.filter((item) => item.id !== id);
    });
  }

  function buildMediaPayload() {
    return {
      version: "partner-media-v1",
      materialType: mediaMaterialType,
      sources: [...new Set(files.map((item) => item.origin))],
      attachmentCount: files.length,
      attachmentNames: files.map((item) => item.file.name),
      attachmentKinds: files.map((item) =>
        item.isImage ? "image" : item.file.type === "application/pdf" ? "pdf" : "document",
      ),
    };
  }

  function createPayload() {
    if (isMediaRequest) {
      return JSON.stringify(buildMediaPayload());
    }

    const selectedPlacement = placementOptions.find((item) => item.id === draft.requestedPlacementId);
    const placementPayload = selectedPlacement?.payload?.trim();
    const manualPayload = draft.payload.trim();

    if (!manualPayload && !placementPayload) {
      return undefined;
    }

    if (!manualPayload) {
      return placementPayload;
    }

    if (!placementPayload) {
      return manualPayload;
    }

    try {
      const parsedManual = JSON.parse(manualPayload) as Record<string, unknown>;
      const parsedPlacement = JSON.parse(placementPayload) as Record<string, unknown>;

      return JSON.stringify({
        ...parsedPlacement,
        ...parsedManual,
      });
    } catch {
      return manualPayload;
    }
  }

  function handleSubmit() {
    startTransition(async () => {
      try {
        if (isMediaRequest && files.length === 0) {
          throw new Error("Za media zahtev dodajte barem jedan prilog iz kamere, galerije ili dokumenta.");
        }

        const body = new FormData();
        body.set("type", draft.type);
        body.set("title", draft.title);
        body.set("message", draft.message);
        if (draft.requestedPlanId) {
          body.set("requestedPlanId", draft.requestedPlanId);
        }
        const selectedPlacement = placementOptions.find((item) => item.id === draft.requestedPlacementId);

        if (draft.requestedPlacementId && !selectedPlacement?.payload) {
          body.set("requestedPlacementId", draft.requestedPlacementId);
        }

        const payload = createPayload();
        if (payload) {
          body.set("payload", payload);
        }

        for (const item of files) {
          body.append("files", item.file);
        }

        const response = await fetch("/api/portal/requests", {
          method: "POST",
          body,
        });
        const result = (await response.json()) as { message?: string };
        if (!response.ok) {
          throw new Error(result.message || "Slanje portal zahteva nije uspelo.");
        }

        clearFiles();
        setMediaMaterialType(defaultMediaMaterialType);
        setDraft({
          type: "PROFILE_UPDATE",
          title: "",
          message: "",
          requestedPlanId: "",
          requestedPlacementId: "",
          payload: "",
        });
        setMessage("Zahtev je uspešno poslat i sada čeka admin pregled.");
        router.refresh();
      } catch (error) {
        setMessage(error instanceof Error ? error.message : "Slanje zahteva nije uspelo.");
      }
    });
  }

  return (
    <section id="zahtevi" className="space-y-6">
      <div className="partner-app-panel p-6">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <p className="eyebrow">Portal zahtevi</p>
            <h2 className="mt-3 font-display text-4xl font-semibold text-foreground">
              Self-service komunikacija sa admin timom
            </h2>
            <p className="mt-4 max-w-3xl text-sm leading-7 text-muted-foreground">
              Kroz portal pratite sve otvorene zahteve, šaljete izmene profila, nove vizuale i komercijalne upite bez dodatnog mail pinga ili telefonskog objašnjavanja.
            </p>
          </div>

          <div className="grid gap-3 sm:grid-cols-3">
            <div className="portal-metric">
              <div className="portal-metric-label">Ukupno zahteva</div>
              <div className="portal-metric-value">{summary.total}</div>
            </div>
            <div className="portal-metric">
              <div className="portal-metric-label">Otvoreno</div>
              <div className="portal-metric-value">{summary.open}</div>
            </div>
            <div className="portal-metric">
              <div className="portal-metric-label">Odobreno</div>
              <div className="portal-metric-value">{summary.approved}</div>
            </div>
          </div>
        </div>
      </div>

      <div className="grid gap-6 xl:grid-cols-[minmax(0,1fr)_440px]">
        <section className="partner-app-panel p-6">
          <div className="flex flex-wrap gap-3">
            {Object.entries(portalRequestTypeMeta).map(([type, item]) => (
              <button
                key={type}
                type="button"
                className="inline-toggle"
                data-active={draft.type === type}
                onClick={() => applyTemplate(type as keyof typeof portalRequestTypeMeta)}
              >
                {item.title}
              </button>
            ))}
          </div>

          {message ? (
            <div className="mt-5 rounded-[1.3rem] border border-primary/15 bg-primary/8 px-4 py-3 text-sm text-primary">
              {message}
            </div>
          ) : null}

          <div className="mt-5 space-y-4">
            <div className="note-banner">
              <p className="field-label">{selectedMeta.title}</p>
              <p className="mt-3 text-sm leading-7 text-muted-foreground">{selectedMeta.copy}</p>
            </div>

            <label className="field-shell">
              <span className="field-label">Naslov zahteva</span>
              <span className="field-hint">Kratak, jasan naslov po kojem admin tim odmah razume prioritet.</span>
              <input
                className="input-premium"
                placeholder={isMediaRequest ? "Na primer: Novi cover za prolećnu kampanju" : "Naslov zahteva"}
                value={draft.title}
                onChange={(event) => updateDraft("title", event.target.value)}
              />
            </label>

            <label className="field-shell">
              <span className="field-label">{isMediaRequest ? "Napomena admin timu" : "Opis zahteva"}</span>
              <span className="field-hint">
                {isMediaRequest
                  ? "Napišite šta treba da se zameni, objavi ili osveži. Na primer: ovaj cover ide na naslovni deo profila."
                  : "Detaljno napišite šta želite da bude izmenjeno, aktivirano ili potvrđeno."}
              </span>
              <textarea
                className="input-premium min-h-[170px] resize-y py-3"
                placeholder={
                  isMediaRequest
                    ? "Dodajte kratko objašnjenje: koji je materijal, gde ide i da li menja postojeći logo, cover ili galeriju."
                    : "Napišite jasan brief za admin tim: šta menjamo, koji je cilj, šta treba objaviti, produžiti ili istaknuti."
                }
                value={draft.message}
                onChange={(event) => updateDraft("message", event.target.value)}
              />
            </label>

            {isMediaRequest ? (
              <div className="space-y-4">
                <section className="field-shell">
                  <span className="field-label">Tip materijala</span>
                  <span className="field-hint">
                    Prvo birate šta šaljete, da bi admin tim odmah znao da li je u pitanju logo, cover, galerija ili dokument.
                  </span>
                  <div className="mt-4 grid gap-3 sm:grid-cols-2">
                    {(
                      Object.entries(portalMediaMaterialMeta) as Array<
                        [PortalMediaMaterialType, (typeof portalMediaMaterialMeta)[PortalMediaMaterialType]]
                      >
                    ).map(([type, item]) => (
                      <button
                        key={type}
                        type="button"
                        className="inline-toggle !justify-start !rounded-[1.25rem] !px-4 !py-4 !text-left !normal-case !tracking-normal"
                        data-active={mediaMaterialType === type}
                        onClick={() => setMediaMaterialType(type)}
                      >
                        <div className="flex items-start gap-3">
                          <div className="min-w-0">
                            <div className="font-semibold text-foreground">{item.title}</div>
                            <div className="mt-1 text-xs leading-6 text-muted-foreground">{item.copy}</div>
                          </div>
                        </div>
                      </button>
                    ))}
                  </div>
                </section>

                <section className="field-shell">
                  <div className="flex flex-wrap items-start justify-between gap-4">
                    <div>
                      <span className="field-label">Dodavanje priloga</span>
                      <p className="field-hint max-w-2xl">
                        Izaberite da li želite da odmah snimite kadar kamerom, uzmete materijal iz galerije ili pošaljete dokument poput cenovnika i PDF-a.
                      </p>
                    </div>
                    <div className="flex flex-wrap gap-2">
                      <span className="admin-chip !normal-case !tracking-normal">
                        Tip: {selectedMaterialMeta.title}
                      </span>
                      <span className="admin-chip !normal-case !tracking-normal">
                        Prilozi: {fileSummary.count}
                      </span>
                    </div>
                  </div>

                  <input
                    ref={cameraInputRef}
                    type="file"
                    accept="image/*"
                    capture="environment"
                    className="hidden"
                    onChange={(event) => {
                      appendFiles(event.target.files, "CAMERA");
                      event.currentTarget.value = "";
                    }}
                  />
                  <input
                    ref={galleryInputRef}
                    type="file"
                    accept="image/*"
                    multiple
                    className="hidden"
                    onChange={(event) => {
                      appendFiles(event.target.files, "GALLERY");
                      event.currentTarget.value = "";
                    }}
                  />
                  <input
                    ref={documentInputRef}
                    type="file"
                    accept="application/pdf,image/*"
                    multiple
                    className="hidden"
                    onChange={(event) => {
                      appendFiles(event.target.files, "DOCUMENTS");
                      event.currentTarget.value = "";
                    }}
                  />

                  <div className="mt-4 grid gap-3 md:grid-cols-3">
                    <button
                      type="button"
                      className="field-shell !rounded-[1.45rem] text-left transition hover:-translate-y-[1px]"
                      onClick={() => {
                        if (nativeMediaEnabled) {
                          void handleNativeCamera();
                          return;
                        }

                        cameraInputRef.current?.click();
                      }}
                    >
                      <div className="flex items-start gap-3">
                        <div className="min-w-0">
                          <div className="font-semibold text-foreground">Snimi kamerom</div>
                          <div className="mt-1 text-xs leading-6 text-muted-foreground">
                            Brzo fotografišite logo, lokal, tim ili promotivni materijal direktno iz aplikacije.
                          </div>
                        </div>
                      </div>
                    </button>

                    <button
                      type="button"
                      className="field-shell !rounded-[1.45rem] text-left transition hover:-translate-y-[1px]"
                      onClick={() => {
                        if (nativeMediaEnabled) {
                          void handleNativeGallery();
                          return;
                        }

                        galleryInputRef.current?.click();
                      }}
                    >
                      <div className="flex items-start gap-3">
                        <div className="min-w-0">
                          <div className="font-semibold text-foreground">Iz galerije</div>
                          <div className="mt-1 text-xs leading-6 text-muted-foreground">
                            {nativeMediaEnabled
                              ? "Otvorite native galeriju i dodajte više fotografija iz uređaja u jednom potezu."
                              : "Dodajte više slika odjednom iz telefona, bez ponovnog ulaska u admin panel."}
                          </div>
                        </div>
                      </div>
                    </button>

                    <button
                      type="button"
                      className="field-shell !rounded-[1.45rem] text-left transition hover:-translate-y-[1px]"
                      onClick={() => documentInputRef.current?.click()}
                    >
                      <div className="flex items-start gap-3">
                        <div className="min-w-0">
                          <div className="font-semibold text-foreground">Dodaj dokument</div>
                          <div className="mt-1 text-xs leading-6 text-muted-foreground">
                            Za cenovnike, PDF materijale, ponude, menije i druge dokumente koji prate profil.
                          </div>
                        </div>
                      </div>
                    </button>
                  </div>

                  {files.length ? (
                    <div className="mt-5 space-y-4">
                      <div className="flex flex-wrap items-center justify-between gap-3 rounded-[1.35rem] border border-border/80 bg-white/80 px-4 py-3">
                        <div className="text-sm leading-7 text-muted-foreground">
                          Spremno za slanje: <span className="font-semibold text-foreground">{fileSummary.count}</span>{" "}
                          priloga · slike {fileSummary.imageCount} · dokumenti {fileSummary.documentCount}
                        </div>
                        <div className="flex flex-wrap gap-2">
                          {fileSummary.sourceLabels.map((label) => (
                            <span key={label} className="admin-chip !normal-case !tracking-normal">
                              {label}
                            </span>
                          ))}
                          <button type="button" className="ghost-button !py-2 !text-sm" onClick={clearFiles}>
                            Obriši priloge
                          </button>
                        </div>
                      </div>

                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-3">
                        {files.map((item) => (
                          <article
                            key={item.id}
                            className="rounded-[1.35rem] border border-border/80 bg-white/82 p-3 shadow-[0_16px_34px_rgba(22,22,22,0.05)]"
                          >
                            <div className="flex items-center justify-between gap-3">
                              <span className="admin-chip !normal-case !tracking-normal">
                                {resolvePortalMediaSources({ sources: [item.origin] })[0] || "Prilog"}
                              </span>
                              <button
                                type="button"
                                className="text-xs font-semibold text-muted-foreground transition hover:text-danger"
                                onClick={() => removeFile(item.id)}
                              >
                                Ukloni
                              </button>
                            </div>
                            <div className="mt-3 overflow-hidden rounded-[1.1rem] border border-border/70 bg-accent/50">
                              {item.isImage && item.previewUrl ? (
                                <Image
                                  src={item.previewUrl}
                                  alt={item.file.name}
                                  width={520}
                                  height={360}
                                  className="h-40 w-full object-cover"
                                  unoptimized
                                />
                              ) : (
                                <div className="flex h-40 items-center justify-center" />
                              )}
                            </div>
                            <div className="mt-3 space-y-1">
                              <p className="line-clamp-2 text-sm font-semibold leading-6 text-foreground" title={item.file.name}>
                                {item.file.name}
                              </p>
                              <p className="text-xs uppercase tracking-[0.14em] text-muted-foreground">
                                {item.isImage ? "Slika" : item.file.type === "application/pdf" ? "PDF" : "Dokument"} ·{" "}
                                {formatFileSize(item.file.size)}
                              </p>
                            </div>
                          </article>
                        ))}
                      </div>
                    </div>
                  ) : (
                    <div className="mt-5 rounded-[1.35rem] border border-dashed border-border/90 bg-white/72 px-4 py-5 text-sm leading-7 text-muted-foreground">
                      Još nema priloga. Za {selectedMaterialMeta.title.toLowerCase()} koristite kameru, galeriju ili dokumente i pregledajte materijal pre slanja admin timu.
                    </div>
                  )}
                </section>
              </div>
            ) : null}

            {needsPlanSelect ? (
              <label className="field-shell">
                <span className="field-label">Traženi plan</span>
                <span className="field-hint">Odaberite plan koji želite da aktivirate, obnovite ili potvrdite.</span>
                <select
                  className="select-premium"
                  value={draft.requestedPlanId}
                  onChange={(event) => updateDraft("requestedPlanId", event.target.value)}
                >
                  <option value="">Odaberite plan</option>
                  {planOptions.map((plan) => (
                    <option key={plan.id} value={plan.id}>
                      {plan.nameSr} · {getTierAdminLabel(plan.tier)}
                    </option>
                  ))}
                </select>
              </label>
            ) : null}

            {needsPlacementSelect ? (
              <label className="field-shell">
                <span className="field-label">Traženo isticanje</span>
                <span className="field-hint">Odaberite placement koji želite da kupite ili obnovite.</span>
                <select
                  className="select-premium"
                  value={draft.requestedPlacementId}
                  onChange={(event) => updateDraft("requestedPlacementId", event.target.value)}
                >
                  <option value="">Odaberite isticanje</option>
                  {placementOptions.map((placement) => (
                    <option key={placement.id} value={placement.id}>
                      {placement.label}
                    </option>
                  ))}
                </select>
              </label>
            ) : null}

            {!isMediaRequest ? (
              <label className="field-shell">
                <span className="field-label">Napredni podaci (JSON, opciono)</span>
                <span className="field-hint">
                  Ako želite preciznu listu izmena, ovde možete dodati strukturirane podatke, na primer{" "}
                  <code>{'{"phone":"+381...","website":"https://..."}'}</code>.
                </span>
                <textarea
                  className="input-premium min-h-[120px] resize-y py-3"
                  placeholder='{"phone":"+381 60 123 4567","website":"https://www.kompanija.rs"}'
                  value={draft.payload}
                  onChange={(event) => updateDraft("payload", event.target.value)}
                />
              </label>
            ) : null}

            <div className="flex flex-wrap items-center justify-between gap-3 border-t border-border/70 pt-4">
              <p className="text-sm leading-6 text-muted-foreground">
                Admin tim će zahtev obraditi, ažurirati status i po potrebi generisati račun ili dodatnu notifikaciju.
              </p>
              <button type="button" className="primary-button" onClick={handleSubmit} disabled={isPending}>
                {isPending ? <Spinner className="h-4 w-4" /> : null}
                {isPending ? "Slanje..." : "Pošalji zahtev admin timu"}
              </button>
            </div>
          </div>
        </section>

        <section className="partner-app-panel p-6">
          <p className="eyebrow">Istorija zahteva</p>
          <div className="mt-4 space-y-4">
            {requests.length ? (
              requests.map((item) => {
                const mediaPayload = extractPortalMediaPayload(item.payload);
                const mediaSources = resolvePortalMediaSources(mediaPayload);

                return (
                  <article key={item.id} className="summary-item">
                    <div className="flex flex-wrap gap-2">
                      <span className="admin-chip !normal-case !tracking-normal">
                        {portalRequestTypeMeta[item.type as keyof typeof portalRequestTypeMeta]?.title || item.type}
                      </span>
                      <span className="admin-chip !normal-case !tracking-normal">
                        {getPortalRequestStatusLabel(item.status)}
                      </span>
                      {mediaPayload?.materialType ? (
                        <span className="admin-chip !normal-case !tracking-normal">
                          {getPortalMediaMaterialLabel(mediaPayload.materialType)}
                        </span>
                      ) : null}
                      {mediaSources.map((source) => (
                        <span key={`${item.id}-${source}`} className="admin-chip !normal-case !tracking-normal">
                          {source}
                        </span>
                      ))}
                    </div>
                    <h3 className="mt-3 text-lg font-semibold text-foreground">{item.title}</h3>
                    <p className="mt-2 text-sm leading-7 text-muted-foreground">{item.message}</p>
                    {item.requestedPlan ? (
                      <p className="mt-3 text-xs uppercase tracking-[0.14em] text-primary">
                        Plan: {item.requestedPlan.nameSr} · {getTierAdminLabel(item.requestedPlan.tier)}
                      </p>
                    ) : null}
                    {item.requestedPlacement ? (
                      <p className="mt-2 text-xs uppercase tracking-[0.14em] text-primary">
                        Isticanje: {item.requestedPlacement.label || item.requestedPlacement.position}
                      </p>
                    ) : null}
                    {item.media.length ? (
                      <div className="mt-4 grid gap-3 sm:grid-cols-2">
                        {item.media.map((entry) => {
                          const renderImage = isRenderableImage(entry.media.mimeType, entry.media.url);

                          return (
                            <div
                              key={entry.id}
                              className="overflow-hidden rounded-[1rem] border border-border/80 bg-white/80"
                            >
                              {renderImage ? (
                                <Image
                                  src={entry.media.url}
                                  alt={entry.media.alt || item.title}
                                  width={420}
                                  height={280}
                                  unoptimized
                                  className="h-28 w-full object-cover"
                                />
                              ) : (
                                <div className="flex h-28 items-center justify-center bg-accent/60" />
                              )}
                              <div className="px-3 py-2">
                                <p
                                  className="truncate text-sm font-semibold text-foreground"
                                  title={entry.media.alt || entry.media.url}
                                >
                                  {entry.media.alt || "Prilog portala"}
                                </p>
                                <p className="mt-1 text-xs uppercase tracking-[0.12em] text-muted-foreground">
                                  {renderImage ? "Vizual" : "Dokument"}
                                  {entry.media.fileSize ? ` · ${formatFileSize(entry.media.fileSize)}` : ""}
                                </p>
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    ) : null}
                    <p className="mt-4 text-xs uppercase tracking-[0.14em] text-muted-foreground">
                      {formatDate(item.createdAt)}
                    </p>
                  </article>
                );
              })
            ) : (
              <div className="summary-item text-sm leading-7 text-muted-foreground">
                Još nema portal zahteva. Ovde će se pojaviti izmene profila, media upload, renewal, placement i drugi komercijalni i operativni zahtevi.
              </div>
            )}
          </div>
        </section>
      </div>
    </section>
  );
}
