import api from "./api";
import type {
  ReportTemplateDto,
  ReportFontDto,
  ReportImageDto,
  GenerateReportRequest,
  PreviewReportRequest,
  DataSchemaDto,
  DatasetTypeDto,
  EntityListItemDto,
  VirtualDatasetDto,
  VirtualDatasetConfiguration,
  VirtualDatasetValidationResult,
  CreateVirtualDatasetRequest,
  UpdateVirtualDatasetRequest,
} from "../types/report";

// Templates
export const reportTemplateService = {
  getAll: async (categoria?: string): Promise<ReportTemplateDto[]> => {
    const params = categoria ? { categoria } : {};
    const response = await api.get("/report-templates", { params });
    return response.data;
  },

  getById: async (id: number): Promise<ReportTemplateDto> => {
    const response = await api.get(`/report-templates/${id}`);
    return response.data;
  },

  create: async (
    template: Partial<ReportTemplateDto>,
  ): Promise<ReportTemplateDto> => {
    const response = await api.post("/report-templates", template);
    return response.data;
  },

  update: async (
    id: number,
    template: Partial<ReportTemplateDto>,
  ): Promise<ReportTemplateDto> => {
    const response = await api.put(`/report-templates/${id}`, template);
    return response.data;
  },

  delete: async (id: number): Promise<void> => {
    await api.delete(`/report-templates/${id}`);
  },

  clone: async (id: number): Promise<ReportTemplateDto> => {
    const response = await api.post(`/report-templates/${id}/clone`);
    return response.data;
  },

  export: async (id: number): Promise<Blob> => {
    const response = await api.get(`/report-templates/${id}/export`, {
      responseType: "blob",
    });
    return response.data;
  },

  import: async (file: File): Promise<ReportTemplateDto> => {
    const formData = new FormData();
    formData.append("file", file);
    const response = await api.post("/report-templates/import", formData, {
      headers: { "Content-Type": "multipart/form-data" },
    });
    return response.data;
  },

  getCategories: async (): Promise<string[]> => {
    const response = await api.get("/report-templates/categories");
    return response.data;
  },
};

// Fonts
export const reportFontService = {
  getAll: async (): Promise<ReportFontDto[]> => {
    const response = await api.get("/report-resources/fonts");
    return response.data;
  },

  getById: async (id: number): Promise<ReportFontDto> => {
    const response = await api.get(`/report-resources/fonts/${id}`);
    return response.data;
  },

  upload: async (
    nome: string,
    fontFamily: string,
    fontStyle: string,
    file: File,
  ): Promise<ReportFontDto> => {
    const formData = new FormData();
    formData.append("nome", nome);
    formData.append("fontFamily", fontFamily);
    formData.append("fontStyle", fontStyle);
    formData.append("file", file);
    const response = await api.post("/report-resources/fonts", formData, {
      headers: { "Content-Type": "multipart/form-data" },
    });
    return response.data;
  },

  delete: async (id: number): Promise<void> => {
    await api.delete(`/report-resources/fonts/${id}`);
  },

  getFamilies: async (): Promise<string[]> => {
    const response = await api.get("/report-resources/fonts/families");
    return response.data;
  },
};

// Images
export const reportImageService = {
  getAll: async (categoria?: string): Promise<ReportImageDto[]> => {
    const params = categoria ? { categoria } : {};
    const response = await api.get("/report-resources/images", { params });
    return response.data;
  },

  getById: async (id: number): Promise<ReportImageDto> => {
    const response = await api.get(`/report-resources/images/${id}`);
    return response.data;
  },

  upload: async (
    nome: string,
    categoria: string,
    file: File,
  ): Promise<ReportImageDto> => {
    const formData = new FormData();
    formData.append("nome", nome);
    formData.append("categoria", categoria);
    formData.append("file", file);
    const response = await api.post("/report-resources/images", formData, {
      headers: { "Content-Type": "multipart/form-data" },
    });
    return response.data;
  },

  update: async (
    id: number,
    data: Partial<ReportImageDto>,
  ): Promise<ReportImageDto> => {
    const response = await api.put(`/report-resources/images/${id}`, data);
    return response.data;
  },

  delete: async (id: number): Promise<void> => {
    await api.delete(`/report-resources/images/${id}`);
  },

  getCategories: async (): Promise<string[]> => {
    const response = await api.get("/report-resources/images/categories");
    return response.data;
  },
};

// Report Generation
export const reportGeneratorService = {
  generate: async (request: GenerateReportRequest): Promise<Blob> => {
    const response = await api.post("/reports/generate", request, {
      responseType: "blob",
    });
    return response.data;
  },

  generateEvento: async (
    eventoId: number,
    templateId?: number,
  ): Promise<Blob> => {
    const params = templateId ? { templateId } : {};
    const response = await api.get(`/reports/evento/${eventoId}`, {
      params,
      responseType: "blob",
    });
    return response.data;
  },

  preview: async (request: PreviewReportRequest): Promise<Blob> => {
    const response = await api.post("/reports/preview", request, {
      responseType: "blob",
    });
    return response.data;
  },

  getSchema: async (datasetId: string): Promise<DataSchemaDto> => {
    const response = await api.get(`/reports/schema/${datasetId}`);
    return response.data;
  },

  getAvailableDatasets: async (): Promise<DatasetTypeDto[]> => {
    const response = await api.get("/reports/datasets");
    return response.data;
  },

  getEntitiesForDataset: async (
    datasetId: string,
  ): Promise<EntityListItemDto[]> => {
    const response = await api.get(`/reports/datasets/${datasetId}/entities`);
    return response.data;
  },
};

// Virtual Datasets
export const virtualDatasetService = {
  getAll: async (categoria?: string): Promise<VirtualDatasetDto[]> => {
    const params = categoria ? { categoria } : {};
    const response = await api.get("/virtual-datasets", { params });
    return response.data;
  },

  getById: async (id: number): Promise<VirtualDatasetDto> => {
    const response = await api.get(`/virtual-datasets/${id}`);
    return response.data;
  },

  getByName: async (nome: string): Promise<VirtualDatasetDto> => {
    const response = await api.get(`/virtual-datasets/by-name/${nome}`);
    return response.data;
  },

  create: async (
    request: CreateVirtualDatasetRequest,
  ): Promise<VirtualDatasetDto> => {
    const response = await api.post("/virtual-datasets", request);
    return response.data;
  },

  update: async (
    id: number,
    request: UpdateVirtualDatasetRequest,
  ): Promise<VirtualDatasetDto> => {
    const response = await api.put(`/virtual-datasets/${id}`, request);
    return response.data;
  },

  delete: async (id: number): Promise<void> => {
    await api.delete(`/virtual-datasets/${id}`);
  },

  clone: async (id: number): Promise<VirtualDatasetDto> => {
    const response = await api.post(`/virtual-datasets/${id}/clone`);
    return response.data;
  },

  getCategories: async (): Promise<string[]> => {
    const response = await api.get("/virtual-datasets/categories");
    return response.data;
  },

  validate: async (
    config: VirtualDatasetConfiguration,
  ): Promise<VirtualDatasetValidationResult> => {
    const response = await api.post("/virtual-datasets/validate", config);
    return response.data;
  },

  getSchema: async (
    config: VirtualDatasetConfiguration,
  ): Promise<DataSchemaDto> => {
    const response = await api.post("/virtual-datasets/schema", config);
    return response.data;
  },
};

// Helper to download blob as file
export function downloadBlob(blob: Blob, filename: string): void {
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  window.URL.revokeObjectURL(url);
}

// Helper to open blob in new tab (for PDF preview)
export function openBlobInNewTab(blob: Blob): void {
  const url = window.URL.createObjectURL(blob);
  window.open(url, "_blank");
}
