package handlers

import (
	"context"
	"net/url"

	"leadb2b.org/internal/api"
	"leadb2b.org/internal/render"
)

const maxCEPScanPages = 12

func searchEstabelecimentosQuery(ctx context.Context, leads *api.LeadsService, query url.Values) (*api.EstabelecimentoSearchOut, error) {
	cep := render.NormalizeCEPDigits(query.Get("cep"))
	if cep == "" {
		return leads.SearchEstabelecimentosQuery(ctx, query)
	}
	form := render.ParseSearchForm(query)
	sp := render.ToAPISearchParams(form)

	pageSize := sp.PageSize
	if pageSize <= 0 {
		pageSize = 10
	}

	scanSize := pageSize * 3
	if scanSize < 30 {
		scanSize = 30
	}
	if scanSize > 50 {
		scanSize = 50
	}

	var collected []api.EstabelecimentoOut
	cursor := sp.Cursor
	var lastOut *api.EstabelecimentoSearchOut

	for page := 0; page < maxCEPScanPages && len(collected) < pageSize; page++ {
		round := sp
		round.Cursor = cursor
		round.PageSize = scanSize
		round.CEP = "" // API não filtra por CEP; evita ruído

		out, err := leads.SearchEstabelecimentos(ctx, round)
		if err != nil {
			return nil, err
		}
		lastOut = out

		collected = append(collected, render.FilterItemsByCEP(out.Items, cep)...)
		if !out.HasMore || out.NextCursor == nil || *out.NextCursor == "" {
			break
		}
		cursor = *out.NextCursor
	}

	if len(collected) > pageSize {
		collected = collected[:pageSize]
	}

	result := &api.EstabelecimentoSearchOut{
		Items:   collected,
		HasMore: false,
	}
	if lastOut != nil {
		result.Total = lastOut.Total
		if len(collected) >= pageSize && lastOut.HasMore {
			result.HasMore = true
			if lastOut.NextCursor != nil {
				c := *lastOut.NextCursor
				result.NextCursor = &c
			}
		}
	}
	return result, nil
}

func searchEstabelecimentos(ctx context.Context, leads *api.LeadsService, sp api.SearchParams) (*api.EstabelecimentoSearchOut, error) {
	return searchEstabelecimentosQuery(ctx, leads, sp.ToQuery())
}

func (h *Handler) searchEstabelecimentos(ctx context.Context, sp api.SearchParams) (*api.EstabelecimentoSearchOut, error) {
	return searchEstabelecimentos(ctx, h.leads, sp)
}
