package consulta

import (
	"context"
	"database/sql"
	"fmt"
	"strings"

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

const sqlImoveisSelect = `
  i.id_imovel, i.id_master, COALESCE(i.referencia,''), COALESCE(i.titulo,''), COALESCE(i.descricao,''), COALESCE(i.descricao_caixa,''),
  COALESCE(i.transacao,''), COALESCE(i.valor_venda,''), COALESCE(i.valor_locacao,''), COALESCE(i.valor_locacao_diario,''),
  COALESCE(i.valor_iptu,''), COALESCE(i.valor_condominio,''), COALESCE(i.valor_avaliacao,''),
  COALESCE(i.area_util,''), COALESCE(i.area_total,''), COALESCE(i.area_construida,''), COALESCE(i.area_privativa_caixa,''), COALESCE(i.area_total_caixa,''),
  COALESCE(i.quartos,''), COALESCE(i.suites,''), COALESCE(i.vagas,''), COALESCE(i.banheiros,''),
  COALESCE(i.andar,''), COALESCE(i.ano_construcao,''),
  i.categoria, COALESCE(c.nome,''), COALESCE(c.subtipo,''),
  COALESCE(c.id_imovel_web,0), CAST(COALESCE(i.mostrar_mapa,'0') AS UNSIGNED), COALESCE(i.destaque,''),
  COALESCE(c.tipo_vivareal,''), COALESCE(c.usagetype_vivareal,''),
  COALESCE(c.tipo_casa_mineira,''), COALESCE(c.subtipo_casa_mineira,''), COALESCE(c.categoria_casa_mineira,''),
  COALESCE(c.subtipoolx,''), COALESCE(c.mercadolivre_tipo,''), COALESCE(c.categoria_facebook,''),
  COALESCE(i.cep,''), COALESCE(i.endereco,''), COALESCE(i.numero,''), COALESCE(i.bairro,''),
  COALESCE(i.cidade,''), COALESCE(i.estado,''), COALESCE(i.complemento,''), COALESCE(i.zona,''),
  COALESCE(i.coordenadas,''), COALESCE(i.video,''), COALESCE(i.ref_caixa,''), COALESCE(i.estado_imovel,''),
  CAST(COALESCE(i.foto_padrao,'0') AS UNSIGNED), CAST(COALESCE(i.descricao_padrao,'0') AS UNSIGNED),
  COALESCE(i.servicos_disponiveis,''),
  REPLACE(REPLACE(COALESCE(i.servicos_disponiveis,''),'[',''),']','') AS servicos_new,
  COALESCE(i.destaque_portal,''), COALESCE(i.fotos,''),
  DATE_FORMAT(i.data_atualizacao,'%%d/%%m/%%Y'), DATE_FORMAT(i.data_cadastro,'%%d/%%m/%%Y')
`

const sqlImoveisBase = `
SELECT` + sqlImoveisSelect + `
FROM imoveis i
JOIN categorias c ON i.categoria = c.id
WHERE i.id_master = ? AND i.status = 'Ativo'
`

func scanImovelRow(r *sql.Rows) (ImovelRow, error) {
	var im ImovelRow
	err := r.Scan(
		&im.IDImovel, &im.IDMaster, &im.Referencia, &im.Titulo, &im.Descricao, &im.DescricaoCaixa,
		&im.Transacao, &im.ValorVenda, &im.ValorLocacao, &im.ValorLocacaoDiario,
		&im.ValorIPTU, &im.ValorCondominio, &im.ValorAvaliacao,
		&im.AreaUtil, &im.AreaTotal, &im.AreaConstruida, &im.AreaPrivativaCaixa, &im.AreaTotalCaixa,
		&im.Quartos, &im.Suites, &im.Vagas, &im.Banheiros,
		&im.Andar, &im.AnoConstrucao,
		&im.Categoria, &im.NomeCategoria, &im.Subtipo,
		&im.IDImovelWeb, &im.MostrarMapa, &im.DestaqueImovel,
		&im.TipoVivareal, &im.UsageTypeVivareal,
		&im.TipoCasaMineira, &im.SubtipoCasaMineira, &im.CategoriaCasaMineira,
		&im.SubtipoOLX, &im.MercadoLivreTipo, &im.CategoriaFacebook,
		&im.CEP, &im.Endereco, &im.Numero, &im.Bairro,
		&im.Cidade, &im.Estado, &im.Complemento, &im.Zona,
		&im.Coordenadas, &im.Video, &im.RefCaixa, &im.EstadoImovel,
		&im.FotoPadrao, &im.DescricaoPadrao,
		&im.ServicosDisponiveis, &im.ServicosNew, &im.DestaquePortal,
		&im.Fotos, &im.DataAtualizacao, &im.DataCadastro,
	)
	return im, err
}

func queryImoveis(ctx context.Context, db *sql.DB, q string, args ...any) ([]ImovelRow, error) {
	var rows []ImovelRow
	err := banco.Retentar(3, func() error {
		r, err := db.QueryContext(ctx, q, args...)
		if err != nil {
			return err
		}
		defer r.Close()
		rows = rows[:0]
		for r.Next() {
			im, err := scanImovelRow(r)
			if err != nil {
				return err
			}
			rows = append(rows, im)
		}
		return r.Err()
	})
	return rows, err
}

func ListarImoveisFeed(ctx context.Context, db *sql.DB, idMaster int, clausulaExtra, limit, orderBy, estadoXML string) ([]ImovelRow, error) {
	q := sqlImoveisBase
	if estadoXML != "" {
		q += fmt.Sprintf(" AND i.estado = '%s'", escapeSQL(estadoXML))
	}
	q += clausulaExtra + orderBy + limit
	return queryImoveis(ctx, db, q, idMaster)
}

func MontarClausulaFeed(f FeedConfig, idsMarcados []int) regras.ResultadoExportacao {
	return regras.MontarClausulaELimiteExportacao(regras.ParametrosExportacao{
		StatusConfig:         f.Status,
		LimiteXML:            f.LimiteXML,
		SendAll:              f.SendAll,
		SendAllParticular:    f.SendAllParticular,
		SendAllCaixa:         f.SendAllCaixa,
		IDsMarcados:          idsMarcados,
		FiltrosSoSendAllZero: f.IDPortal == 2 || f.IDPortal == 48,
	})
}

func escapeSQL(s string) string {
	return strings.ReplaceAll(s, "'", "''")
}
