import apiClient from '../apiClient';
import type { ExistenciaPapelDto } from '../../models/dtos/Reportes/ExistenciaPapelDto';
import type { MovimientoBobinasDto } from '../../models/dtos/Reportes/MovimientoBobinasDto';
import type { MovimientoBobinasPorEstadoResponseDto } from '../../models/dtos/Reportes/MovimientoBobinasPorEstadoResponseDto';
import type { ListadoDistribucionGeneralResponseDto } from '../../models/dtos/Reportes/ListadoDistribucionGeneralResponseDto';
import type { ListadoDistribucionCanillasResponseDto } from '../../models/dtos/Reportes/ListadoDistribucionCanillasResponseDto';
import type { ListadoDistribucionCanillasImporteDto } from '../../models/dtos/Reportes/ListadoDistribucionCanillasImporteDto';
import type { VentaMensualSecretariaElDiaDto } from '../../models/dtos/Reportes/VentaMensualSecretariaElDiaDto';
import type { VentaMensualSecretariaElPlataDto } from '../../models/dtos/Reportes/VentaMensualSecretariaElPlataDto';
import type { VentaMensualSecretariaTirDevoDto } from '../../models/dtos/Reportes/VentaMensualSecretariaTirDevoDto';
import type { ReporteDistribucionCanillasResponseDto } from '../../models/dtos/Reportes/ReporteDistribucionCanillasResponseDto';
import type { TiradasPublicacionesSeccionesDto } from '../../models/dtos/Reportes/TiradasPublicacionesSeccionesDto';
import type { ConsumoBobinasSeccionDto } from '../../models/dtos/Reportes/ConsumoBobinasSeccionDto';
import type { ConsumoBobinasPublicacionDto } from '../../models/dtos/Reportes/ConsumoBobinasPublicacionDto';
import type { ComparativaConsumoBobinasDto } from '../../models/dtos/Reportes/ComparativaConsumoBobinasDto';
import type { ReporteCuentasDistribuidorResponseDto } from '../../models/dtos/Reportes/ReporteCuentasDistribuidorResponseDto';
import type { ListadoDistribucionDistribuidoresResponseDto } from '../../models/dtos/Reportes/ListadoDistribucionDistribuidoresResponseDto';
import type { ControlDevolucionesDataResponseDto } from '../../models/dtos/Reportes/ControlDevolucionesDataResponseDto';
import type { NovedadesCanillasReporteDto } from '../../models/dtos/Reportes/NovedadesCanillasReporteDto';
import type { CanillaGananciaReporteDto } from '../../models/dtos/Reportes/CanillaGananciaReporteDto';
import type { ListadoDistCanMensualDiariosDto } from '../../models/dtos/Reportes/ListadoDistCanMensualDiariosDto';
import type { ListadoDistCanMensualPubDto } from '../../models/dtos/Reportes/ListadoDistCanMensualPubDto';
import axios from 'axios';

interface GetExistenciaPapelParams {
  fechaDesde: string; // yyyy-MM-dd
  fechaHasta: string; // yyyy-MM-dd
  idPlanta?: number | null;
  consolidado: boolean;
}

interface GetNovedadesCanillasParams {
  idEmpresa: number;
  fechaDesde: string; // yyyy-MM-dd
  fechaHasta: string; // yyyy-MM-dd
}

interface GetListadoDistMensualParams {
  fechaDesde: string; // yyyy-MM-dd
  fechaHasta: string; // yyyy-MM-dd
  esAccionista: boolean;
}

const getExistenciaPapelPdf = async (params: GetExistenciaPapelParams): Promise<Blob> => {
  const queryParams: Record<string, string | number | boolean> = {
    fechaDesde: params.fechaDesde,
    fechaHasta: params.fechaHasta,
    consolidado: params.consolidado,
  };
  if (params.idPlanta && !params.consolidado) {
    queryParams.idPlanta = params.idPlanta;
  }

  const response = await apiClient.get('/reportes/existencia-papel/pdf', {
    params: queryParams,
    responseType: 'blob', // ¡Importante para descargar archivos!
  });
  return response.data; // response.data será un Blob
};

const getExistenciaPapel = async (params: GetExistenciaPapelParams): Promise<ExistenciaPapelDto[]> => {
  // Construir los query params, omitiendo idPlanta si es consolidado o no está definido
  const queryParams: Record<string, string | number | boolean> = {
    fechaDesde: params.fechaDesde,
    fechaHasta: params.fechaHasta,
    consolidado: params.consolidado,
  };
  if (params.idPlanta && !params.consolidado) {
    queryParams.idPlanta = params.idPlanta;
  }

  const response = await apiClient.get<ExistenciaPapelDto[]>('/reportes/existencia-papel', { params: queryParams });
  return response.data;
};

const getMovimientoBobinas = async (params: {
  fechaDesde: string;
  fechaHasta: string;
  idPlanta: number;
}): Promise<MovimientoBobinasDto[]> => {
  const response = await apiClient.get<MovimientoBobinasDto[]>('/reportes/movimiento-bobinas', { params });
  return response.data;
};

const getMovimientoBobinasPdf = async (params: {
  fechaDesde: string;
  fechaHasta: string;
  idPlanta: number;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/movimiento-bobinas/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getMovimientoBobinasEstado = async (params: {
  fechaDesde: string;
  fechaHasta: string;
  idPlanta: number;
}): Promise<MovimientoBobinasPorEstadoResponseDto> => { // <- Devuelve el DTO combinado
  const response = await apiClient.get<MovimientoBobinasPorEstadoResponseDto>('/reportes/movimiento-bobinas-estado', { params });
  return response.data;
};

const getMovimientoBobinasEstadoPdf = async (params: {
  fechaDesde: string;
  fechaHasta: string;
  idPlanta: number;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/movimiento-bobinas-estado/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getListadoDistribucionGeneral = async (params: {
  idPublicacion: number;
  fechaDesde: string; // YYYY-MM-DD (primer día del mes)
  fechaHasta: string; // YYYY-MM-DD (último día del mes)
}): Promise<ListadoDistribucionGeneralResponseDto> => {
  const response = await apiClient.get<ListadoDistribucionGeneralResponseDto>('/reportes/listado-distribucion-general', { params });
  return response.data;
};

const getListadoDistribucionGeneralPdf = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/listado-distribucion-general/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getListadoDistribucionCanillas = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<ListadoDistribucionCanillasResponseDto> => {
  const response = await apiClient.get<ListadoDistribucionCanillasResponseDto>('/reportes/listado-distribucion-canillas', { params });
  return response.data;
};


const getListadoDistribucionCanillasPdf = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/listado-distribucion-canillas/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getListadoDistribucionCanillasImporte = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
  esAccionista: boolean;
}): Promise<ListadoDistribucionCanillasImporteDto[]> => {
  const response = await apiClient.get<ListadoDistribucionCanillasImporteDto[]>('/reportes/listado-distribucion-canillas-importe', { params });
  return response.data;
};

const getListadoDistribucionCanillasImportePdf = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
  esAccionista: boolean;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/listado-distribucion-canillas-importe/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getVentaMensualSecretariaElDia = async (params: { fechaDesde: string; fechaHasta: string }): Promise<VentaMensualSecretariaElDiaDto[]> => {
  const response = await apiClient.get<VentaMensualSecretariaElDiaDto[]>('/reportes/venta-mensual-secretaria/el-dia', { params });
  return response.data;
};

const getVentaMensualSecretariaElDiaPdf = async (params: { fechaDesde: string; fechaHasta: string }): Promise<Blob> => {
  const response = await apiClient.get('/reportes/venta-mensual-secretaria/el-dia/pdf', { params, responseType: 'blob' });
  return response.data;
};

const getVentaMensualSecretariaElPlata = async (params: { fechaDesde: string; fechaHasta: string }): Promise<VentaMensualSecretariaElPlataDto[]> => {
  const response = await apiClient.get<VentaMensualSecretariaElPlataDto[]>('/reportes/venta-mensual-secretaria/el-plata', { params });
  return response.data;
};

const getVentaMensualSecretariaElPlataPdf = async (params: { fechaDesde: string; fechaHasta: string }): Promise<Blob> => {
  const response = await apiClient.get('/reportes/venta-mensual-secretaria/el-plata/pdf', { params, responseType: 'blob' });
  return response.data;
};

const getVentaMensualSecretariaTirDevo = async (params: { fechaDesde: string; fechaHasta: string }): Promise<VentaMensualSecretariaTirDevoDto[]> => {
  const response = await apiClient.get<VentaMensualSecretariaTirDevoDto[]>('/reportes/venta-mensual-secretaria/tirada-devolucion', { params });
  return response.data;
};
const getVentaMensualSecretariaTirDevoPdf = async (params: { fechaDesde: string; fechaHasta: string }): Promise<Blob> => {
  const response = await apiClient.get('/reportes/venta-mensual-secretaria/tirada-devolucion/pdf', { params, responseType: 'blob' });
  return response.data;
};

const getReporteDistribucionCanillas = async (params: { 
    fecha: string; 
    idEmpresa: number; 
    esAccionista?: boolean; // Hacerlo opcional
}): Promise<ReporteDistribucionCanillasResponseDto> => {
    try {
        const response = await apiClient.get<ReporteDistribucionCanillasResponseDto>('/reportes/distribucion-canillas', { params });
        return response.data;
    } catch (error) {
        console.error('Error al obtener datos del reporte de distribución de canillas:', error);
        throw error;
    }
};

const getReporteDistribucionCanillasPdf = async (params: {
    fecha: string;
    idEmpresa: number;
    esAccionista?: boolean; // Opcional
    soloTotales: boolean;
}): Promise<Blob> => {
    try {
        const response = await apiClient.get('/reportes/distribucion-canillas/pdf', {
            params,
            responseType: 'blob'
        });
        return response.data;
    } catch (error) {
        console.error('Error al generar PDF del reporte de distribución de canillas:', error);
        if (axios.isAxiosError(error) && error.response?.data) {
            // Si el error es un JSON dentro de un Blob, hay que leerlo
            if (error.response.data.type === 'application/json') {
                const errorJson = JSON.parse(await error.response.data.text());
                throw new Error(errorJson.message || "Error al generar PDF");
            }
        }
        throw error;
    }
};

const getTiradasPublicacionesSecciones = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
  idPlanta?: number | null;
  consolidado: boolean;
}): Promise<TiradasPublicacionesSeccionesDto[]> => {
  const response = await apiClient.get<TiradasPublicacionesSeccionesDto[]>('/reportes/tiradas-publicaciones-secciones', { params });
  return response.data;
};

const getTiradasPublicacionesSeccionesPdf = async (params: {
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
  idPlanta?: number | null;
  consolidado: boolean;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/tiradas-publicaciones-secciones/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getConsumoBobinasSeccion = async (params: {
  fechaDesde: string;
  fechaHasta: string;
  idPlanta?: number | null;
  consolidado: boolean;
}): Promise<ConsumoBobinasSeccionDto[]> => {
  const response = await apiClient.get<ConsumoBobinasSeccionDto[]>('/reportes/consumo-bobinas-seccion', { params });
  return response.data;
};

const getConsumoBobinasSeccionPdf = async (params: {
  fechaDesde: string;
  fechaHasta: string;
  idPlanta?: number | null;
  consolidado: boolean;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/consumo-bobinas-seccion/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getConsumoBobinasPorPublicacion = async (params: {
  fechaDesde: string;
  fechaHasta: string;
}): Promise<ConsumoBobinasPublicacionDto[]> => {
  const response = await apiClient.get<ConsumoBobinasPublicacionDto[]>('/reportes/consumo-bobinas-publicacion', { params });
  return response.data;
};

const getConsumoBobinasPorPublicacionPdf = async (params: {
  fechaDesde: string;
  fechaHasta: string;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/consumo-bobinas-publicacion/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getComparativaConsumoBobinas = async (params: {
  fechaInicioMesA: string; fechaFinMesA: string;
  fechaInicioMesB: string; fechaFinMesB: string;
  idPlanta?: number | null; consolidado: boolean;
}): Promise<ComparativaConsumoBobinasDto[]> => {
  const response = await apiClient.get<ComparativaConsumoBobinasDto[]>('/reportes/comparativa-consumo-bobinas', { params });
  return response.data;
};

const getComparativaConsumoBobinasPdf = async (params: {
  fechaInicioMesA: string; fechaFinMesA: string;
  fechaInicioMesB: string; fechaFinMesB: string;
  idPlanta?: number | null; consolidado: boolean;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/comparativa-consumo-bobinas/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getReporteCuentasDistribuidor = async (params: {
  idDistribuidor: number;
  idEmpresa: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<ReporteCuentasDistribuidorResponseDto> => {
  const response = await apiClient.get<ReporteCuentasDistribuidorResponseDto>('/reportes/cuentas-distribuidores', { params });
  return response.data;
};

const getReporteCuentasDistribuidorPdf = async (params: {
  idDistribuidor: number;
  idEmpresa: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/cuentas-distribuidores/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getListadoDistribucionDistribuidores = async (params: {
  idDistribuidor: number;
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<ListadoDistribucionDistribuidoresResponseDto> => {
  const response = await apiClient.get<ListadoDistribucionDistribuidoresResponseDto>('/reportes/listado-distribucion-distribuidores', { params });
  return response.data;
};

const getListadoDistribucionDistribuidoresPdf = async (params: {
  idDistribuidor: number;
  idPublicacion: number;
  fechaDesde: string;
  fechaHasta: string;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/listado-distribucion-distribuidores/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getControlDevolucionesData = async (params: {
  fecha: string; // YYYY-MM-DD
  idEmpresa: number;
}): Promise<ControlDevolucionesDataResponseDto> => {
  const response = await apiClient.get<ControlDevolucionesDataResponseDto>('/reportes/control-devoluciones', { params });
  return response.data;
};

const getControlDevolucionesPdf = async (params: {
  fecha: string; // YYYY-MM-DD
  idEmpresa: number;
}): Promise<Blob> => {
  const response = await apiClient.get('/reportes/control-devoluciones/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getTicketLiquidacionCanillaPdf = async (params: {
  fecha: string; // YYYY-MM-DD
  idCanilla: number;
  esAccionista?: boolean; // Hacerlo opcional, el backend podría tener un default
}): Promise<Blob> => {
  const queryParams: Record<string, string | number | boolean> = {
    fecha: params.fecha,
    idCanilla: params.idCanilla,
  };
  if (params.esAccionista !== undefined) {
    queryParams.esAccionista = params.esAccionista;
  }
  const response = await apiClient.get('/reportes/ticket-liquidacion-canilla/pdf', {
    params: queryParams,
    responseType: 'blob',
  });
  return response.data;
};

const getNovedadesCanillasReporte = async (params: GetNovedadesCanillasParams): Promise<NovedadesCanillasReporteDto[]> => {
  const response = await apiClient.get<NovedadesCanillasReporteDto[]>('/reportes/novedades-canillas', { params });
  return response.data;
};

const getNovedadesCanillasReportePdf = async (params: GetNovedadesCanillasParams): Promise<Blob> => {
  const response = await apiClient.get('/reportes/novedades-canillas/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getCanillasGananciasReporte = async (params: GetNovedadesCanillasParams): Promise<CanillaGananciaReporteDto[]> => {
  const response = await apiClient.get<CanillaGananciaReporteDto[]>('/reportes/novedades-canillas-ganancias', { params });
  return response.data;
};

const getListadoDistMensualDiarios = async (params: GetListadoDistMensualParams): Promise<ListadoDistCanMensualDiariosDto[]> => {
  const response = await apiClient.get<ListadoDistCanMensualDiariosDto[]>('/reportes/listado-distribucion-mensual/diarios', { params });
  return response.data;
};

const getListadoDistMensualDiariosPdf = async (params: GetListadoDistMensualParams): Promise<Blob> => {
  const response = await apiClient.get('/reportes/listado-distribucion-mensual/diarios/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getListadoDistMensualPorPublicacion = async (params: GetListadoDistMensualParams): Promise<ListadoDistCanMensualPubDto[]> => {
  const response = await apiClient.get<ListadoDistCanMensualPubDto[]>('/reportes/listado-distribucion-mensual/publicaciones', { params });
  return response.data;
};

const getListadoDistMensualPorPublicacionPdf = async (params: GetListadoDistMensualParams): Promise<Blob> => {
  const response = await apiClient.get('/reportes/listado-distribucion-mensual/publicaciones/pdf', {
    params,
    responseType: 'blob',
  });
  return response.data;
};

const getReporteFacturasPublicidadPdf = async (anio: number, mes: number): Promise<{ fileContent: Blob, fileName: string }> => {
  const params = new URLSearchParams({ anio: String(anio), mes: String(mes) });
  const url = `/reportes/suscripciones/facturas-para-publicidad/pdf?${params.toString()}`;
  const response = await apiClient.get(url, {
    responseType: 'blob',
  });

  const contentDisposition = response.headers['content-disposition'];
  let fileName = `ReportePublicidad_Suscripciones_${anio}-${String(mes).padStart(2, '0')}.pdf`; // Fallback
  if (contentDisposition) {
    const fileNameMatch = contentDisposition.match(/filename="(.+)"/);
    if (fileNameMatch && fileNameMatch.length > 1) {
      fileName = fileNameMatch[1];
    }
  }

  return { fileContent: response.data, fileName: fileName };
};

const getReporteDistribucionSuscripcionesPdf = async (fechaDesde: string, fechaHasta: string): Promise<{ fileContent: Blob, fileName: string }> => {
    const params = new URLSearchParams({ 
        fechaDesde: fechaDesde, 
        fechaHasta: fechaHasta 
    });
    const url = `/reportes/suscripciones/distribucion/pdf?${params.toString()}`;
    
    const response = await apiClient.get(url, {
        responseType: 'blob',
    });

    const contentDisposition = response.headers['content-disposition'];
    let fileName = `ReporteDistribucion_Suscripciones_${fechaDesde}_al_${fechaHasta}.pdf`; // Fallback
    if (contentDisposition) {
        const fileNameMatch = contentDisposition.match(/filename="(.+)"/);
        if (fileNameMatch && fileNameMatch.length > 1) {
            fileName = fileNameMatch[1];
        }
    }
    
    return { fileContent: response.data, fileName: fileName };
};

const reportesService = {
  getExistenciaPapel,
  getExistenciaPapelPdf,
  getMovimientoBobinas,
  getMovimientoBobinasPdf,
  getMovimientoBobinasEstado,
  getMovimientoBobinasEstadoPdf,
  getListadoDistribucionGeneral,
  getListadoDistribucionGeneralPdf,
  getListadoDistribucionCanillas,
  getListadoDistribucionCanillasPdf,
  getListadoDistribucionCanillasImporte,
  getListadoDistribucionCanillasImportePdf,
  getVentaMensualSecretariaElDia,
  getVentaMensualSecretariaElDiaPdf,
  getVentaMensualSecretariaElPlata,
  getVentaMensualSecretariaElPlataPdf,
  getVentaMensualSecretariaTirDevo,
  getVentaMensualSecretariaTirDevoPdf,
  getReporteDistribucionCanillas,
  getReporteDistribucionCanillasPdf,
  getTiradasPublicacionesSecciones,
  getTiradasPublicacionesSeccionesPdf,
  getConsumoBobinasSeccion,
  getConsumoBobinasSeccionPdf,
  getConsumoBobinasPorPublicacion,
  getConsumoBobinasPorPublicacionPdf,
  getComparativaConsumoBobinas,
  getComparativaConsumoBobinasPdf,
  getReporteCuentasDistribuidor,
  getReporteCuentasDistribuidorPdf,
  getListadoDistribucionDistribuidores,
  getListadoDistribucionDistribuidoresPdf,
  getControlDevolucionesData,
  getControlDevolucionesPdf,
  getTicketLiquidacionCanillaPdf,
  getNovedadesCanillasReporte,
  getNovedadesCanillasReportePdf,
  getCanillasGananciasReporte,
  getListadoDistMensualDiarios,
  getListadoDistMensualDiariosPdf,
  getListadoDistMensualPorPublicacion,
  getListadoDistMensualPorPublicacionPdf,
  getReporteFacturasPublicidadPdf,
  getReporteDistribucionSuscripcionesPdf,
};

export default reportesService;