package render

import (
	"net/url"
	"testing"

	"leadb2b.org/internal/api"
)

func TestParseSearchForm_contato(t *testing.T) {
	q := url.Values{}
	q.Set("tem_telefone", "true")
	q.Set("tem_email", "false")
	q.Set("tem_socios", "true")
	p := ParseSearchForm(q)
	if p.TemTelefone != "true" || p.TemEmail != "false" || p.TemSocios != "true" {
		t.Fatalf("got tel=%q email=%q socios=%q", p.TemTelefone, p.TemEmail, p.TemSocios)
	}
}

func TestParseSearchForm_enderecoRegime(t *testing.T) {
	q := url.Values{}
	q.Set("cep", "01310-100")
	q.Set("bairro", "Pinheiros")
	q.Set("logradouro", "Paulista")
	q.Set("mei", "true")
	q.Set("simples", "false")
	q.Set("porte", "01")
	q.Set("natureza_juridica", "2062")
	p := ParseSearchForm(q)
	if p.CEP != "01310-100" || p.Bairro != "Pinheiros" || p.Logradouro != "Paulista" {
		t.Fatalf("endereco: cep=%q bairro=%q log=%q", p.CEP, p.Bairro, p.Logradouro)
	}
	if p.MEI != "true" || p.Simples != "false" || p.Porte != "01" || p.NaturezaJuridica != "2062" {
		t.Fatalf("regime: mei=%q simples=%q porte=%q nj=%q", p.MEI, p.Simples, p.Porte, p.NaturezaJuridica)
	}
}

func TestSearchForm_QueryValues_contato(t *testing.T) {
	p := SearchForm{TemTelefone: "true", TemEmail: "false", TemSocios: "true"}
	q := p.QueryValues()
	if q.Get("tem_telefone") != "true" {
		t.Fatalf("telefone: got %q", q.Get("tem_telefone"))
	}
	if q.Get("tem_email") != "false" {
		t.Fatalf("email: got %q", q.Get("tem_email"))
	}
	if q.Get("tem_socios") != "true" {
		t.Fatalf("socios: got %q", q.Get("tem_socios"))
	}
}

func TestBuildActiveFilterTags_contato(t *testing.T) {
	base := url.Values{}
	base.Set("uf", "BA")
	params := SearchForm{TemTelefone: "true", TemEmail: "true", TemSocios: "true"}
	tags := BuildActiveFilterTags(params, base, FilterTagContext{})
	if len(tags) != 3 {
		t.Fatalf("expected 3 tags, got %d", len(tags))
	}
}

func TestEffectiveQ_mergesCNPJ(t *testing.T) {
	p := SearchForm{CNPJ: "07.367.073/0001-65"}
	if got := EffectiveQ(p); got != "07.367.073/0001-65" {
		t.Fatalf("got %q", got)
	}
	p2 := SearchForm{Q: "padaria", CNPJ: "07367073000165"}
	if got := EffectiveQ(p2); got != "padaria" {
		t.Fatalf("got %q", got)
	}
}

func TestToAPISearchParams_CNPJViaQ(t *testing.T) {
	p := ApplySearchDefaults(SearchForm{CNPJ: "07367073000165", UF: "SP"})
	sp := ToAPISearchParams(p)
	q := sp.ToQuery()
	if q.Get("q") != "07367073000165" {
		t.Fatalf("expected q param, got q=%q cnpj=%q", q.Get("q"), q.Get("cnpj"))
	}
	if q.Get("cnpj") != "" {
		t.Fatalf("cnpj param must not be sent: %q", q.Get("cnpj"))
	}
}

func TestToAPISearchParams_allFilters(t *testing.T) {
	p := ApplySearchDefaults(SearchForm{
		UF:                  "SP",
		CEP:                 "01310100",
		Bairro:              "Pinheiros",
		Logradouro:          "Paulista",
		MEI:                 "true",
		Simples:             "false",
		Porte:               "02",
		NaturezaJuridica:    "2062",
		TemTelefone:         "true",
	})
	sp := ToAPISearchParams(p)
	q := sp.ToQuery()
	for _, key := range []string{"cep", "bairro", "logradouro", "mei", "simples", "porte", "natureza_juridica", "tem_telefone"} {
		if q.Get(key) == "" {
			t.Fatalf("missing %s", key)
		}
	}
}

func TestRequiresUFAndMunicipio(t *testing.T) {
	if !RequiresUFAndMunicipio(SearchForm{}) {
		t.Fatal("empty form should require location")
	}
	if !RequiresUFAndMunicipio(SearchForm{UF: "SP"}) {
		t.Fatal("uf only should require municipio")
	}
	if !RequiresUFAndMunicipio(SearchForm{Municipio: "3550308"}) {
		t.Fatal("municipio only should require uf")
	}
	if RequiresUFAndMunicipio(SearchForm{UF: "SP", Municipio: "3550308"}) {
		t.Fatal("uf+municipio should be allowed")
	}
	if RequiresUFAndMunicipio(SearchForm{CNPJ: "07367073000165"}) {
		t.Fatal("cnpj-only lookup should skip location")
	}
	if !RequiresUFAndMunicipio(SearchForm{CNPJ: "07367073000165", UF: "SP"}) {
		t.Fatal("cnpj with extra filters needs location")
	}
}

func TestRequiresUFOrMunicipio(t *testing.T) {
	if !RequiresUFOrMunicipio(SearchForm{Q: "padaria"}) {
		t.Fatal("text without uf/mun should require")
	}
	if RequiresUFOrMunicipio(SearchForm{Q: "padaria", UF: "SP"}) {
		t.Fatal("text with uf should not require")
	}
	if RequiresUFOrMunicipio(SearchForm{CNPJ: "07367073000165"}) {
		t.Fatal("cnpj should not require uf")
	}
}

func TestIsCNPJLookup(t *testing.T) {
	if !IsCNPJLookup(SearchForm{CNPJ: "07367073000165"}) {
		t.Fatal("expected cnpj-only lookup")
	}
	if IsCNPJLookup(SearchForm{CNPJ: "07367073000165", UF: "SP"}) {
		t.Fatal("cnpj with uf is not lookup-only")
	}
}

func TestExtractCNPJDigits(t *testing.T) {
	for _, c := range []struct {
		in  string
		out string
	}{
		{"07.367.073/0001-65", "07367073000165"},
		{"07367073", "07367073"},
	} {
		got, ok := ExtractCNPJDigits(c.in)
		if !ok || got != c.out {
			t.Fatalf("%q => %q ok=%v", c.in, got, ok)
		}
	}
}

func TestToAPISearchParams_type(t *testing.T) {
	var _ api.SearchParams = ToAPISearchParams(SearchForm{})
}

func TestApplyAppSearchDefaults_pristine(t *testing.T) {
	p := ApplyAppSearchDefaults(ParseSearchForm(url.Values{}), url.Values{})
	if len(p.SituacaoCadastral) != 1 || p.SituacaoCadastral[0] != "2" {
		t.Fatalf("situacao: %v", p.SituacaoCadastral)
	}
	if p.TemTelefone != "" || p.TemEmail != "" {
		t.Fatalf("contato deve ficar vazio no estado inicial: tel=%q email=%q", p.TemTelefone, p.TemEmail)
	}
}

func TestDefaultAppBuscaParams(t *testing.T) {
	p := DefaultAppBuscaParams()
	if len(p.SituacaoCadastral) != 1 || p.SituacaoCadastral[0] != "2" {
		t.Fatalf("situacao: %v", p.SituacaoCadastral)
	}
	if p.PageSize != 10 {
		t.Fatalf("page_size: %d", p.PageSize)
	}
}

func TestApplyAppSearchDefaults_submittedRespectsUnchecked(t *testing.T) {
	q := url.Values{"busca_submitted": {"1"}, "uf": {"SP"}}
	p := ApplyAppSearchDefaults(ParseSearchForm(q), q)
	if len(p.SituacaoCadastral) != 0 || p.TemTelefone != "" || p.TemEmail != "" {
		t.Fatalf("expected no defaults after explicit submit: %+v", p)
	}
}

func TestApplyAppSearchDefaults_savedState(t *testing.T) {
	q := url.Values{"uf": {"RJ"}, "page": {"2"}}
	p := ApplyAppSearchDefaults(ParseSearchForm(q), q)
	if p.TemTelefone == "true" {
		t.Fatal("should not re-apply defaults on saved pagination state")
	}
}

func TestToProductSearchQuery_productParamNames(t *testing.T) {
	p := SearchForm{
		Porte:        "02",
		MEI:          "true",
		Simples:      "false",
		TemWhatsApp:  "true",
		TemSocios:    "true",
		CEP:          "01310-100",
	}
	q := ToProductSearchQuery(p)
	for _, pair := range [][2]string{
		{"porte_empresa", "02"},
		{"opcao_mei", "true"},
		{"opcao_pelo_simples", "false"},
		{"tem_whatsapp", "true"},
		{"tem_socios", "true"},
		{"cep", "01310100"},
	} {
		if q.Get(pair[0]) != pair[1] {
			t.Fatalf("%s: got %q want %q", pair[0], q.Get(pair[0]), pair[1])
		}
	}
}
