package regras

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strings"
	"sync"
	"time"
)

var (
	naventCache   = make(map[int][]naventSubtipo)
	naventCacheMu sync.RWMutex
)

type naventSubtipo struct {
	ID     int    `json:"id"`
	Nombre string `json:"nombre"`
}

// TipoSubTipo espelha FunctionsPortais::tipoSubTipo (API Navent + fallback).
func TipoSubTipo(idImovelWeb int, nomeCategoria, accessToken string) string {
	if idImovelWeb == 0 {
		return `<idTipo><![CDATA[1]]></idTipo>
        <idSubTipo><![CDATA[5]]></idSubTipo>`
	}
	subID := resolverSubtipoNavent(idImovelWeb, nomeCategoria, accessToken)
	return fmt.Sprintf(`<idTipo><![CDATA[%d]]></idTipo>
            <idSubTipo><![CDATA[%d]]></idSubTipo>`, idImovelWeb, subID)
}

func resolverSubtipoNavent(idTipo int, nomeCategoria, token string) int {
	subs := carregarSubtiposNavent(idTipo, token)
	cat := strings.ToLower(nomeCategoria)
	for _, s := range subs {
		if strings.Contains(cat, strings.ToLower(s.Nombre)) {
			return s.ID
		}
	}
	return TrataValorCategoria(idTipo, nomeCategoria)
}

func carregarSubtiposNavent(idTipo int, token string) []naventSubtipo {
	naventCacheMu.RLock()
	if v, ok := naventCache[idTipo]; ok {
		naventCacheMu.RUnlock()
		return v
	}
	naventCacheMu.RUnlock()

	url := fmt.Sprintf("https://api-br.open.navent.com/v1/tipopropriedade/%d/subtipos?access_token=%s", idTipo, token)
	client := &http.Client{Timeout: 15 * time.Second}
	resp, err := client.Get(url)
	if err != nil || resp.StatusCode != http.StatusOK {
		return nil
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	var subs []naventSubtipo
	if err := json.Unmarshal(body, &subs); err != nil {
		return nil
	}
	naventCacheMu.Lock()
	naventCache[idTipo] = subs
	naventCacheMu.Unlock()
	return subs
}

// TrataValorCategoria fallback offline (FunctionsPortais::trataValorCategoria).
func TrataValorCategoria(idTipoWeb int, _ string) int {
	switch idTipoWeb {
	case 1:
		return 5
	case 2:
		return 1
	case 1003:
		return 8
	case 1004:
		return 11
	case 1005:
		return 32
	default:
		return 5
	}
}
