package render

import (
	"fmt"
	"net/url"
	"strconv"

	"leadb2b.org/internal/api"
)

type ActiveFilterTag struct {
	Label     string
	RemoveURL string
	Kind      string
}

type FilterTagContext struct {
	UFs        []api.FiltroOpcao
	Municipios []api.MunicipioItem
	Situacoes  []api.FiltroOpcao
	CNAEs      []api.CnaeItem
}

func BuildActiveFilterTags(params SearchForm, base url.Values, ctx FilterTagContext) []ActiveFilterTag {
	return buildActiveFilterTags(params, base, ctx, "/busca")
}

func BuildAppActiveFilterTags(params SearchForm, base url.Values, ctx FilterTagContext) []ActiveFilterTag {
	return buildActiveFilterTags(params, base, ctx, "/app/busca")
}

func buildActiveFilterTags(params SearchForm, base url.Values, ctx FilterTagContext, basePath string) []ActiveFilterTag {
	var tags []ActiveFilterTag

	if params.Q != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Busca: " + params.Q,
			RemoveURL: removeFilterURL(base, "q", "", basePath),
		})
	}
	if params.CNPJ != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "CNPJ: " + params.CNPJ,
			RemoveURL: removeFilterURL(base, "cnpj", "", basePath),
		})
	}
	if params.UF != "" {
		q := cloneSearchQuery(base)
		q.Del("uf")
		q.Del("municipio")
		tags = append(tags, ActiveFilterTag{
			Label:     "UF: " + lookupUF(ctx.UFs, params.UF),
			RemoveURL: listingURL(basePath, q),
		})
	}
	if params.Municipio != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Município: " + lookupMunicipio(ctx.Municipios, params.Municipio),
			RemoveURL: removeFilterURL(base, "municipio", "", basePath),
		})
	}
	for i, cnae := range params.CNAEFiscalPrincipal {
		if cnae == "" {
			continue
		}
		if i > 0 {
			break
		}
		tags = append(tags, ActiveFilterTag{
			Label:     "CNAE: " + LookupCNAEDescricao(ctx.CNAEs, cnae),
			RemoveURL: removeFilterURL(base, "cnae_fiscal_principal", cnae, basePath),
			Kind:      "cnae",
		})
	}
	if params.DataInicioAno != "" || params.DataInicioMes != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Abertura: " + formatAbertura(params.DataInicioAno, params.DataInicioMes),
			RemoveURL: removeAberturaURL(base, basePath),
		})
	}
	for _, code := range params.SituacaoCadastral {
		if code == "" {
			continue
		}
		tags = append(tags, ActiveFilterTag{
			Label:     lookupSituacao(ctx.Situacoes, code),
			RemoveURL: removeFilterURL(base, "situacao_cadastral", code, basePath),
		})
	}
	switch params.IdentificadorMatrizFilial {
	case "1":
		tags = append(tags, ActiveFilterTag{
			Label:     "Matriz",
			RemoveURL: removeFilterURL(base, "identificador_matriz_filial", "", basePath),
		})
	case "2":
		tags = append(tags, ActiveFilterTag{
			Label:     "Filial",
			RemoveURL: removeFilterURL(base, "identificador_matriz_filial", "", basePath),
		})
	}
	if params.TemTelefone == "true" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Com telefone",
			RemoveURL: removeFilterURL(base, "tem_telefone", "", basePath),
		})
	}
	switch params.TemEmail {
	case "true":
		tags = append(tags, ActiveFilterTag{
			Label:     "Com e-mail",
			RemoveURL: removeFilterURL(base, "tem_email", "", basePath),
		})
	case "false":
		tags = append(tags, ActiveFilterTag{
			Label:     "Sem e-mail",
			RemoveURL: removeFilterURL(base, "tem_email", "", basePath),
		})
	}
	if params.TemSocios == "true" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Com sócios",
			RemoveURL: removeFilterURL(base, "tem_socios", "", basePath),
		})
	}
	if params.TemWhatsApp == "true" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Com WhatsApp",
			RemoveURL: removeFilterURL(base, "tem_whatsapp", "", basePath),
		})
	}
	if params.CEP != "" {
		label := "CEP: " + FormatCEPDisplay(params.CEP)
		if label == "CEP: " {
			label = "CEP: " + params.CEP
		}
		tags = append(tags, ActiveFilterTag{
			Label:     label,
			RemoveURL: removeFilterURL(base, "cep", "", basePath),
		})
	}
	if params.Bairro != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Bairro: " + params.Bairro,
			RemoveURL: removeFilterURL(base, "bairro", "", basePath),
		})
	}
	if params.Logradouro != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Logradouro: " + params.Logradouro,
			RemoveURL: removeFilterURL(base, "logradouro", "", basePath),
		})
	}
	switch params.MEI {
	case "true":
		tags = append(tags, ActiveFilterTag{
			Label:     "MEI",
			RemoveURL: removeFilterURL(base, "mei", "", basePath),
		})
	case "false":
		tags = append(tags, ActiveFilterTag{
			Label:     "Não MEI",
			RemoveURL: removeFilterURL(base, "mei", "", basePath),
		})
	}
	switch params.Simples {
	case "true":
		tags = append(tags, ActiveFilterTag{
			Label:     "Simples Nacional",
			RemoveURL: removeFilterURL(base, "simples", "", basePath),
		})
	case "false":
		tags = append(tags, ActiveFilterTag{
			Label:     "Fora do Simples",
			RemoveURL: removeFilterURL(base, "simples", "", basePath),
		})
	}
	if params.Porte != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Porte: " + lookupPorte(params.Porte),
			RemoveURL: removeFilterURL(base, "porte", "", basePath),
		})
	}
	if params.NaturezaJuridica != "" {
		tags = append(tags, ActiveFilterTag{
			Label:     "Natureza jurídica: " + LookupNaturezaJuridica(params.NaturezaJuridica),
			RemoveURL: removeFilterURL(base, "natureza_juridica", "", basePath),
		})
	}

	return tags
}

func lookupPorte(code string) string {
	for _, p := range PorteOptions() {
		if p.Codigo == code {
			return p.Descricao
		}
	}
	return code
}

func removeFilterURL(base url.Values, key, value, basePath string) string {
	q := cloneSearchQuery(base)
	if value == "" {
		q.Del(key)
	} else {
		vals := q[key]
		q.Del(key)
		for _, v := range vals {
			if v != value {
				q.Add(key, v)
			}
		}
	}
	return listingURL(basePath, q)
}

func removeAberturaURL(base url.Values, basePath string) string {
	q := cloneSearchQuery(base)
	q.Del("data_inicio_ano")
	q.Del("data_inicio_mes")
	return listingURL(basePath, q)
}

func listingURL(basePath string, q url.Values) string {
	if len(q) == 0 {
		return basePath
	}
	return basePath + "?" + q.Encode()
}

func lookupUF(ufs []api.FiltroOpcao, code string) string {
	for _, u := range ufs {
		if fmt.Sprint(u.Codigo) == code {
			return u.Descricao
		}
	}
	return code
}

func lookupMunicipio(items []api.MunicipioItem, code string) string {
	for _, m := range items {
		if fmt.Sprint(m.Codigo) == code || strconv.Itoa(m.Codigo) == code {
			return m.Descricao
		}
	}
	return code
}

func lookupSituacao(items []api.FiltroOpcao, code string) string {
	for _, s := range items {
		if fmt.Sprint(s.Codigo) == code {
			return s.Descricao
		}
	}
	return "Situação " + code
}

func formatAbertura(ano, mes string) string {
	if mes != "" {
		if n, err := strconv.Atoi(mes); err == nil && n >= 1 && n <= 12 {
			mesLabel := Meses()[n-1].Label
			if ano != "" {
				return mesLabel + "/" + ano
			}
			return mesLabel
		}
	}
	if ano != "" {
		return ano
	}
	return mes
}
