import { env } from "@/lib/runtime-env";
import { createServerProductionSvg } from "@/lib/production-svg-server";

type ProductionType = "sign" | "neon";
type Row = Record<string, string | number | boolean | null>;

export type StoredProductionSvg = {
  file: Row;
  created: boolean;
  warning: string;
  sourceMode: "uploaded-vector" | "generated-text";
};

export async function ensureStoredProductionSvg(
  requestType: ProductionType,
  requestId: number,
): Promise<StoredProductionSvg> {
  const project = requestType === "sign"
    ? await env.DB.prepare(`SELECT id, reference, profile_code, sign_text, width_cm, height_cm, letter_spacing_cm,
      depth_mm, font, sign_color, logo_key, logo_type FROM quote_requests WHERE id = ?`)
      .bind(requestId).first<Row>()
    : await env.DB.prepare(`SELECT id, reference, neon_text, font, width_cm, height_cm, tube_mm, color,
      design_key, design_type FROM neon_quote_requests WHERE id = ?`)
      .bind(requestId).first<Row>();
  if (!project) throw new Error("Projet introuvable.");

  const sourceKey = requestType === "sign" ? project.logo_key : project.design_key;
  const sourceType = String(requestType === "sign" ? project.logo_type : project.design_type);
  const vectorSource = sourceKey && sourceType === "image/svg+xml"
    ? await env.MEDIA.get(String(sourceKey))
    : null;
  const uploadedSvg = vectorSource ? new TextDecoder().decode(vectorSource.body) : "";
  const generated = await createServerProductionSvg(project, {
    uploadedSvg,
    rasterSource: Boolean(sourceKey) && sourceType !== "image/svg+xml",
    invalidVectorSource: Boolean(sourceKey) && sourceType === "image/svg+xml" && !uploadedSvg,
  });

  const latest = await env.DB.prepare(`SELECT * FROM project_files
    WHERE request_type = ? AND request_id = ? AND category = 'production'
      AND content_type = 'image/svg+xml' AND label LIKE 'SVG production automatique%'
    ORDER BY created_at DESC, id DESC LIMIT 1`)
    .bind(requestType, requestId).first<Row>();
  if (latest) {
    const object = await env.MEDIA.get(String(latest.storage_key));
    if (object && new TextDecoder().decode(object.body) === generated.svg) {
      return { file: latest, created: false, warning: generated.warning, sourceMode: generated.sourceMode };
    }
  }

  const count = await env.DB.prepare(`SELECT COUNT(*) AS total FROM project_files
    WHERE request_type = ? AND request_id = ? AND category = 'production'
      AND content_type = 'image/svg+xml' AND label LIKE 'SVG production automatique%'`)
    .bind(requestType, requestId).first<{ total: number }>();
  const version = Number(count?.total ?? 0) + 1;
  const versionLabel = String(version).padStart(2, "0");
  const reference = safeName(String(project.reference || `${requestType}-${requestId}`));
  const fileName = `${reference}-production-v${versionLabel}.svg`;
  const storageKey = `projects/${requestType}/${requestId}/production-v${versionLabel}-${crypto.randomUUID()}.svg`;
  const shareToken = crypto.randomUUID().replaceAll("-", "") + crypto.randomUUID().replaceAll("-", "").slice(0, 16);
  const label = `SVG production automatique · v${versionLabel}${generated.warning ? " · SOURCE RASTER À CONTRÔLER" : ""}`;
  const bytes = new TextEncoder().encode(generated.svg);
  await env.MEDIA.put(storageKey, bytes, {
    httpMetadata: { contentType: "image/svg+xml" },
    customMetadata: {
      generated: "true",
      sourceMode: generated.sourceMode,
      version: String(version),
      warning: generated.warning,
    },
  });
  try {
    const result = await env.DB.prepare(`INSERT INTO project_files
      (request_type, request_id, label, category, storage_key, file_name, content_type, size_bytes, factory_visible, share_token, created_at)
      VALUES (?, ?, ?, 'production', ?, ?, 'image/svg+xml', ?, 1, ?, ?)`)
      .bind(requestType, requestId, label, storageKey, fileName, bytes.byteLength, shareToken, Date.now()).run();
    const file = await env.DB.prepare("SELECT * FROM project_files WHERE id = ?")
      .bind(result.meta.last_row_id).first<Row>();
    if (!file) throw new Error("Fichier SVG introuvable après création.");
    return { file, created: true, warning: generated.warning, sourceMode: generated.sourceMode };
  } catch (error) {
    await env.MEDIA.delete(storageKey).catch(() => undefined);
    throw error;
  }
}

function safeName(value: string) {
  return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 100) || "projet";
}
