package main

import (
	"fmt"
	"github.com/gorilla/handlers"
	"go_project/internal/configuration"
	"go_project/internal/connection"
	"go_project/internal/controllers"
	"go_project/internal/routes"
	"go_project/internal/schema"
	"go_project/pkg/behaivor"
	"go_project/pkg/file"
	"log"
	"net/http"
	"strconv"
)

func main() {
	configuration.Init()

	// Create database
	if configuration.GetForceCreateSchema() {
		sqlDBFileName := configuration.GetDatabaseLocation()
		file.MustCreate(sqlDBFileName)
		sqlHandler, err := connection.Open(sqlDBFileName)

		behaivor.Anxiety("Database connection error", err)

		schema.MustCreate(sqlHandler)

		log.Println("Database created")

		return
	} else if configuration.GetCreateSchema() {
		sqlDBFileName := configuration.GetDatabaseLocation()

		if file.MustIsNotExist(sqlDBFileName) {
			file.MustCreate(sqlDBFileName)
		} else {
			return
		}

		sqlHandler, err := connection.Open(sqlDBFileName)

		behaivor.Anxiety("Database connection error", err)

		schema.MustCreate(sqlHandler)

		log.Println("Database created")

		return
	}
	// Create database end

	// NOTE: Temp data for testing
	MustFillDatabase()

	serverRouter := routes.DefaultRouter()

	// Adding CORS policy
	corsHandler := handlers.CORS(
		handlers.AllowedOrigins([]string{"*"}),                                       // Allow all origins
		handlers.AllowedMethods([]string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}), // Allow common HTTP methods
		handlers.AllowedHeaders([]string{"Content-Type"}),                            // Allow specific headers
	)

	serverHost := configuration.GetServerHost()
	serverPort := strconv.FormatInt(int64(configuration.GetServerPort()), 10)
	serverAddr := serverHost + ":" + serverPort
	serverWriteTimeout := configuration.GetWriteTimeout()
	serverReadTimeout := configuration.GetReadTimeout()

	server := &http.Server{
		Handler:      corsHandler(serverRouter),
		Addr:         serverAddr,
		WriteTimeout: serverWriteTimeout,
		ReadTimeout:  serverReadTimeout,
	}

	log.Println("Preparations for listen and serve are complete. Starting server at " + serverAddr)

	log.Fatal(server.ListenAndServe())
}

// NOTE: Temp data for testing
func MustFillDatabase() {
	sqlHandler, err := connection.OpenDefault()

	behaivor.Anxiety("Database connection error", err)

	log.Println("Database filling operations are started")
	defer connection.MustClose(sqlHandler)

	// Fill database with Tables data
	for i := 1; i <= 5; i++ {
		createTableParams := controllers.CreateTableParams{
			Name:      i,
			MaxPeople: 2,
			Room:      "Room 1",
		}
		log.Printf("Current CreateTableParams: %v\n", createTableParams)
		_, err := controllers.CreateTable(sqlHandler, createTableParams)
		if err != nil {
			continue
		}
	}

	//Fill database with Bookings data
	for i := 0; i < 10; i++ {
		reservationTime := fmt.Sprintf("2025-01-01T%02d:00:00", 10+i)
		createBookingParams := controllers.CreateBookingParams{
			IdTables:    i%5 + 1,
			Reservation: reservationTime,
			TimeReserve: "01:00",
			WhoBooked:   "John Doe",
		}
		log.Printf("Current CreateBookingParams: %v\n", createBookingParams)
		_, err := controllers.CreateBooking(sqlHandler, createBookingParams)
		if err != nil {
			continue
		}
	}

	log.Println("Database filling operations are completed")
}
