package regras

import (
	"fmt"
	"strconv"
	"strings"
)

// ClausulaInOuTodosAtivos espelha XmlImoveisExportHelper::clausulaInOuTodosAtivos.
func ClausulaInOuTodosAtivos(idsImovel []int) string {
	if len(idsImovel) == 0 {
		return ""
	}
	seen := make(map[int]struct{}, len(idsImovel))
	parts := make([]string, 0, len(idsImovel))
	for _, id := range idsImovel {
		if id <= 0 {
			continue
		}
		if _, ok := seen[id]; ok {
			continue
		}
		seen[id] = struct{}{}
		parts = append(parts, strconv.Itoa(id))
	}
	if len(parts) == 0 {
		return ""
	}
	return " AND id_imovel IN (" + strings.Join(parts, ",") + ")"
}

// ParametrosExportacao parâmetros de xml_config para montagem de cláusula.
type ParametrosExportacao struct {
	StatusConfig        int
	LimiteXML           int
	SendAll             int
	SendAllParticular   int
	SendAllCaixa        int
	IDsMarcados         []int
	FiltrosSoSendAllZero bool
}

// ResultadoExportacao cláusula SQL extra, LIMIT e ORDER BY.
type ResultadoExportacao struct {
	ClausulaExtra string
	Limit         string
	OrderBy       string
}

// MontarClausulaELimiteExportacao espelha Controller::xmlMontarClausulaELimiteExportacao.
func MontarClausulaELimiteExportacao(p ParametrosExportacao) ResultadoExportacao {
	r := ResultadoExportacao{}
	if p.StatusConfig == 0 {
		r.Limit = " LIMIT 0 "
		return r
	}
	if p.LimiteXML >= 1 {
		r.Limit = fmt.Sprintf(" LIMIT %d ", p.LimiteXML)
	}
	if len(p.IDsMarcados) == 0 {
		return r
	}
	if p.FiltrosSoSendAllZero && p.SendAll == 1 {
		return r
	}
	clausulaIn := ClausulaInOuTodosAtivos(p.IDsMarcados)
	sa := p.SendAll
	sp := p.SendAllParticular
	sc := p.SendAllCaixa
	lm := p.LimiteXML

	if sa == 1 {
		r.ClausulaExtra = ""
	} else if sp == 1 && sc == 0 {
		r.ClausulaExtra = " AND ref_caixa = '' " + clausulaIn
	} else if sc == 1 && sp == 0 {
		r.ClausulaExtra = " AND ref_caixa != '' " + clausulaIn
	} else if sp == 1 && sc == 1 {
		r.ClausulaExtra = clausulaIn
	} else {
		if sa == 0 && lm == 0 {
			r.ClausulaExtra = clausulaIn
		}
	}
	return r
}

// IDsConfigComVinculo retorna lista de id_xml_config incluindo vínculo.
func IDsConfigComVinculo(idConfig int, vinculo string) []int {
	vinculo = strings.TrimSpace(vinculo)
	if vinculo == "" || vinculo == "0" {
		return []int{idConfig}
	}
	v, err := strconv.Atoi(vinculo)
	if err != nil || v <= 0 {
		return []int{idConfig}
	}
	return []int{idConfig, v}
}

// MontarClausulaChaveNaMao espelha Portal_ChaveNaMao.php (send_all=1 mantém IN).
func MontarClausulaChaveNaMao(p ParametrosExportacao, podeLimitar bool) ResultadoExportacao {
	r := ResultadoExportacao{}
	if p.StatusConfig == 0 {
		r.Limit = " LIMIT 0 "
		return r
	}
	clausulaIn := ""
	if len(p.IDsMarcados) > 0 {
		clausulaIn = ClausulaInOuTodosAtivos(p.IDsMarcados)
		sa := p.SendAll
		sp := p.SendAllParticular
		sc := p.SendAllCaixa
		if sa == 1 {
			r.ClausulaExtra = clausulaIn
		} else if sp == 1 && sc == 0 {
			r.ClausulaExtra = " AND ref_caixa = '' " + clausulaIn
		} else if sc == 1 && sp == 0 {
			r.ClausulaExtra = " AND ref_caixa != '' " + clausulaIn
		} else if sp == 1 && sc == 1 {
			r.ClausulaExtra = clausulaIn
		} else if sa != 1 {
			r.ClausulaExtra = clausulaIn
		}
	}
	if podeLimitar && p.LimiteXML > 0 {
		r.OrderBy = " ORDER BY CASE WHEN COALESCE(TRIM(ref_caixa), '') = '' THEN 0 ELSE 1 END ASC, id_imovel DESC "
		r.Limit = fmt.Sprintf(" LIMIT %d ", p.LimiteXML)
	}
	return r
}
