import { createClient, type FileStat } from "webdav";
import sharp from "sharp";

const baseURL = process.env.NEXTCLOUD_BASE_URL;
const username = process.env.NEXTCLOUD_USER;
const password = process.env.NEXTCLOUD_APP_PASSWORD;

if (!baseURL || !username || !password) {
  throw new Error("Nextcloud-Zugangsdaten fehlen (.env.local)");
}

// WebDAV-Root eines Nutzers, z. B. "/[PHOTOGRAPHY]/<Kunde>" für Kundenordner.
export const nextcloud = createClient(`${baseURL}/remote.php/dav/files/${username}`, {
  username,
  password,
});

export const PHOTOGRAPHY_ROOT = process.env.NEXTCLOUD_PHOTOGRAPHY_ROOT ?? "/[PHOTOGRAPHY]";

const IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp"];

export type NextcloudEntry = { name: string; path: string; isDirectory: boolean };

// { numeric: true } sortiert natürlich statt als reinen String-Vergleich —
// ohne das käme z. B. "Juan_10.jpg" vor "Juan_7.jpg" (Bug-Report Till,
// 26.09.2026), weil "1" < "7" als einzelnes Zeichen verglichen wird,
// unabhängig von der tatsächlichen Zahl dahinter. Einziger Sortier-Ort für
// Nextcloud-Einträge — Admin- und Kunden-Ansicht laufen beide über
// listFolder()/listFolderImages(), ein Fix hier reicht für beide.
export async function listFolder(path: string): Promise<NextcloudEntry[]> {
  const items = (await nextcloud.getDirectoryContents(path)) as FileStat[];
  return items
    .map((item) => ({ name: item.basename, path: item.filename, isDirectory: item.type === "directory" }))
    .sort((a, b) => (a.isDirectory === b.isDirectory ? a.name.localeCompare(b.name, undefined, { numeric: true }) : a.isDirectory ? -1 : 1));
}

export async function listFolderImages(path: string): Promise<string[]> {
  const entries = await listFolder(path);
  return entries
    .filter((e) => !e.isDirectory && IMAGE_EXTENSIONS.some((ext) => e.name.toLowerCase().endsWith(ext)))
    .map((e) => e.name);
}

// Nextclouds eigener Vorschaubild-Dienst — deutlich schneller/kleiner als das
// Originalfoto zu laden, nutzt dieselben WebDAV-Zugangsdaten.
export async function fetchPreview(filePath: string, size = 480): Promise<Buffer> {
  const url = `${baseURL}/index.php/core/preview.png?file=${encodeURIComponent(filePath)}&x=${size}&y=${size}&a=1`;
  const auth = Buffer.from(`${username}:${password}`).toString("base64");
  const res = await fetch(url, { headers: { Authorization: `Basic ${auth}` } });
  if (!res.ok) throw new Error(`Nextcloud-Vorschau fehlgeschlagen (${res.status})`);
  return Buffer.from(await res.arrayBuffer());
}

export async function fetchOriginal(filePath: string): Promise<Buffer> {
  const content = await nextcloud.getFileContents(filePath);
  return Buffer.from(content as ArrayBuffer);
}

// Nextclouds Vorschaubild-Dienst liefert bei manchen Dateipfaden (beobachtet
// bei eckigen Klammern in Ordnernamen, z. B. "[FOTOS]" — genau das in diesem
// Nextcloud verwendete Namensschema) einen 404, obwohl dieselbe Datei per
// WebDAV (fetchOriginal) problemlos abrufbar ist — vermutlich ein Nextcloud-
// seitiges Encoding-/Routing-Problem mit diesen Zeichen, nicht behebbar von
// hier aus. Deshalb bei einem Fehlschlag der schnellen Vorschau immer auf
// das Originalfoto + lokales Verkleinern mit sharp zurückfallen, statt die
// ganze Anfrage scheitern zu lassen.
export async function fetchPreviewSafe(filePath: string, size = 480): Promise<Buffer> {
  try {
    return await fetchPreview(filePath, size);
  } catch {
    const original = await fetchOriginal(filePath);
    return sharp(original).rotate().resize({ width: size, height: size, fit: "inside", withoutEnlargement: true }).jpeg({ quality: 85 }).toBuffer();
  }
}
