package render

import (
	"strings"
	"unicode"

	"leadb2b.org/internal/api"
)

const maxSlugPartRunes = 48

var accentFold = strings.NewReplacer(
	"á", "a", "à", "a", "â", "a", "ã", "a", "ä", "a",
	"é", "e", "è", "e", "ê", "e", "ë", "e",
	"í", "i", "ì", "i", "î", "i", "ï", "i",
	"ó", "o", "ò", "o", "ô", "o", "õ", "o", "ö", "o",
	"ú", "u", "ù", "u", "û", "u", "ü", "u",
	"ç", "c", "ñ", "n",
	"Á", "a", "À", "a", "Â", "a", "Ã", "a", "Ä", "a",
	"É", "e", "É", "e", "Ê", "e", "Ë", "e",
	"Í", "i", "Ì", "i", "Î", "i", "Ï", "i",
	"Ó", "o", "Ò", "o", "Ô", "o", "Õ", "o", "Ö", "o",
	"Ú", "u", "Ù", "u", "Û", "u", "Ü", "u",
	"Ç", "c", "Ñ", "n",
)

// EmpresaSlug gera o segmento legível da URL (nome fantasia ou razão social, cidade, UF e CNPJ).
func EmpresaSlug(cnpj, nome, municipio, uf string) string {
	cnpj = digitsOnly(cnpj)
	parts := []string{
		slugPart(nome, "empresa"),
		slugPart(municipio, ""),
		strings.ToLower(strings.TrimSpace(uf)),
		cnpj,
	}
	var out []string
	for _, p := range parts {
		if p != "" {
			out = append(out, p)
		}
	}
	if len(out) == 0 {
		return cnpj
	}
	return strings.Join(out, "-")
}

// EmpresaPath retorna o caminho canônico da ficha (/empresa/... ou /empresa-premium/...).
func EmpresaPath(cnpj, nome, municipio, uf string, premium bool) string {
	prefix := "/empresa"
	if premium {
		prefix = "/empresa-premium"
	}
	return prefix + "/" + EmpresaSlug(cnpj, nome, municipio, uf)
}

func EmpresaPathFromList(item api.EstabelecimentoOut) string {
	return EmpresaPath(item.CNPJ, EmpresaNomeExibicaoList(item), item.MunicipioNome, item.UF, false)
}

func EmpresaPathFromDetail(d *api.EstabelecimentoDetailOut, premium bool) string {
	if d == nil {
		if premium {
			return "/empresa-premium/"
		}
		return "/empresa/"
	}
	return EmpresaPath(d.CNPJ, EmpresaNomeExibicao(d), d.Endereco.Municipio.Descricao, d.Endereco.UF, premium)
}

// CNPJFromEmpresaSlug extrai o CNPJ (14 dígitos) do segmento da URL.
func CNPJFromEmpresaSlug(slug string) (string, bool) {
	slug = strings.TrimSpace(slug)
	if slug == "" {
		return "", false
	}
	if d := digitsOnly(slug); len(d) == 14 {
		return d, true
	}
	if i := strings.LastIndex(slug, "-"); i >= 0 {
		if d := digitsOnly(slug[i+1:]); len(d) == 14 {
			return d, true
		}
	}
	return "", false
}

func slugPart(s, fallback string) string {
	s = strings.TrimSpace(accentFold.Replace(s))
	if s == "" {
		return fallback
	}
	var b strings.Builder
	runes := 0
	for _, r := range strings.ToLower(s) {
		if runes >= maxSlugPartRunes {
			break
		}
		switch {
		case r >= 'a' && r <= 'z', r >= '0' && r <= '9':
			b.WriteRune(r)
			runes++
		case unicode.IsSpace(r), r == '-', r == '_', r == '/', r == '.', r == '&':
			if b.Len() > 0 && b.String()[b.Len()-1] != '-' {
				b.WriteByte('-')
			}
		}
	}
	out := strings.Trim(b.String(), "-")
	if out == "" {
		return fallback
	}
	return out
}

func digitsOnly(s string) string {
	var b strings.Builder
	for _, r := range s {
		if r >= '0' && r <= '9' {
			b.WriteRune(r)
		}
	}
	return b.String()
}
