package formats

import (
	"encoding/json"
	"fmt"
	"sort"
)

type Transformer interface {
	Name() string
	Transform(raw json.RawMessage) (*TransformResult, error)
}

type TransformResult struct {
	EmisorNIF       string
	EmisorNombre    string
	NumSerie        string
	FechaExpedicion string
	TipoFactura     string
	Descripcion     string
	Destinatario    *DestinatarioData
	IVA             []IVAData
	ImporteTotal    float64
	Sistema         SistemaData
}

type DestinatarioData struct {
	Nombre string
	NIF    string
}

type IVAData struct {
	Base  float64
	Cuota float64
	Tipo  float64
}

type SistemaData struct {
	Nombre       string
	NIFProveedor string
	Version      string
}

var registry = make(map[string]Transformer)
var order []string

func Register(t Transformer) {
	name := t.Name()
	if _, exists := registry[name]; !exists {
		order = append(order, name)
	}
	registry[name] = t
}

func TransformAuto(raw json.RawMessage) (*TransformResult, string, error) {
	for _, name := range order {
		t := registry[name]
		result, err := t.Transform(raw)
		if err == nil {
			return result, name, nil
		}
	}
	return nil, "", fmt.Errorf("no matching format found (available: %v)", Available())
}

func Available() []string {
	names := make([]string, len(order))
	copy(names, order)
	sort.Strings(names)
	return names
}
