import { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common';
import { envs } from 'src/config/envs';
import { SifenPayloadService } from 'src/facturas/sifen-payload.service';
import { NotaCreditoPayloadService } from 'src/nota-creditos/nota-credito-payload.service';
import { NotaRemisionSifenPayloadService } from 'src/nota-remision/nota-remision-sifen-payload.service';

@Injectable()
export class KudeService {
  private readonly logger = new Logger(KudeService.name);
  private readonly apiUrl = envs.apiGeneradorPDF;

  constructor(
    private readonly sifenPayloadService: SifenPayloadService,
    private readonly notaCreditoPayloadService: NotaCreditoPayloadService,
    private readonly notaRemisionPayloadService: NotaRemisionSifenPayloadService,
  ) {}

  async generateKudeFactura(
    facturaId: string,
    empresaId: string,
    options: { ticket?: boolean; tipo_retorno?: string } = {},
  ): Promise<{ pdfBuffer?: Buffer; base64?: string; contentType: string }> {
    const { ticket = false, tipo_retorno = 'view' } = options;

    const documento = await this.sifenPayloadService.buildFacturaPayload(facturaId, empresaId);

    const body = {
      tipo_documento: 1,
      empresa_id: empresaId,
      documento,
      ticket,
      tipo_retorno,
    };
    console.log(JSON.stringify(body));

    return this.callGenerateKude(body, tipo_retorno);
  }

  async generateKudeNotaCredito(
    notaCreditoId: string,
    empresaId: string,
    options: { ticket?: boolean; tipo_retorno?: string } = {},
  ): Promise<{ pdfBuffer?: Buffer; base64?: string; contentType: string }> {
    const { ticket = false, tipo_retorno = 'view' } = options;

    const documento = await this.notaCreditoPayloadService.buildNotaCreditoPayload(notaCreditoId, empresaId);

    const body = {
      tipo_documento: 5,
      empresa_id: empresaId,
      documento,
      ticket,
      tipo_retorno,
    };

    return this.callGenerateKude(body, tipo_retorno);
  }

  async generateKudeNotaRemision(
    notaRemisionId: string,
    empresaId: string,
    options: { ticket?: boolean; tipo_retorno?: string } = {},
  ): Promise<{ pdfBuffer?: Buffer; base64?: string; contentType: string }> {
    const { ticket = false, tipo_retorno = 'view' } = options;

    const documento = await this.notaRemisionPayloadService.buildPayload(notaRemisionId, empresaId);

    const body = {
      tipo_documento: 7,
      empresa_id: empresaId,
      documento,
      ticket,
      tipo_retorno,
    };

    return this.callGenerateKude(body, tipo_retorno);
  }

  private async callGenerateKude(
    body: Record<string, unknown>,
    tipo_retorno: string,
  ): Promise<{ pdfBuffer?: Buffer; base64?: string; contentType: string }> {
    const url = `${this.apiUrl}/api/generate-kude`;
    this.logger.log(
      `Calling msv-kude: ${url} tipo_documento=${String(body.tipo_documento)} tipo_retorno=${tipo_retorno}`,
    );

    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });

      if (!response.ok) {
        const errorBody = await response.text();
        this.logger.error(`msv-kude responded ${response.status}: ${errorBody}`);
        throw new HttpException(
          { message: 'Error al generar KUDE', detail: errorBody },
          HttpStatus.BAD_GATEWAY,
        );
      }

      if (tipo_retorno === 'base64') {
        const json = (await response.json()) as {
          status: string;
          kude_base64?: string;
          message?: string;
        };
        if (json.status !== 'success') {
          throw new HttpException(
            { message: json.message || 'Error al generar KUDE' },
            HttpStatus.BAD_GATEWAY,
          );
        }
        return { base64: json.kude_base64, contentType: 'application/json' };
      }

      const arrayBuffer = await response.arrayBuffer();
      const pdfBuffer = Buffer.from(arrayBuffer);
      return { pdfBuffer, contentType: 'application/pdf' };
    } catch (error) {
      if (error instanceof HttpException) throw error;
      const message = error instanceof Error ? error.message : 'Error desconocido';
      this.logger.error(`Error llamando a msv-kude: ${message}`);
      throw new HttpException(
        {
          message: 'No se pudo conectar con el servicio de generación de KUDE',
          detail: message,
        },
        HttpStatus.BAD_GATEWAY,
      );
    }
  }
}
