import type { APIRoute } from 'astro';
import { writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import { randomBytes } from 'node:crypto';
import { getDb } from '../../../../../lib/db';
import { getEnv } from '../../../../../lib/env';
import { invalidateContentCache } from '../../../../../lib/content';
import { validateUploadFile } from '../../../../../lib/upload-rules';
export const prerender = false;

const json = (status: number, body: object) =>
  new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' } });

// Difesa in profondità: oggi i tag arrivano solo dal seed, ma il nome file deriva
// dal tag — vincolarne il formato evita sorprese se in futuro i tag diventano dinamici.
const TAG_RE = /^[a-z0-9][a-z0-9.-]*$/;

function findImageTag(tag: string): { ok: true } | { ok: false; status: number; error: string } {
  if (!TAG_RE.test(tag)) return { ok: false, status: 400, error: 'Tag non valido.' };
  const row = getDb().prepare('SELECT type FROM content_blocks WHERE tag = ?').get(tag) as { type: string } | undefined;
  if (!row) return { ok: false, status: 404, error: 'Tag inesistente.' };
  if (row.type !== 'image') return { ok: false, status: 400, error: 'Il tag non è di tipo immagine.' };
  return { ok: true };
}

export const POST: APIRoute = async ({ params, request, locals }) => {
  const tag = params.tag ?? '';
  const found = findImageTag(tag);
  if (!found.ok) return json(found.status, { error: found.error });
  const form = await request.formData().catch(() => null);
  const checked = validateUploadFile(form?.get('file'));
  if (!checked.ok) return json(400, { error: checked.error });
  const dir = join(getEnv('UPLOADS_DIR', 'uploads'), 'content');
  await mkdir(dir, { recursive: true });
  const name = `${tag.replaceAll('.', '-')}-${Date.now()}-${randomBytes(4).toString('hex')}${checked.ext}`;
  await writeFile(join(dir, name), Buffer.from(await checked.file.arrayBuffer()));
  getDb().prepare(
    `UPDATE content_blocks SET value = ?, updated_at = datetime('now'), updated_by = ? WHERE tag = ?`
  ).run(`content/${name}`, locals.user!.username, tag);
  invalidateContentCache();
  return json(200, { url: `/uploads/content/${name}` });
};

export const DELETE: APIRoute = ({ params, locals }) => {
  const tag = params.tag ?? '';
  const found = findImageTag(tag);
  if (!found.ok) return json(found.status, { error: found.error });
  getDb().prepare(
    `UPDATE content_blocks SET value = '', updated_at = datetime('now'), updated_by = ? WHERE tag = ?`
  ).run(locals.user!.username, tag);
  invalidateContentCache();
  return json(200, { ok: true });
};
