package handlers

import (
	"context"
	"daemonService/internal/models/obtencionCodigos/request"
	"daemonService/internal/repositories"
	serv "daemonService/internal/services"
	"daemonService/internal/services/procesar"
	"daemonService/internal/utils"
	"encoding/json"
	"fmt"
	"net/http"
)

type APIHandler struct {
	CuisService      *serv.CuisService
	CuisRepository   *repositories.CuisRepository
	ProcesarRegistro *procesar.ProcesarRegistro
}

func NewApiHandler(cuisService *serv.CuisService, cuisRepo *repositories.CuisRepository, procesarRegistro *procesar.ProcesarRegistro) *APIHandler {
	return &APIHandler{CuisService: cuisService, CuisRepository: cuisRepo, ProcesarRegistro: procesarRegistro}
}

// ParseCuisRequest parsea la solicitud de CUIS desde el body del request
func (h *APIHandler) ParseCuisRequest(w http.ResponseWriter, req *http.Request) (request.SolicitudCuisCufd, error) {
	var cuisRequest request.SolicitudCuisCufd

	// Limitar el tamaño del body para prevenir ataques DoS
	req.Body = http.MaxBytesReader(w, req.Body, utils.MaxBodySize)

	decoder := json.NewDecoder(req.Body)
	decoder.DisallowUnknownFields() // Rechazar campos desconocidos

	if err := decoder.Decode(&cuisRequest); err != nil {
		return cuisRequest, fmt.Errorf("error al decodificar JSON: %v", err)
	}

	return cuisRequest, nil
}

// maneja las solicitudes API
func (h *APIHandler) HandleAPIRequest(ctx context.Context, w http.ResponseWriter, req *http.Request) (interface{}, error) {
	// Parsear la solicitud
	cuisRequest, err := h.ParseCuisRequest(w, req)
	if err != nil {
		return nil, err
	}

	// Validar la solicitud
	if err := h.ValidateCuisRequest(cuisRequest); err != nil {
		return nil, fmt.Errorf("datos inválidos: %v", err)
	}

	// Procesar la solicitud Cuis
	respCuis, _, err := h.ProcesarRegistro.CodigoProcesarRegistro(cuisRequest)
	if err != nil {
		return nil, fmt.Errorf(utils.LogErrorProcessing, cuisRequest.CodigoSistema, err)
	}

	// Parsear respuesta SOAP
	codCuis, fechaVigencia, transaccion, err := utils.ParseSoapCuisResponse(respCuis)
	if err != nil {
		return nil, fmt.Errorf("error al parsear respuesta CUIS SOAP: %v", err)
	}

	// Procesamos la solicitud Cufd
	cuisRequest.Cuis = codCuis
	_, codCufd, err := h.ProcesarRegistro.CodigoProcesarRegistro(cuisRequest)
	if err != nil {
		return nil, fmt.Errorf(utils.LogErrorProcessing, cuisRequest.CodigoSistema, err)
	}

	fmt.Println("codigo CUFD: %v", codCufd)

	cufdData, err := utils.ParseSoapCufdResponse(codCufd)
	if err != nil {
		return nil, fmt.Errorf("error al parsear respuesta CUFD SOAP: %v", err)
	}

	// Crear nuevo registro
	if err := h.CuisRepository.CrearNuevoRegistro(ctx, cuisRequest, codCuis, fechaVigencia, transaccion, cufdData); err != nil {
		//return nil, fmt.Errorf("error creando nuevo registro: %v", err)
		return nil, err
	}

	return respCuis, nil
}

// valida los datos de la solicitud CUIS
func (s *APIHandler) ValidateCuisRequest(request request.SolicitudCuisCufd) error {
	if request.CodigoAmbiente == "" ||
		request.CodigoModalidad == "" ||
		request.CodigoPuntoVenta == "" ||
		request.CodigoSistema == "" ||
		request.CodigoSucursal == "" ||
		request.Nit == "" {
		return utils.ErrAllFieldsRequired
	}
	return nil
}
