import { apiClient } from '../api/client';

/** A placeholder field extracted from a template's .docx (`{{ key }}`). */
export type TemplateField = { key: string; label: string; type: string };

/** Admin-managed document template (mirrors be0 `TemplateOut`). */
export type DocumentTemplate = {
  id: string;
  name: string;
  description?: string | null;
  fields: TemplateField[];
  originalFilename?: string | null;
  isActive: boolean;
  createdAt?: string | null;
  updatedAt?: string | null;
};

export type RenderFormat = 'pdf' | 'docx';

export const TEMPLATE_DOCX_MIME =
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
export const TEMPLATE_PDF_MIME = 'application/pdf';

const BASE = '/api/v1/templates';

/** Authed: list templates. Non-admin sees active only; admin sees all. */
export function listTemplates(): Promise<DocumentTemplate[]> {
  return apiClient.get<DocumentTemplate[]>(BASE);
}

export function getTemplate(id: string): Promise<DocumentTemplate> {
  return apiClient.get<DocumentTemplate>(`${BASE}/${encodeURIComponent(id)}`);
}

/** Admin: upload a .docx → backend extracts its `{{placeholders}}` and stores it. */
export function createTemplate(input: {
  name: string;
  description?: string;
  file: File;
}): Promise<DocumentTemplate> {
  const fd = new FormData();
  fd.append('name', input.name);
  fd.append('description', input.description ?? '');
  fd.append('file', input.file, input.file.name);
  return apiClient.post<DocumentTemplate>(BASE, fd);
}

/** Admin: update metadata (name / description / active). */
export function updateTemplate(
  id: string,
  patch: { name?: string; description?: string; isActive?: boolean },
): Promise<DocumentTemplate> {
  return apiClient.put<DocumentTemplate>(`${BASE}/${encodeURIComponent(id)}`, patch);
}

/** Admin: soft-delete by default; `hard` removes the row + MinIO object. */
export function deleteTemplate(
  id: string,
  opts: { hard?: boolean } = {},
): Promise<{ ok: boolean; hardDeleted: boolean }> {
  return apiClient.delete(`${BASE}/${encodeURIComponent(id)}`, {
    params: opts.hard ? { hard: true } : undefined,
  });
}

/** Authed: fill the template with `values` → PDF (default) or DOCX bytes. */
export function renderTemplate(
  id: string,
  values: Record<string, unknown>,
  format: RenderFormat = 'pdf',
): Promise<ArrayBuffer> {
  return apiClient.postArrayBuffer(
    `${BASE}/${encodeURIComponent(id)}/render`,
    { values, format },
    { timeout: 180_000 },
  );
}

/** Admin: download the raw .docx template file. */
export function downloadTemplateFile(id: string): Promise<ArrayBuffer> {
  return apiClient.get<ArrayBuffer>(`${BASE}/${encodeURIComponent(id)}/file`, {
    responseType: 'arraybuffer',
  });
}

/** Browser helper: turn raw bytes into an object URL (for inline preview); caller revokes it. */
export function arrayBufferToObjectUrl(buf: ArrayBuffer, mime: string): string {
  return URL.createObjectURL(new Blob([buf], { type: mime }));
}

/** Browser helper: trigger a download from raw bytes. */
export function saveArrayBufferAs(buf: ArrayBuffer, filename: string, mime: string): void {
  const url = arrayBufferToObjectUrl(buf, mime);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  a.remove();
  setTimeout(() => URL.revokeObjectURL(url), 1000);
}
