package main

import (
	"backend/dbhelpers"
	"context"
	"fmt"
	"log/slog"
	"os"

	"github.com/georgysavva/scany/v2/pgxscan"
	pgxuuid "github.com/jackc/pgx-gofrs-uuid"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgxpool"
)

type DbHandler struct {
	Dbpool *pgxpool.Pool
	Ctx    context.Context
}

func NewDbHandler() *DbHandler {
	fmt.Println("Connecting to db")
	ctx := context.Background()

	host := os.Getenv("PGHOST")
	dbname := os.Getenv("POSTGRES_DB")
	dbport := os.Getenv("PGPORT")
	pguser := os.Getenv("POSTGRES_USER")
	pgpassword := os.Getenv("POSTGRES_PASSWORD")

	connStr := fmt.Sprintf("postgresql://%s:%s@%s:%s/%s?sslmode=disable", pguser, pgpassword, host, dbport, dbname)
	fmt.Printf("Connecting to db with connection string: %s", connStr)
	config, err := pgxpool.ParseConfig(connStr)
	if err != nil {
		panic(err)
	}
	config.ConnConfig.Tracer = dbhelpers.NewMultiQueryTracer(dbhelpers.NewLoggingQueryTracer(slog.Default()))

	config.AfterConnect = func(ctx context.Context, conn *pgx.Conn) error {
		pgxuuid.Register(conn.TypeMap())
		return nil
	}
	dbpool, err := pgxpool.NewWithConfig(ctx, config)
	if err != nil {
		panic(err)
	}
	fmt.Println("Connected to db")

	return &DbHandler{Dbpool: dbpool, Ctx: ctx}
}

func (h *DbHandler) GetActiveAnnunci() []string {
	var annunci []string
	pgxscan.Select(h.Ctx, h.Dbpool, &annunci, "SELECT codice FROM public.annunci WHERE web = true and stato = 'Attivo' ")
	/*for i, annuncio := range annunci {
		//if first letter is V then set annuncio as  the last 4 digits
		if string(annuncio[0]) != "V" {
			annunci[i] = annuncio[:4]
		}
	}*/
	return annunci
}

func (h *DbHandler) GetAllAnnunci() []AnnunciDB {
	//var annuncio AnnunciDB
	var annunci []AnnunciDB

	pgxscan.Select(h.Ctx, h.Dbpool, &annunci, "SELECT * FROM public.annunci")
	return annunci

}

func (h *DbHandler) InsertAnnunciInDB(annunci AnnunciParsed) {

	//SET ALL WEB TO FALSE
	_, err := h.Dbpool.Exec(h.Ctx, "UPDATE public.annunci SET web = false")
	if err != nil {
		panic(err)

	}
	//GET ALL CODICI
	var codici []string
	err = pgxscan.Select(h.Ctx, h.Dbpool, &codici, "SELECT DISTINCT codice FROM public.annunci")
	if err != nil {
		panic(err)
	}
	batch := &pgx.Batch{}
	for _, annuncio := range annunci.Annuncio {

		if contains(codici, annuncio.Codice) {
			batch.Queue(`
			 UPDATE public.annunci
			SET locatore = $1,
				numero = $2,
				idlocatore = $3,
				email = $4,
				creato_il = $5,
				modificato_il = $6,
				indirizzo = $7,
				civico = $8,
				comune = $9,
				cap = $10,
				provincia = $11,
				regione = $12,
				lat = $13,
				lon = $14,
				indirizzo_secondario = $15,
				civico_secondario = $16,
				lat_secondario = $17,
				lon_secondario = $18,
				tipo = $19,
				categorie = $20,
				prezzo = $21,
				anno = $22,
				consegna = $23,
				classe = $24,
				mq = $25,
				piano = $26,
				piano_palazzo = $27,
				unita_condominio = $28,
				numero_vani = $29,
				numero_camere = $30,
				numero_bagni = $31,
				numero_balconi = $32,
				numero_terrazzi = $33,
				numero_box = $34,
				numero_postiauto = $35,
				caratteristiche = $36,
				accessori = $37,
				titolo_it = $38,
				desc_it = $39,
				titolo_en = $40,
				desc_en = $41,
				stato = $42,
				web = $43,
				homepage = $44,
				url_immagini = $45,
				url_video = $46
			WHERE codice = $47
			`, annuncio.Locatore, annuncio.Numero, annuncio.Idlocatore,
				annuncio.Email, annuncio.Creato_il, annuncio.Modificato_il,
				annuncio.Indirizzo, annuncio.Civico, annuncio.Comune, annuncio.Cap,
				annuncio.Provincia, annuncio.Regione, annuncio.Lat, annuncio.Lon,
				annuncio.Indirizzo_secondario, annuncio.Civico_secondario, annuncio.Lat_secondario,
				annuncio.Lon_secondario, annuncio.Tipo, annuncio.Categorie, annuncio.Prezzo, annuncio.Anno,
				annuncio.Consegna, annuncio.Classe, annuncio.Mq, annuncio.Piano, annuncio.Piano_palazzo,
				annuncio.Unita_condominio, annuncio.Numero_vani, annuncio.Numero_camere, annuncio.Numero_bagni,
				annuncio.Numero_balconi, annuncio.Numero_terrazzi, annuncio.Numero_box, annuncio.Numero_postiauto,
				annuncio.Caratteristiche, annuncio.Accessori, annuncio.Titolo_it, annuncio.Desc_it, annuncio.Titolo_en,
				annuncio.Desc_en, annuncio.Stato, annuncio.Web, annuncio.Homepage, annuncio.Url_foto,
				annuncio.Url_video, annuncio.Codice)

		} else {
			batch.Queue(`
			 INSERT INTO public.annunci(
				locatore,
				numero,
				idlocatore,
				email,
				creato_il,
				modificato_il,
				indirizzo,
				civico,
				comune,
				cap,
				provincia,
				regione,
				lat,
				lon,
				indirizzo_secondario,
				civico_secondario,
				lat_secondario,
				lon_secondario,
				tipo,
				categorie,
				prezzo,
				anno,
				consegna,
				classe,
				mq,
				piano,
				piano_palazzo,
				unita_condominio,
				numero_vani,
				numero_camere,
				numero_bagni,
				numero_balconi,
				numero_terrazzi,
				numero_box,
				numero_postiauto,
				caratteristiche,
				accessori,
				titolo_it,
				desc_it,
				titolo_en,
				desc_en,
				stato,
				web,
				homepage,
				url_immagini,
				url_video,
				codice
			)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40, $41, $42, $43, $44, $45, $46, $47)
			`, annuncio.Locatore, annuncio.Numero, annuncio.Idlocatore,
				annuncio.Email, annuncio.Creato_il, annuncio.Modificato_il,
				annuncio.Indirizzo, annuncio.Civico, annuncio.Comune, annuncio.Cap,
				annuncio.Provincia, annuncio.Regione, annuncio.Lat, annuncio.Lon,
				annuncio.Indirizzo_secondario, annuncio.Civico_secondario, annuncio.Lat_secondario,
				annuncio.Lon_secondario, annuncio.Tipo, annuncio.Categorie, annuncio.Prezzo, annuncio.Anno,
				annuncio.Consegna, annuncio.Classe, annuncio.Mq, annuncio.Piano, annuncio.Piano_palazzo,
				annuncio.Unita_condominio, annuncio.Numero_vani, annuncio.Numero_camere, annuncio.Numero_bagni,
				annuncio.Numero_balconi, annuncio.Numero_terrazzi, annuncio.Numero_box, annuncio.Numero_postiauto,
				annuncio.Caratteristiche, annuncio.Accessori, annuncio.Titolo_it, annuncio.Desc_it, annuncio.Titolo_en,
				annuncio.Desc_en, annuncio.Stato, annuncio.Web, annuncio.Homepage, annuncio.Url_foto,
				annuncio.Url_video, annuncio.Codice)

		}
	}
	results := h.Dbpool.SendBatch(h.Ctx, batch).Close()
	fmt.Println(results)

}

func contains(s []string, str string) bool {
	for _, v := range s {
		if v == str {
			return true
		}
	}
	return false
}

func (h *DbHandler) ClearRecords() {

	//SET ALL WEB TO FALSE
	_, err := h.Dbpool.Exec(h.Ctx, "DELETE FROM public.annunci")
	if err != nil {
		panic(err)

	}
}

func (h *DbHandler) SetFromBkp(annunci AnnunciParsed) {
	h.ClearRecords()

	batch := &pgx.Batch{}
	for _, annuncio := range annunci.Annuncio {
		batch.Queue(`
			 INSERT INTO public.annunci(
				locatore,
				numero,
				idlocatore,
				email,
				creato_il,
				modificato_il,
				indirizzo,
				civico,
				comune,
				cap,
				provincia,
				regione,
				lat,
				lon,
				indirizzo_secondario,
				civico_secondario,
				lat_secondario,
				lon_secondario,
				tipo,
				categorie,
				prezzo,
				anno,
				consegna,
				classe,
				mq,
				piano,
				piano_palazzo,
				unita_condominio,
				numero_vani,
				numero_camere,
				numero_bagni,
				numero_balconi,
				numero_terrazzi,
				numero_box,
				numero_postiauto,
				caratteristiche,
				accessori,
				titolo_it,
				desc_it,
				titolo_en,
				desc_en,
				stato,
				web,
				homepage,
				url_immagini,
				url_video,
				codice
			)
			VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39, $40, $41, $42, $43, $44, $45, $46, $47)
			`, annuncio.Locatore, annuncio.Numero, annuncio.Idlocatore,
			annuncio.Email, annuncio.Creato_il, annuncio.Modificato_il,
			annuncio.Indirizzo, annuncio.Civico, annuncio.Comune, annuncio.Cap,
			annuncio.Provincia, annuncio.Regione, annuncio.Lat, annuncio.Lon,
			annuncio.Indirizzo_secondario, annuncio.Civico_secondario, annuncio.Lat_secondario,
			annuncio.Lon_secondario, annuncio.Tipo, annuncio.Categorie, annuncio.Prezzo, annuncio.Anno,
			annuncio.Consegna, annuncio.Classe, annuncio.Mq, annuncio.Piano, annuncio.Piano_palazzo,
			annuncio.Unita_condominio, annuncio.Numero_vani, annuncio.Numero_camere, annuncio.Numero_bagni,
			annuncio.Numero_balconi, annuncio.Numero_terrazzi, annuncio.Numero_box, annuncio.Numero_postiauto,
			annuncio.Caratteristiche, annuncio.Accessori, annuncio.Titolo_it, annuncio.Desc_it, annuncio.Titolo_en,
			annuncio.Desc_en, annuncio.Stato, annuncio.Web, annuncio.Homepage, annuncio.Url_foto,
			annuncio.Url_video, annuncio.Codice)

	}
	results := h.Dbpool.SendBatch(h.Ctx, batch).Close()
	fmt.Println(results)

}
