package main

import (
	"fmt"
	"log"
	"net/http"

	"gitlab.com/pactual1/backend/config"
	"gitlab.com/pactual1/backend/models"
	"gitlab.com/pactual1/backend/routes"
	"gitlab.com/pactual1/backend/services/erp"
	"gitlab.com/pactual1/backend/services/messaging"
	"gitlab.com/pactual1/backend/shared"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"github.com/qor/admin"
)

var DB *gorm.DB

func main() {

	// LOAD APPLICATION CONFIGURATION
	err := config.Load()
	if err != nil {
		log.Fatal(err)
	}

	// Db Connect and Close
	if err := shared.Init(); err != nil {
		log.Fatalf("Failed to initialize shared resources: %v", err)
	}
	defer shared.CloseDb()

	// Initialize Admin interface
	Admin := admin.New(&admin.AdminConfig{DB: shared.GetDb()})
	Admin.RegisterViewPath("app/views/qor")
	fmt.Printf("Admin instance: %+v\n", Admin)

	// Allow Admin to manage User resource
	company := Admin.AddResource(&models.Company{})
	// Add User and Device resources
	Admin.AddResource(&models.User{})
	Admin.AddResource(&models.Device{})
	Admin.AddResource(&models.ProductTemplate{})
	company.Meta(&admin.Meta{Name: "Users", Config: &admin.SelectManyConfig{SelectMode: "select"}})
	company.Meta(&admin.Meta{Name: "Devices", Config: &admin.SelectManyConfig{SelectMode: "bottom_sheet"}})
	// // Initialize HTTP request multiplexe
	mux := http.NewServeMux()
	// // Mount admin interface to mux
	Admin.MountTo("/admin", mux)

	// // Setup Admin
	// Admin := admin.New(&admin.AdminConfig{DB: shared.GetDb()})
	// 	Admin.AddResource(&models.Student{})
	// school := Admin.AddResource(&models.School{})
	// school.Meta(&admin.Meta{Name: "Students", Config: &admin.SelectManyConfig{SelectMode: "select"}})
	// Admin.MountTo("/admin", mux)

	// school.SaveHandler = func(value interface{}, ctx *qor.Context) error {
	// 	schoolRecord := value.(*models.School)
	// 	log.Printf("Executed handler %v", schoolRecord)
	// 	log.Printf("Executed handler %v", schoolRecord.Students)

	// 	return ctx.GetDB().Save(schoolRecord).Error
	// }

	// Start the admin server in a separate goroutine
	go func() {
		port := config.AppConfig.Service.Port
		fmt.Println("Admin server listening on :" + port)
		http.ListenAndServe(":"+port, mux)
	}()

	// Initialize channels
	// messagingChannel := make(chan string)
	erpChannel := make(chan string)

	// Start services and pass the respective channels
	notificationCh := make(chan models.Notification, 100)
	// Start services and pass the respective channels
	emailCh := make(chan models.EmailNotification, 100)
	// Create a new messaging service
	messagingService := messaging.NewService(notificationCh, emailCh, shared.GetDb())
	// Run the messaging service
	go messagingService.MessagingService()
	go messagingService.SendEmailService()
	go erp.ERPService(erpChannel)

	// Sending messages via channels
	// messagingChannel <- "Send an email"
	erpChannel <- "Update ERP record"

	// Initialize Gin
	r := gin.Default()
	routes.InitRouter(r)
	// Start the Gin server on another port
	port := config.AppConfig.AdminService.Port
	fmt.Println("Application server listening on :" + port)
	r.Run(":" + port)

}
