package portais

import (
	"context"
	"fmt"
	"strings"

	"gitlab.com/sistema-pro/xmlcolibex/internal/consulta"
	"gitlab.com/sistema-pro/xmlcolibex/internal/portais/especificos"
	"gitlab.com/sistema-pro/xmlcolibex/internal/regras"
)

func transformarImovel(
	ctx context.Context,
	g *Gerador,
	feed consulta.FeedConfig,
	meta MetaPortal,
	im consulta.ImovelRow,
	dest consulta.DestaqueDB,
	fotosDB []consulta.FotoDB,
	urlsPadrao []string,
	textoPadraoMaster string,
	urls regras.URLsFotos,
) (ImovelTemplate, error) {
	m := ImovelTemplate{}

	descPadraoCompleta := ""
	if feed.TextoPadrao == 1 {
		descPadraoCompleta = regras.DescricaoPadraoCompleta(textoPadraoMaster, im.DescricaoCaixa, "<br>")
	}
	textoAdicional := regras.TextoAdicionalFormatado(textoPadraoMaster)

	var textoAnuncio string
	switch feed.IDPortal {
	case 47:
		textoAnuncio = regras.MontarDescricaoImovelWebNovo(
			im.Descricao, im.DescricaoCaixa, im.DescricaoPadrao, im.RefCaixa,
			textoAdicional, descPadraoCompleta,
		)
		textoAnuncio = regras.DescricaoAjustar(im.RefCaixa, im.Estado, textoAnuncio)
	case 32:
		descExtra := ""
		if im.DescricaoPadrao == 1 && feed.TextoPadrao == 1 {
			descExtra = descPadraoCompleta
		}
		textoAnuncio = regras.MontarDescricaoChaveNaMao(
			im.Descricao, im.DescricaoCaixa, descExtra, im.DescricaoPadrao, im.RefCaixa, descPadraoCompleta,
		)
	default:
		textoAnuncio = regras.MontarDescricaoComRegrasCaixaComEstado(
			im.Descricao, im.DescricaoCaixa, im.Estado,
			im.DescricaoPadrao, im.RefCaixa, feed.TextoPadrao, textoAdicional, descPadraoCompleta,
		)
	}

	areaUtil := im.AreaUtil
	areaTotal := im.AreaTotal
	if areaUtil == "" && im.RefCaixa != "" {
		if im.AreaPrivativaCaixa != "" {
			areaUtil = regras.TratarAreaVivareal(im.AreaPrivativaCaixa, im.NomeCategoria)
		} else {
			areaUtil = regras.TratarAreaVivareal(im.AreaTotalCaixa, im.NomeCategoria)
		}
	}
	if areaTotal == "" && im.RefCaixa != "" {
		if im.AreaPrivativaCaixa != "" {
			areaTotal = regras.TratarAreaVivareal(im.AreaPrivativaCaixa, im.NomeCategoria)
		} else {
			areaTotal = regras.TratarAreaVivareal(im.AreaTotalCaixa, im.NomeCategoria)
		}
	}
	if areaUtil != "" && feed.IDPortal != 47 {
		areaUtil = regras.TratarAreaVivareal(areaUtil, im.NomeCategoria)
	}
	if areaTotal != "" && feed.IDPortal != 47 {
		areaTotal = regras.TratarAreaVivareal(areaTotal, im.NomeCategoria)
	}

	fotos := montarFotosImovel(ctx, g, fotosDB, im, feed, urls, urlsPadrao)
	fotosXML := regras.RenderizarFotos(meta.FormatoFotos, fotos)
	if feed.IDPortal == 45 {
		fotosXML = regras.FotosFacebookXML(fotos)
	}

	feats, _ := g.Repo.CarregarFeaturesServicos(ctx, im.ServicosDisponiveis)
	servicos := regras.MontarServicosVivareal(feats)

	destaque := regras.FormatarDestaquePorPortal(feed.IDPortal, regras.DestaqueInfo{SEO: dest.SEO, Nome: dest.Nome}, im.DestaquePortal)

	valorAvaliacao := ""
	if im.RefCaixa != "" && im.ValorAvaliacao != "" {
		valorAvaliacao = "Valor avalidação : R$ " + im.ValorAvaliacao
	}

	m["referencia"] = regras.CorrigirLatin1(im.Referencia)
	m["id_master"] = fmt.Sprintf("%d", im.IDMaster)
	m["titulo"] = regras.CorrigirLatin1(regras.StripTags(strings.ReplaceAll(im.Titulo, "<br>", "")))
	m["descricao"] = regras.CorrigirLatin1(textoAnuncio)
	m["descricaoPadrao"] = ""
	m["transacao"] = regras.TipoTransacaoVivareal(im.Transacao)
	m["cidade"] = regras.CorrigirLatin1(im.Cidade)
	m["estado"] = im.Estado
	m["cep"] = im.CEP
	m["bairro"] = regras.CorrigirLatin1(im.Bairro)
	m["endereco"] = regras.EnderecoOculto(feed.ViewEndereco, im.Endereco)
	m["numero"] = regras.EnderecoOculto(feed.ViewEndereco, im.Numero)
	m["complemento"] = regras.EnderecoOculto(feed.ViewEndereco, im.Complemento)
	m["zona"] = im.Zona
	m["video"] = im.Video
	m["location"] = regras.DisplayEndereco(feed.ViewEndereco)
	m["valor_avaliacao"] = valorAvaliacao
	m["valor_venda"] = regras.TipoPrecoVivareal(im.ValorVenda, "valor_venda")
	m["valor_locacao"] = regras.TipoPrecoVivareal(im.ValorLocacao, "valor_locacao")
	m["valor_locacao_diario"] = regras.TipoPrecoVivareal(im.ValorLocacaoDiario, "valor_locacao_diario")
	m["valor_condominio"] = regras.ValorCondominioSemCentavos(im.ValorCondominio)
	m["valor_iptu"] = regras.ValorIPTUSemCentavos(im.ValorIPTU)
	m["iptu"] = m["valor_iptu"]
	m["vagas"] = defaultZero(im.Vagas)
	m["suites"] = defaultZero(im.Suites)
	m["andar"] = im.Andar
	m["ano_construcao"] = formatAnoConstrucao(feed.IDPortal, im.AnoConstrucao)
	m["area_util"] = areaUtil
	m["area_total"] = areaTotal
	m["area_construida"] = regras.TratarAreaVivareal(im.AreaConstruida, im.NomeCategoria)
	m["fotos"] = fotosXML
	m["fotosCaixa"] = ""
	m["fotosPadrao"] = ""
	m["destaque"] = destaque
	m["servicos"] = servicos
	m["servicos_new"] = im.ServicosNew

	m["tipo"] = regras.CorrigirLatin1(im.UsageTypeVivareal)
	m["subtipo"] = im.TipoVivareal
	if feed.IDPortal == 46 || feed.IDPortal == 29 {
		m["tipo"] = regras.CorrigirLatin1(im.TipoVivareal)
		m["subtipo"] = im.UsageTypeVivareal
	}

	m["banheiro"] = banheiroPorPortal(feed.IDPortal, im)
	m["quartos"] = quartosPorPortal(feed.IDPortal, im)

	if meta.FormatoFotos == regras.FormatoZap {
		m["valor_venda"] = regras.TipoPrecoSimples(im.ValorVenda)
		m["valor_locacao"] = regras.TipoPrecoSimples(im.ValorLocacao)
	}
	if feed.IDPortal == 14 {
		m["tipo"] = im.MercadoLivreTipo
		m["subtipo"] = im.SubtipoOLX
		m["banheiro"] = regras.BanheiroMercadoLivre(im.Banheiros)
	}
	if feed.IDPortal == 45 {
		m["transacao"] = regras.DisponibilidadeFacebook(im.Transacao)
		m["price"] = regras.PrecoFacebookFormatado(im.Transacao, im.ValorVenda, im.ValorLocacao)
		m["property_type"] = regras.PropertyTypeFacebook(im.CategoriaFacebook)
		m["url_anuncio"] = fmt.Sprintf("/detalhes/%d.html", im.IDImovel)
		m["latitude"] = regras.ExtrairLatitude(im.Coordenadas)
		m["longitude"] = regras.ExtrairLongitude(im.Coordenadas)
		m["city_id"] = ""
		m["province"] = ""
		m["fotos"] = fotosXML
	}

	especificos.Aplicar(ctx, feed.IDPortal, especificos.Params{
		Feed:        feed,
		Im:          im,
		M:           especificos.ImovelMap(m),
		NaventToken: g.Cfg.NaventAccessToken,
		ZapLoader:   g.Repo,
	})

	for k, v := range m {
		m[k] = regras.CorrigirLatin1(v)
	}
	return m, nil
}

func montarFotosImovel(ctx context.Context, g *Gerador, fotosDB []consulta.FotoDB, im consulta.ImovelRow, feed consulta.FeedConfig, urls regras.URLsFotos, urlsPadrao []string) []regras.FotoItem {
	marca := feed.Marca == 1
	if im.RefCaixa != "" {
		var items []regras.FotoItem
		ids, err := g.Repo.CarregarIDsFotosCaixa(ctx, im.RefCaixa)
		if err == nil {
			for _, id := range ids {
				items = append(items, regras.FotoItem{
					URL: regras.MontarURLFotoCaixa(urls.FotoCaixaBase, id),
				})
			}
		}
		for _, u := range urlsPadrao {
			if strings.HasPrefix(u, "http") {
				items = append(items, regras.FotoItem{URL: u})
			}
		}
		if len(items) == 0 {
			return montarFotosParticular(fotosDB, im, marca, urls, urlsPadrao, feed)
		}
		return items
	}
	return montarFotosParticular(fotosDB, im, marca, urls, urlsPadrao, feed)
}

func montarFotosParticular(fotosDB []consulta.FotoDB, im consulta.ImovelRow, marca bool, urls regras.URLsFotos, urlsPadrao []string, feed consulta.FeedConfig) []regras.FotoItem {
	var items []regras.FotoItem
	for _, f := range fotosDB {
		url := f.Foto
		if marca {
			url = regras.MontarURLMarcaDagua(urls.MarcaDaguaBase, f.IDMaster, f.ID)
		} else if !strings.HasPrefix(url, "http") {
			url = regras.MontarURLFotoImovel(urls.ArquivosBase, f.IDMaster, f.IDImovel, f.Foto)
		}
		items = append(items, regras.FotoItem{URL: url})
	}
	if im.FotoPadrao == 1 || (feed.FotosPadrao == 1 && len(urlsPadrao) > 0) {
		for _, u := range urlsPadrao {
			items = append(items, regras.FotoItem{URL: u})
		}
	}
	return items
}

func defaultZero(v string) string {
	if strings.TrimSpace(v) == "" {
		return "0"
	}
	return v
}

func formatAnoConstrucao(idPortal int, ano string) string {
	if ano == "" {
		return ""
	}
	if idPortal == 2 || idPortal == 48 {
		return fmt.Sprintf("<AnoConstrucao>%s</AnoConstrucao>", ano)
	}
	return ano
}

func banheiroPorPortal(idPortal int, im consulta.ImovelRow) string {
	tipo := im.TipoVivareal
	switch idPortal {
	case 32:
		return regras.TratarBanheiroChavesNaMao(im.Banheiros, tipo)
	case 2, 48:
		return regras.SoNumero(im.Banheiros)
	case 3, 5, 6, 7, 8, 9, 10, 11, 12, 18, 19, 25, 27, 33, 47, 15:
		if im.Banheiros == "" {
			return "0"
		}
		return im.Banheiros
	default:
		return regras.TratarBanheiroVivareal(im.Banheiros, tipo)
	}
}

func quartosPorPortal(idPortal int, im consulta.ImovelRow) string {
	tipo := im.TipoVivareal
	switch idPortal {
	case 2, 48:
		return regras.TratarQuartoZap(im.Quartos, tipo, im.RefCaixa, im.IDMaster)
	case 32:
		return regras.TratarQuartoChavesNaMao(im.Quartos, tipo)
	case 3, 5, 6, 7, 8, 9, 10, 11, 12, 18, 19, 25, 27, 33, 47, 15:
		if im.Quartos == "" {
			return "0"
		}
		return im.Quartos
	default:
		return regras.TratarQuartoVivareal(im.Quartos, tipo)
	}
}
