import { GlobalFunctions, TransferAreaProperties } from '@/GlobalFunctions';
import { apiService } from './api';

/**
 * Interface para resposta do POST de parecer técnico
 */
export interface CreateOpinionResponse {
  success: boolean;
  id?: string;
  file_url?: string;
  file_url_melhoria?: string;
}

/**
 * Interface para requisição de criação de parecer
 */
export interface CreateOpinionRequest {
  titulo: string;
  categoria: string;
  instrucoes: string;
  userEmail?: string;
  estabelecimentoId?: number;
}

/**
 * Status do parecer
 */
export type OpinionStatus = 'processando' | 'concluido' | 'erro';

/**
 * Interface para um parecer retornado pela API
 */
export interface OpinionRecord {
  id: string;
  estabelecimento_id: number;
  user_email: string;
  titulo: string;
  categoria: string;
  instrucoes: string;
  file_url: string;
  created_at: string;
  file_url_melhoria: string;
  status?: OpinionStatus; // Status do processamento do parecer (pode vir da API ou ser local)
  isLocalPending?: boolean; // Flag para indicar se é um registro local temporário
}

/**
 * Interface para parâmetros de paginação e busca
 */
export interface GetOpinionsParams {
  page?: number;
  per_page?: number;
  search?: string;
  userEmail?: string;
  estabelecimentoId?: number;
}

/**
 * Interface para resposta do GET de pareceres
 */
export interface GetOpinionsResponse {
  data: OpinionRecord[];
  total: number;
  page: number;
  per_page: number;
}

/**
 * Serviço para gerenciamento de pareceres jurídicos
 */
class AgentService {
  private readonly CREATE_OPINION_ENDPOINT = '/webhook/codex/gepam/parecer-tecnico';
  private readonly GET_OPINIONS_ENDPOINT = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/get_parecer';

  /**
   * Cria um novo parecer técnico
   *
   * @param request - Dados do parecer
   * @returns Promise com a resposta da API
   */
  async createOpinion(request: CreateOpinionRequest): Promise<CreateOpinionResponse> {
    const {
      titulo,
      categoria,
      instrucoes,
      userEmail,
      estabelecimentoId
    } = request;

    // Usa valores do GlobalFunctions se não forem fornecidos
    const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
    const estabId = estabelecimentoId || GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo);

    // Validações
    if (!titulo || titulo.trim().length === 0) {
      throw {
        success: false,
        message: 'Título do parecer é obrigatório',
      };
    }

    if (!instrucoes || instrucoes.trim().length === 0) {
      throw {
        success: false,
        message: 'Instruções são obrigatórias',
      };
    }

    if (!email) {
      throw {
        success: false,
        message: 'Email do usuário não fornecido',
      };
    }

    if (!estabId) {
      throw {
        success: false,
        message: 'ID do estabelecimento não fornecido',
      };
    }

    // Log para debug
    console.log('Criando parecer:', {
      titulo,
      categoria,
      instrucoesLength: instrucoes.length,
      userEmail: email,
      estabelecimentoId: estabId,
    });

    try {
      // Faz a requisição usando o serviço de API com timeout de 5 minutos
      const response = await apiService.post<CreateOpinionResponse>(
        this.CREATE_OPINION_ENDPOINT,
        {
          user_email: email,
          estabelecimento_id: estabId,
          titulo: titulo.trim(),
          categoria: categoria.trim(),
          instrucoes: instrucoes.trim(),
        },
        {
          timeout: 600000, // 5 minutos para geração de parecer (processo demorado)
        }
      );

      console.log('Resposta da API (criar parecer):', response.data);

      return response.data;
    } catch (error: any) {
      // Trata erros específicos
      console.error('Erro ao criar parecer:', error);

      throw {
        success: false,
        message: error.message || 'Erro ao criar parecer',
        status: error.status,
      };
    }
  }

  /**
   * Busca todos os pareceres do usuário com paginação e busca
   *
   * @param params - Parâmetros de paginação e busca
   * @returns Promise com array de pareceres
   */
  async getOpinions(params?: GetOpinionsParams): Promise<OpinionRecord[]> {
    const {
      page = 1,
      per_page = 10,
      search = '',
      userEmail,
      estabelecimentoId
    } = params || {};

    // Usa valores do GlobalFunctions se não forem fornecidos
    const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);
    const estabId = estabelecimentoId || GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo);

    if (!email) {
      throw {
        success: false,
        message: 'Email do usuário não fornecido',
      };
    }

    if (!estabId) {
      throw {
        success: false,
        message: 'ID do estabelecimento não fornecido',
      };
    }

    console.log('Buscando pareceres:', {
      userEmail: email,
      estabelecimentoId: estabId,
      page,
      per_page,
      search,
    });

    try {
      // Constrói a URL com parâmetros de query
      const url = `${this.GET_OPINIONS_ENDPOINT}/${email}/${estabId}`;

      const response = await apiService.get<OpinionRecord[]>(url, {
        params: {
          page,
          per_page,
          search,
        },
      });

      console.log('Resposta da API (buscar pareceres):', response.data);

      // A API retorna diretamente o array de pareceres
      // Garante que sempre retorna um array
      if (Array.isArray(response.data)) {
        return response.data;
      } else if (response.data && typeof response.data === 'object') {
        // Se a resposta for um objeto, tenta encontrar o array dentro dele
        console.warn('API retornou objeto em vez de array:', response.data);

        if (Array.isArray((response.data as any).data)) {
          return (response.data as any).data;
        } else if (Array.isArray((response.data as any).opinions)) {
          return (response.data as any).opinions;
        }
      }

      // Se não conseguir extrair array, retorna vazio
      console.warn('Não foi possível extrair array de pareceres da resposta');
      return [];
    } catch (error: any) {
      console.error('Erro ao buscar pareceres:', error);

      throw {
        success: false,
        message: error.message || 'Erro ao buscar pareceres',
        status: error.status,
      };
    }
  }

  /**
   * Faz download de um arquivo de parecer
   *
   * @param fileUrl - URL do arquivo a ser baixado
   * @param fileName - Nome do arquivo para download
   */
  async downloadOpinion(fileUrl: string, fileName: string): Promise<void> {
    if (!fileUrl) {
      throw {
        success: false,
        message: 'URL do arquivo não fornecida',
      };
    }

    try {
      console.log('Iniciando download:', { fileUrl, fileName });

      // Tenta primeiro fazer o download via fetch (funciona se CORS estiver configurado)
      try {
        const response = await fetch(fileUrl, {
          method: 'GET',
          mode: 'cors',
          cache: 'no-cache',
        });

        if (!response.ok) {
          throw new Error(`Erro HTTP: ${response.status}`);
        }

        // Converte a resposta em blob
        const blob = await response.blob();

        // Cria uma URL temporária para o blob
        const blobUrl = URL.createObjectURL(blob);

        // Cria um elemento <a> temporário para forçar o download
        const link = document.createElement('a');
        link.href = blobUrl;
        link.download = fileName;
        document.body.appendChild(link);
        link.click();

        // Remove o elemento e libera a URL temporária
        document.body.removeChild(link);
        URL.revokeObjectURL(blobUrl);

        console.log('Download via fetch concluído:', { fileUrl, fileName });
        return;
      } catch (fetchError: any) {
        console.warn('Erro no download via fetch, tentando método alternativo:', fetchError.message);

        // Se falhar (erro de CORS), usa o método alternativo de abrir em nova aba
        // Isso permite que o navegador force o download mesmo com restrições de CORS
        const link = document.createElement('a');
        link.href = fileUrl;
        link.download = fileName;
        link.target = '_blank';
        link.rel = 'noopener noreferrer';

        // Para S3, podemos tentar adicionar parâmetros que forçam o download
        const url = new URL(fileUrl);
        url.searchParams.set('response-content-disposition', `attachment; filename="${encodeURIComponent(fileName)}"`);
        link.href = url.toString();

        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);

        console.log('Download via link direto iniciado:', { fileUrl, fileName });
      }
    } catch (error: any) {
      console.error('Erro ao fazer download:', error);

      throw {
        success: false,
        message: error.message || 'Erro ao fazer download do arquivo. Verifique se a URL está acessível.',
      };
    }
  }

  /**
   * Exclui um parecer técnico
   *
   * @param opinionId - ID do parecer a ser excluído
   * @param userEmail - Email do usuário (opcional, usa GlobalFunctions se não fornecido)
   * @returns Promise com a resposta da API
   */
  async deleteOpinion(opinionId: string, userEmail?: string): Promise<{ success: boolean }> {
    // Usa valores do GlobalFunctions se não forem fornecidos
    const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail);

    if (!opinionId) {
      throw {
        success: false,
        message: 'ID do parecer não fornecido',
      };
    }

    if (!email) {
      throw {
        success: false,
        message: 'Email do usuário não fornecido',
      };
    }

    console.log('Excluindo parecer:', {
      opinionId,
      userEmail: email,
    });

    try {
      // Constrói a URL com o user_email e id
      const url = `/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex/delete_parecer/${email}/${opinionId}`;

      const response = await apiService.delete<{ success: boolean }[]>(url);

      console.log('Resposta da API (excluir parecer):', response.data);

      // A API retorna um array com { success: true }
      if (Array.isArray(response.data) && response.data.length > 0) {
        return response.data[0];
      }

      return { success: true };
    } catch (error: any) {
      console.error('Erro ao excluir parecer:', error);

      throw {
        success: false,
        message: error.message || 'Erro ao excluir parecer',
        status: error.status,
      };
    }
  }
}

// Exporta instância única (Singleton)
export const agentService = new AgentService();
