package database

import (
	"bytes"
	"database/sql"
	"fmt"
	"log"
	"strings"

	"cpone/package/config"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

var Handle *sql.DB
var Handlex *sqlx.DB

// log
var HandleLog *sql.DB
var HandlexLog *sqlx.DB

func InitDB() {
	println(config.Data.Get("DBhost"))
	if config.Data.Get("DBhost") == "" {
		println("sqlite")

		handle, err := sql.Open("sqlite", config.Data.Get("DBname"))
		if err != nil {
			// log.Fatalf("🔥 failed to connect to the database: %s", err.Error())
			log.Panic(err)
		}
		Handle = handle

		// log handle
		handlelog, err := sql.Open("sqlite", config.Data.Get("DBnamelog"))
		if err != nil {
			// log.Fatalf("🔥 failed to connect to the database: %s", err.Error())
			log.Panic(err)
		}
		HandleLog = handlelog
		// log handle

		db, err := sqlx.Open("sqlite", config.Data.Get("DBname"))

		if err != nil {
			log.Fatal(err)
		}

		Handlex = db

		// log
		dblog, err := sqlx.Open("sqlite", config.Data.Get("DBnamelog"))

		if err != nil {
			log.Fatal(err)
		}

		HandlexLog = dblog
		// log
	} else {
		println("mysql")
		dsn := config.Data.Get("DBuser") + ":" + config.Data.Get("DBpass") + "@tcp(" + config.Data.Get("DBhost") + ":" + config.Data.Get("DBport") + ")/" + config.Data.Get("DBname")
		println(dsn)
		handle, err := sql.Open("mysql", dsn)

		if err != nil {
			log.Panic(err)
		}

		if err = handle.Ping(); err != nil {
			log.Panic(err)
		}
		Handle = handle

		// log
		dsnlog := config.Data.Get("DBuser") + ":" + config.Data.Get("DBpass") + "@tcp(" + config.Data.Get("DBhost") + ":" + config.Data.Get("DBport") + ")/" + config.Data.Get("DBnamelog")
		println(dsnlog)
		handlelog, err := sql.Open("mysql", dsnlog)

		if err != nil {
			log.Panic(err)
		}

		if err = handlelog.Ping(); err != nil {
			log.Panic(err)
		}
		HandleLog = handlelog
		// log

		// sqlx
		db, err := sqlx.Open("mysql", dsn)

		if err != nil {
			log.Fatal(err)
		}

		Handlex = db

		// log
		dblog, err := sqlx.Open("mysql", dsnlog)

		if err != nil {
			log.Fatal(err)
		}

		HandlexLog = dblog
		// log

	}
	log.Println("🚀 Connected Successfully to the Database")

}

func LogSQL(query string, args ...interface{}) {
	var buffer bytes.Buffer
	nArgs := len(args)
	// Break the string by question marks, iterate over its parts and for each
	// question mark - append an argument and format the argument according to
	// it's type, taking into consideration NULL values and quoting strings.
	for i, part := range strings.Split(query, "?") {
		buffer.WriteString(part)
		if i < nArgs {
			switch a := args[i].(type) {
			case int:
				buffer.WriteString(fmt.Sprintf("%d", a))
			case int64:
				buffer.WriteString(fmt.Sprintf("%d", a))
			case bool:
				buffer.WriteString(fmt.Sprintf("%t", a))
			case sql.NullBool:
				if a.Valid {
					buffer.WriteString(fmt.Sprintf("%t", a.Bool))
				} else {
					buffer.WriteString("NULL")
				}
			case sql.NullInt64:
				if a.Valid {
					buffer.WriteString(fmt.Sprintf("%d", a.Int64))
				} else {
					buffer.WriteString("NULL")
				}
			case sql.NullString:
				if a.Valid {
					buffer.WriteString(fmt.Sprintf("%q", a.String))
				} else {
					buffer.WriteString("NULL")
				}
			case sql.NullFloat64:
				if a.Valid {
					buffer.WriteString(fmt.Sprintf("%f", a.Float64))
				} else {
					buffer.WriteString("NULL")
				}
			default:
				buffer.WriteString(fmt.Sprintf("%q", a))
			}
		}
	}
	log.Print(buffer.String())
}
