package utils

import (
	"encoding/json"
	"fmt"
	"net/url"
	"strings"
	"time"

	"github.com/google/uuid"
)

var (
	boliviaLocation *time.Location
	locationErr     error
)

func init() {
	// Cargar la zona horaria de Bolivia
	boliviaLocation, locationErr = time.LoadLocation("America/La_Paz")
	if locationErr != nil {
		fmt.Printf("Error cargando zona horaria de Bolivia: %v\n", locationErr)
	}
}

// Función helper para obtener la hora actual en Bolivia
func NowInBolivia() time.Time {
	return time.Now().In(boliviaLocation)
}

// formatFecha convierte una fecha ISO a formato para CUF
func FormatFecha(fechaISO string) (string, error) {
	const inLayout = "2006-01-02T15:04:05.000"
	t, err := time.Parse(inLayout, fechaISO)
	if err != nil {
		return "", fmt.Errorf("formato de fecha inválido: %w", err)
	}

	// Formato yyyyMMddHHmmssSSS (17 caracteres)
	base := t.Format("20060102150405")
	ms := fmt.Sprintf("%03d", t.Nanosecond()/1e6)

	result := base + ms
	if len(result) != 17 {
		return "", fmt.Errorf("longitud incorrecta en fecha formateada: %d, esperado 17", len(result))
	}

	return result, nil
}

// mustMarshal serializa a JSON sin error
func MustMarshal(v interface{}) []byte {
	b, err := json.Marshal(v)
	if err != nil {
		// En lugar de panic, maneja el error y devuelve un JSON de error
		return []byte(`{"error":"Error serializando JSON"}`)
	}
	return b
}

// isValidUUID verifica si una cadena es un UUID válido
func IsValidUUID(u string) bool {
	_, err := uuid.Parse(u)
	return err == nil
}

// generateUUID genera un nuevo UUID
func GenerateUUID() string {
	return uuid.New().String()
}

// getEnv obtiene valor de variable de entorno con valor por defecto
func GetEnv(key, defaultValue string) string {
	value := strings.TrimSpace(key)
	if value == "" {
		return defaultValue
	}
	return value
}

// funcion para concatenar URL
func ConstruirURLSIAT(numeroFactura string, vCuf string) (string, error) {
	u := url.URL{
		Scheme: "https",
		Host:   "siat.impuestos.gob.bo",
		Path:   "consulta/QR",
	}
	q := u.Query()
	q.Set("nit", numeroFactura)
	q.Set("cuf", vCuf)
	q.Set("numero", "1")
	q.Set("t", "1")
	u.RawQuery = q.Encode()

	return u.String(), nil
}
