package portais

import (
	"context"
	"encoding/json"
	"strings"

	"gitlab.com/sistema-pro/xmlcolibex/internal/configuracao"
	"gitlab.com/sistema-pro/xmlcolibex/internal/consulta"
	"gitlab.com/sistema-pro/xmlcolibex/internal/regras"
	"gitlab.com/sistema-pro/xmlcolibex/internal/renderizacao"
)

type Gerador struct {
	Cfg    *configuracao.Config
	Repo   *consulta.Repositorio
	Motor  *renderizacao.Motor
}

func (g *Gerador) GerarFeed(ctx context.Context, feed consulta.FeedConfig, onProgress func(feito, total int, msg string)) ([]byte, error) {
	meta := ResolverMetaPortal(feed.IDPortal, feed.PortalSEO, feed.PortalNome)

	idsConfig := regras.IDsConfigComVinculo(feed.IDXMLConfig, feed.Vinculo)
	idsMarcados, err := g.Repo.ListarIDsImoveisMarcados(ctx, idsConfig, feed.IDMaster)
	if err != nil {
		return nil, err
	}
	imoveis, err := g.Repo.ListarImoveisPorPortal(ctx, feed, idsMarcados)
	if err != nil {
		return nil, err
	}
	total := len(imoveis)
	if onProgress != nil {
		onProgress(0, total, "consulta OK")
	}

	cab, err := g.Repo.CarregarCabecalhoFeed(ctx, feed.IDMaster, feed.IDXMLConfig)
	if err != nil {
		return nil, err
	}
	textoPadrao, _ := g.Repo.CarregarTextoPadrao(ctx, feed.IDMaster)
	fotosPadraoJSON, _ := g.Repo.CarregarFotosPadraoJSON(ctx, feed.IDMaster)
	urlsPadrao := parseJSONArray(fotosPadraoJSON)

	tel := regras.TelefoneContato(cab.Telefone, cab.WhatsApp, cab.Celular)
	header := map[string]string{
		"nome_concat":    regras.CorrigirLatin1(cab.NomeConcat),
		"email":          regras.PrimeiroEmailJSON(cab.Email),
		"telefone":       tel,
		"whatsapp":       tel,
		"data_alteracao": cab.DataAlteracao,
		"dominio":        cab.Dominio,
		"creci":          cab.CRECI,
	}

	lote := g.Cfg.LoteImoveis
	if lote < 1 {
		lote = 500
	}
	out := make([]ImovelTemplate, 0, total)
	urls := regras.URLsFotos{
		MarcaDaguaBase: g.Cfg.MarcaDaguaBaseURL,
		FotoCaixaBase:  g.Cfg.FotoCaixaBaseURL,
		ArquivosBase:   g.Cfg.ArquivosBaseURL,
	}

	for i := 0; i < total; i += lote {
		fim := i + lote
		if fim > total {
			fim = total
		}
		loteRows := imoveis[i:fim]
		idsLote := make([]int, len(loteRows))
		for j, im := range loteRows {
			idsLote[j] = im.IDImovel
		}
		destaques, err := g.Repo.CarregarDestaques(ctx, idsConfig, feed.IDMaster, idsLote)
		if err != nil {
			return nil, err
		}
		fotosMap, err := g.Repo.CarregarFotosImoveis(ctx, idsLote)
		if err != nil {
			return nil, err
		}
		for _, im := range loteRows {
			item, err := transformarImovel(ctx, g, feed, meta, im, destaques[im.IDImovel], fotosMap[im.IDImovel], urlsPadrao, textoPadrao, urls)
			if err != nil {
				return nil, err
			}
			out = append(out, item)
		}
		if onProgress != nil {
			onProgress(fim, total, "transformação")
		}
	}

	dados := DadosTemplate{Header: header, Imoveis: out}
	if feed.IDPortal == 47 {
		dados.Data = feed.DataAlteracao.UnixMilli()
	}
	return g.Motor.Renderizar(meta.NomeModelo, dados)
}

func parseJSONArray(raw string) []string {
	raw = strings.TrimSpace(raw)
	if raw == "" {
		return nil
	}
	var arr []string
	if err := json.Unmarshal([]byte(raw), &arr); err != nil {
		return nil
	}
	return arr
}
