import api from './api';
import { handleRequest, simulateLatency } from './serviceUtils';
import { MOCK_EXPENSES_COMPARISON, MOCK_EXPENSES_CATEGORIES } from '../features/workspace/mockData';

/**
 * @typedef {Object} ContaAPagar
 * @property {number} idcontas_a_pagar
 * @property {string} nome_beneficiario
 * @property {number} valor_planejado
 * @property {string} data_vencimento
 * @property {string} categoria
 * @property {string} status
 */

/**
 * @typedef {Object} ExtratoTransacao
 * @property {number} idextrato
 * @property {string} dataEntrada
 * @property {string} descricao
 * @property {number} valor
 * @property {string} tipoOperacao - "C" (Crédito) ou "D" (Débito)
 * @property {string} tipoTransacao
 */

/**
 * @typedef {Object} FluxoCaixa
 * @property {number} ano
 * @property {number} mes
 * @property {number} entrada
 * @property {number} saida
 */

/**
 * Service de Despesas para o ambiente Workspace
 * Gerencia comunicação com as rotas de contas a pagar e extrato
 */
export const workspaceDespesasService = {
  /**
   * Busca contas a pagar planejadas
   * Rota: GET /contas_a_pagar/apresentar
   * Baseado na lógica antiga: item.Nome === "Contas"
   * @returns {Promise<ContaAPagar[]>}
   */
  fetchContasAPagar: () => handleRequest({
    mockFn: () => simulateLatency([]),
    apiFn: async () => {
      const response = await api.get('/contas_a_pagar/apresentar');
      // A lógica antiga mostra que pode retornar objeto de objetos ou array
      const data = Array.isArray(response.data) ? response.data : Object.values(response.data || {});
      return data.map(item => ({
        id: item.idcontas_a_pagar || item.id,
        beneficiario: item.nome_beneficiario || '',
        valor_planejado: Number(item.valor_planejado || item.valor_servico || 0),
        data_vencimento: item.data_vencimento || '',
        categoria: item.categoria || '',
        status: item.status || 'Pendente',
        parcelas: item.parcelas || 1,
        forma_pagamento: item.forma_de_pagamento || '',
        tipo_servico: item.tipo_servico || ''
      }));
    }
  }),

  /**
   * Busca transações de saída do extrato bancário
   * Rota: GET /extrato/apresentar
   * Filtra apenas transações com tipoOperacao === "D" (Débito)
   * Baseado na lógica antiga: conect.tipoOperacao !== "D" continue
   * @returns {Promise<ExtratoTransacao[]>}
   */
  fetchExtratoSaidas: () => handleRequest({
    mockFn: () => simulateLatency([]),
    apiFn: async () => {
      const response = await api.get('/extrato/apresentar');
      // A lógica antiga mostra que pode retornar objeto de objetos ou array
      const data = Array.isArray(response.data) ? response.data : Object.values(response.data || {});
      // Filtra apenas saídas (tipoOperacao === "D") - baseado na lógica antiga
      return data
        .filter(item => item.tipoOperacao === 'D')
        .map(item => ({
          id: item.idextrato || item.id,
          idextrato: item.idextrato || item.id,
          data: item.dataEntrada || '',
          dataEntrada: item.dataEntrada || '',
          descricao: item.descricao || '',
          valor: Math.abs(Number(item.valor || 0)), // Garante valor positivo para saídas
          tipo: item.tipoTransacao || 'Saída',
          tipoTransacao: item.tipoTransacao || 'Saída',
          categoria: item.categoria || '',
          beneficiario: item.beneficiario_pagador || '',
          beneficiario_pagador: item.beneficiario_pagador || '',
          regra: item.regra || 0,
          caixinha: item.caixinha || ''
        }));
    }
  }),

  /**
   * Busca dados de fluxo de caixa mensal/anual
   * Rota: GET /extrato/fluxo
   * A lógica antiga mostra que retorna { mensal: [...] }
   * @returns {Promise<FluxoCaixa[]>}
   */
  fetchFluxoCaixa: () => handleRequest({
    mockFn: () => simulateLatency(MOCK_EXPENSES_COMPARISON),
    apiFn: async () => {
      const response = await api.get('/extrato/fluxo');
      // A lógica antiga mostra que retorna { mensal: [...] }
      const data = response.data?.mensal || response.data || [];
      const arrayData = Array.isArray(data) ? data : Object.values(data || {});
      return arrayData.map(item => ({
        ano: item.ano || new Date().getFullYear(),
        mes: item.mes || new Date().getMonth() + 1,
        entrada: Number(item.entrada || 0),
        saida: Number(item.saida || 0),
        name: item.name || `${item.mes || new Date().getMonth() + 1}/${item.ano || new Date().getFullYear()}`,
        // Lado planejado desativado no Workspace por enquanto.
        // Mantemos sempre 0 para qualquer métrica de "planejado" relacionada a despesas.
        planejado: 0,
        executado: Number(item.executado || item.saida || 0)
      }));
    }
  }),

  /**
   * Busca categorias para gráfico de despesas
   * Rota: GET /categorias/apresentar
   * Baseado na lógica antiga: usado para alinhamento de dados
   * @returns {Promise<Array>}
   */
  fetchCategoriasDespesas: () => handleRequest({
    mockFn: () => simulateLatency(MOCK_EXPENSES_CATEGORIES),
    apiFn: async () => {
      const response = await api.get('/categorias/apresentar');
      const data = Array.isArray(response.data) ? response.data : Object.values(response.data || {});
      // Retorna lista de categorias disponíveis
      // O hook calculará os valores baseado nas transações do extrato
      return data.map(item => ({
        id: item.idcategoria || item.id,
        name: item.categoria || 'Sem categoria',
        value: 0 // Será calculado no hook baseado nas transações do extrato
      }));
    }
  })
};
