package consulta

import (
	"context"
	"fmt"
	"strings"

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

// ListarImoveisPorPortal delega consulta conforme id_portal.
func (r *Repositorio) ListarImoveisPorPortal(ctx context.Context, feed FeedConfig, idsMarcados []int) ([]ImovelRow, error) {
	switch feed.IDPortal {
	case 32:
		return r.listarImoveisChaveNaMao(ctx, feed, idsMarcados)
	case 3:
		if strings.TrimSpace(feed.Vinculo) != "" && feed.Vinculo != "0" &&
			feed.SendAllParticular == 0 && feed.SendAllCaixa == 1 {
			return r.listarImoveisImovelWebVinculo(ctx, feed, idsMarcados)
		}
	}
	cl := MontarClausulaFeed(feed, idsMarcados)
	return ListarImoveisFeed(ctx, r.DB, feed.IDMaster, cl.ClausulaExtra, cl.Limit, cl.OrderBy, feed.EstadoXML)
}

func (r *Repositorio) listarImoveisChaveNaMao(ctx context.Context, feed FeedConfig, idsMarcados []int) ([]ImovelRow, error) {
	podeLimitar := feed.SendAll == 1 || feed.SendAllParticular == 1 || feed.SendAllCaixa == 1
	if len(idsMarcados) == 0 {
		podeLimitar = true
	}
	if !podeLimitar && feed.LimiteXML > 0 {
		totalAtivos, err := r.contarImoveisAtivos(ctx, feed.IDMaster, feed.EstadoXML)
		if err != nil {
			return nil, err
		}
		totalMarcados, err := r.contarImoveisMarcados(ctx, feed.IDXMLConfig, feed.IDMaster, feed.EstadoXML)
		if err != nil {
			return nil, err
		}
		podeLimitar = totalAtivos > 0 && totalMarcados >= totalAtivos
	}
	cl := regras.MontarClausulaChaveNaMao(regras.ParametrosExportacao{
		StatusConfig:      feed.Status,
		LimiteXML:         feed.LimiteXML,
		SendAll:           feed.SendAll,
		SendAllParticular: feed.SendAllParticular,
		SendAllCaixa:      feed.SendAllCaixa,
		IDsMarcados:       idsMarcados,
	}, podeLimitar)
	return ListarImoveisFeed(ctx, r.DB, feed.IDMaster, cl.ClausulaExtra, cl.Limit, cl.OrderBy, feed.EstadoXML)
}

func (r *Repositorio) listarImoveisImovelWebVinculo(ctx context.Context, feed FeedConfig, idsMarcados []int) ([]ImovelRow, error) {
	cl := regras.MontarClausulaELimiteExportacao(regras.ParametrosExportacao{
		StatusConfig:      feed.Status,
		LimiteXML:         feed.LimiteXML,
		SendAll:           feed.SendAll,
		SendAllParticular: feed.SendAllParticular,
		SendAllCaixa:      feed.SendAllCaixa,
		IDsMarcados:       idsMarcados,
	})
	if feed.Status == 0 {
		return ListarImoveisFeed(ctx, r.DB, feed.IDMaster, "", " LIMIT 0 ", "", feed.EstadoXML)
	}
	clausulaIn := regras.ClausulaInOuTodosAtivos(idsMarcados)
	particular := "AND ref_caixa = '' "
	if clausulaIn != "" {
		particular += clausulaIn
	} else if len(idsMarcados) == 0 {
		particular = "AND ref_caixa = '' "
	}
	caixa := "AND ref_caixa != '' "
	estado := ""
	if feed.EstadoXML != "" {
		estado = fmt.Sprintf(" AND i.estado = '%s'", escapeSQL(feed.EstadoXML))
	}
	q := fmt.Sprintf(`SELECT %s FROM imoveis i JOIN categorias c ON i.categoria = c.id
WHERE i.id_master = ? AND i.status = 'Ativo' %s %s %s
UNION SELECT %s FROM imoveis i JOIN categorias c ON i.categoria = c.id
WHERE i.id_master = ? AND i.status = 'Ativo' %s %s`,
		sqlImoveisSelect, estado, particular, cl.Limit,
		sqlImoveisSelect, estado, caixa)
	return queryImoveis(ctx, r.DB, q, feed.IDMaster, feed.IDMaster)
}

func (r *Repositorio) contarImoveisAtivos(ctx context.Context, idMaster int, estadoXML string) (int, error) {
	q := `SELECT COUNT(*) FROM imoveis WHERE id_master = ? AND status = 'Ativo'`
	args := []any{idMaster}
	if estadoXML != "" {
		q += " AND estado = ?"
		args = append(args, estadoXML)
	}
	var n int
	err := r.DB.QueryRowContext(ctx, q, args...).Scan(&n)
	return n, err
}

func (r *Repositorio) contarImoveisMarcados(ctx context.Context, idConfig, idMaster int, estadoXML string) (int, error) {
	q := `SELECT COUNT(DISTINCT xi.imovel) FROM xml_imoveis xi
INNER JOIN imoveis i ON xi.imovel = i.id_imovel AND xi.id_master = i.id_master
WHERE xi.id_xml_config = ? AND i.id_master = ? AND i.status = 'Ativo'`
	args := []any{idConfig, idMaster}
	if estadoXML != "" {
		q += " AND i.estado = ?"
		args = append(args, estadoXML)
	}
	var n int
	err := r.DB.QueryRowContext(ctx, q, args...).Scan(&n)
	return n, err
}
