import { NextRequest, NextResponse } from 'next/server';
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
import { join, extname } from 'node:path';
import { createHash, randomUUID } from 'node:crypto';
import { getPublicBaseUrl } from '@/modules/sending/lib/public-base-url';
import { withAuth } from '@/core/auth';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

/**
 * Akzeptiert ein User-Upload-Bild als Hero (oder anderer inline-Asset).
 * Speichert in `public/assets/upload/{uuid}.{ext}` und returnt URL + Absolute-URL für Email.
 *
 * Validierung:
 * - Nur Bild-MIME-Types (image/png, image/jpeg, image/jpg, image/webp, image/gif)
 * - Max 8 MB (Email-Clients drosseln eh; > 8 MB bringt nichts und blockiert lange Uploads)
 *
 * Sicherheit:
 * - Dateiname wird VERWORFEN (User-Input, gefährlich) — wir nutzen UUID + Extension aus MIME
 * - Multipart-Form-Data via Next.js native `req.formData()` (kein extra Library nötig)
 */
const MAX_BYTES = 8 * 1024 * 1024; // 8 MB
const ALLOWED_MIME: Record<string, string> = {
  'image/png': '.png',
  'image/jpeg': '.jpg',
  'image/jpg': '.jpg',
  'image/webp': '.webp',
  'image/gif': '.gif',
};

const UPLOAD_DIR = join(process.cwd(), 'public', 'assets', 'upload');
const PUBLIC_PREFIX = '/assets/upload';

export const POST = withAuth(async (req: NextRequest, _ctx) => {
  try {
    const formData = await req.formData();
    const file = formData.get('file');

    if (!(file instanceof File)) {
      return NextResponse.json({ error: 'Kein File-Field — erwartet `file` im FormData' }, { status: 400 });
    }
    if (file.size === 0) {
      return NextResponse.json({ error: 'Datei ist leer' }, { status: 400 });
    }
    if (file.size > MAX_BYTES) {
      return NextResponse.json({
        error: `Datei zu groß: ${(file.size / 1024 / 1024).toFixed(1)} MB · Max ${MAX_BYTES / 1024 / 1024} MB`,
      }, { status: 413 });
    }
    const ext = ALLOWED_MIME[file.type];
    if (!ext) {
      return NextResponse.json({
        error: `MIME nicht unterstützt: ${file.type} · Erlaubt: ${Object.keys(ALLOWED_MIME).join(', ')}`,
      }, { status: 415 });
    }

    if (!existsSync(UPLOAD_DIR)) mkdirSync(UPLOAD_DIR, { recursive: true });

    // UUID + Hash der ersten Bytes → deterministischer Pfad bei identischen Bytes (verhindert Duplikate)
    const buf = Buffer.from(await file.arrayBuffer());
    const hash = createHash('sha256').update(buf).digest('hex').slice(0, 16);
    const filename = `${hash}-${randomUUID().slice(0, 8)}${ext}`;
    const localPath = join(UPLOAD_DIR, filename);
    writeFileSync(localPath, buf);

    const url = `${PUBLIC_PREFIX}/${filename}`;
    const absoluteUrl = `${getPublicBaseUrl(req)}${url}`;

    return NextResponse.json({
      ok: true,
      hero: {
        url,
        absoluteUrl,
        bytes: buf.byteLength,
      },
    });
  } catch (err) {
    console.error('[/api/upload-image] error:', err);
    return NextResponse.json(
      { error: err instanceof Error ? err.message : 'Internal error' },
      { status: 500 },
    );
  }
});
