import api from './api';
import { handleRequest, simulateLatency } from './serviceUtils';

/**
 * Service de Boletos do Inter
 * Gerencia comunicação com as rotas de boletos e extrato para cruzamento
 * Baseado na lógica antiga do sistema
 */
export const boletosService = {

  /**
   * Busca dados de apresentação dos boletos (Lista e Resumo)
   * Rota: GET /boletos/status
   * API retorna: { cobrancas: [...], resumoValorPorSituacaoMesAno: [...] }
   */
  fetchBoletosStatus: () => handleRequest({
    mockFn: () => simulateLatency({ cobrancas: [], resumoValorPorSituacaoMesAno: [] }),
    apiFn: async () => {
      // O usuário solicitou OPTIONS seguido de GET para apresentação
      try {
        await api.options('/boletos/status');
      } catch (err) {
        console.warn('[boletosService] OPTIONS /boletos/status failed', err);
      }

      const response = await api.get('/boletos/status');
      return response.data;
    }
  }),

  /**
   * Busca extrato bancário
   * Rota: GET /extrato/apresentar
   * Usado para fazer cruzamento com boletos e identificar PIX recebidos sem boleto correspondente
   * @returns {Promise<Array>}
   */
  fetchExtrato: () => handleRequest({
    mockFn: () => simulateLatency([]),
    apiFn: async () => {
      const response = await api.get('/extrato/apresentar');
      // Retorna array de itens do extrato
      const data = Array.isArray(response.data) ? response.data : (response.data?.Base_Dados_API || []);
      return data;
    }
  }),

  /**
   * Baixa PDF do boleto
   * Rota: GET /boletos/pdf/{codigoSolicitacao}
   * @param {string} codigoSolicitacao
   * @returns {Promise<Blob>}
   */
  downloadBoletoPDF: (codigoSolicitacao) => handleRequest({
    mockFn: () => simulateLatency(new Blob(['PDF mock'], { type: 'application/pdf' })),
    apiFn: async () => {
      const response = await api.get(`/boletos/pdf/${codigoSolicitacao}`, {
        responseType: 'blob'
      });
      return response.data;
    }
  }),

  /**
   * Envia boleto por email
   * Rota: POST /boletos/enviar_email
   * @param {Object} payload - { codigo_solicitacao, idempresa }
   * @returns {Promise<any>}
   */
  enviarBoletoEmail: (payload) => handleRequest({
    mockFn: () => simulateLatency({ success: true, message: 'Email enviado com sucesso' }),
    apiFn: async () => {
      const response = await api.post('/boletos/enviar_email', payload);
      return response.data;
    }
  }),

  /**
   * Busca empresas/clientes para envio de email
   * Rota: GET /empresas_financeiro
   * @returns {Promise<Array>}
   */
  fetchEmpresas: () => handleRequest({
    mockFn: () => simulateLatency([]),
    apiFn: async () => {
      const response = await api.get('/empresas_financeiro');
      const data = Array.isArray(response.data) ? response.data : (response.data?.Base_Dados_API || Object.values(response.data || {}));
      return data;
    }
  }),

  /**
   * Cria um novo serviço financeiro (preâmbulo para boleto avulso)
   * Rota: POST /servicos_financeiro/create
   */
  createServicoFinanceiro: (payload) => handleRequest({
    mockFn: () => simulateLatency({ success: true }),
    apiFn: async () => {
      const response = await api.post('/servicos_financeiro/create', payload);
      return response.data;
    }
  }),

  /**
   * Busca lista de serviços financeiros
   * Rota: GET /servicos_financeiro
   */
  fetchServicosFinanceiro: () => handleRequest({
    mockFn: () => simulateLatency([]),
    apiFn: async () => {
      const response = await api.get('/servicos_financeiro');
      const data = Array.isArray(response.data) ? response.data : (response.data?.Base_Dados_API || []);
      return data;
    }
  }),

  /**
   * Gera o PDF de um boleto avulso
   * Rota: POST /boletos/avulsos (com OPTIONS prévio)
   */
  generateBoletoAvulsoPDF: (objeto) => handleRequest({
    mockFn: () => simulateLatency(new Blob(['PDF mock'], { type: 'application/pdf' })),
    apiFn: async () => {
      try {
        await api.options('/boletos/avulsos', objeto);
      } catch (err) {
        console.warn('[boletosService] OPTIONS /boletos/avulsos failed', err);
      }
      const response = await api.post('/boletos/avulsos', objeto, {
        responseType: 'blob'
      });
      return response.data;
    }
  }),

  /**
   * Cria um novo boleto (Mensal ou outros tipos que usam a rota padrão)
   * Realiza OPTIONS seguido de POST na rota /boletos
   * @param {Object} payload 
   * @returns {Promise<any>}
   */
  createBoleto: (payload) => handleRequest({
    mockFn: () => simulateLatency({ success: true, message: 'Boleto gerado com sucesso' }),
    apiFn: async () => {
      // Primeiro faz OPTIONS
      try {
        await api.options('/boletos', payload);
      } catch (err) {
        console.warn('[boletosService] createBoleto OPTIONS failed:', err);
      }

      // Depois faz POST
      const response = await api.post('/boletos', payload);
      return response.data;
    }
  }),

  /**
   * Cancela um boleto
   * Rota: POST /boletos/cancelar
   * @param {Object} payload - { codigo_solicitacao, motivo }
   */
  cancelarBoleto: (payload) => handleRequest({
    mockFn: () => simulateLatency({ success: true, message: 'Boleto cancelado com sucesso' }),
    apiFn: async () => {
      const response = await api.post('/boletos/cancelar', payload);
      return response.data;
    }
  }),

  /**
   * Agenda um boleto individual
   * Rota: POST /boletos/agendar/individual
   */
  scheduleBoleto: (payload) => handleRequest({
    mockFn: () => simulateLatency({ success: true }),
    apiFn: async () => {
      const response = await api.post('/boletos/agendar/individual', payload);
      return response.data;
    }
  }),

  /**
   * Busca detalhes de juros de um cliente específico
   * Rota: GET /financeiro/cliente/boletos
   * Resposta esperada: { cliente, dias_atraso, juros, multa, seuNumero, situacao, total_atualizado, valor_original, vencimento }
   * @param {number|string} idempresa 
   * @param {Object} filters - { situacao, mes, ano }
   */
  fetchJurosCliente: (idempresa, filters = {}) => handleRequest({
    mockFn: () => simulateLatency([]),
    apiFn: async () => {
      // Filtra parâmetros vazios para não enviá-los na URL
      const cleanFilters = Object.fromEntries(
        Object.entries(filters).filter(([_, v]) => v !== null && v !== undefined && v !== '')
      );

      const response = await api.get('/financeiro/cliente/boletos', {
        params: { idempresa, ...cleanFilters }
      });
      const raw = response?.data ?? response;
      const data = raw?.dados ?? raw?.Base_Dados_API ?? raw;
      // A API pode retornar um objeto único ou um array
      if (Array.isArray(data)) return data;
      // Se for objeto válido com campos conhecidos, envolve em array
      if (data && typeof data === 'object' && !Array.isArray(data)) {
        const items = Object.values(data);
        // Se o próprio objeto tem campos de juros é um registro único
        const hasBoletoFields = 'vencimento' in data || 'juros' in data || 'situacao' in data;
        return hasBoletoFields ? [data] : items.filter(i => typeof i === 'object' && i !== null);
      }
      return [];
    }
  })
};

