package db

import (
	"database/sql"
	"fmt"
	"log/slog"
	"mocksnow/db/queries"

	//_ "github.com/tursodatabase/libsql-client-go/libsql"
	"github.com/jmoiron/sqlx"
	_ "modernc.org/sqlite"
)

type LocalDB struct {
	logger  *slog.Logger
	db      *sqlx.DB
	queries *queries.Queries
}

type DB struct {
	writeDB *sql.DB
	readDB  *sql.DB
}

var _ Database = (*LocalDB)(nil)

func (d *LocalDB) DB() *sqlx.DB {
	return d.db
}

func (d *LocalDB) Queries() *queries.Queries {
	return d.queries
}

func (d *LocalDB) Logger() *slog.Logger {
	return d.logger
}

func (d *LocalDB) Close() error {
	fmt.Println("Shutting database")
	d.logger.Debug("test")
	return d.db.Close()
}

func newLocalDB(logger *slog.Logger, path string) (*LocalDB, error) {

	// TODO - work out if https://kerkour.com/sqlite-for-servers is possible without using sqlx
	/*
		writeDB, err := sql.Open("sqlite3", "file:"+path)
		if err != nil {
			logger.Error("can't create writedb connection", "error", err)
			return nil, err
		}

		writeDB.SetMaxOpenConns(1)

		readDB, err := sql.Open("sqlite3", "file:"+path)
		if err != nil {
			logger.Error("can't create readdb connection", "error", err)
			return nil, err
		}
		readDB.SetMaxOpenConns(max(4, runtime.NumCPU()))
	*/

	//db, err := sql.Open("libsql", "file:"+path)
	db, err := sqlx.Open("sqlite", "file:"+path)
	if err != nil {
		logger.Error("can't open database connection", "error", err)
		return nil, err
	}

	db.SetMaxOpenConns(1)

	// Execute PRAGMA commands
	pragmas := []string{
		"PRAGMA journal_mode = WAL;",
		"PRAGMA busy_timeout = 5000;",
		"PRAGMA synchronous = NORMAL;",
		"PRAGMA cache_size = 1000000000;",
		"PRAGMA foreign_keys = true;",
		"PRAGMA temp_store = MEMORY;",
	}

	for _, pragma := range pragmas {
		logger.Debug("Setting pragma", "pragma", pragma)
		_, err := db.Exec(pragma)
		if err != nil {
			logger.Error("failed to execute pragma statement", "stmt", pragma, "error", err)
			return nil, err
		}
	}

	return &LocalDB{logger: logger, db: db, queries: queries.New(db)}, nil
}
