package main

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"

	"fred-api/config"
	"fred-api/handlers"

	"github.com/gin-gonic/gin"
	"github.com/joho/godotenv"
)

func main() {
	if err := godotenv.Load(); err != nil {
		log.Println("No .env file found, using default config")
	}

	cfg := config.Load()

	fredHandler := handlers.NewFREDHandler(cfg)

	gin.SetMode(gin.ReleaseMode)
	router := gin.Default()

	router.Use(func(c *gin.Context) {
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}
		c.Next()
	})

	router.GET("/health", fredHandler.HealthCheck)

	api := router.Group("/api/v1")
	{
		api.GET("/category", fredHandler.GetCategory)
		api.GET("/category/children", fredHandler.GetCategoryChildren)
		api.GET("/category/related", fredHandler.GetCategoryRelated)
		api.GET("/category/series", fredHandler.GetCategorySeries)
		api.GET("/category/tags", fredHandler.GetCategoryTags)
		api.GET("/category/related_tags", fredHandler.GetCategoryRelatedTags)

		api.GET("/series", fredHandler.GetSeries)
		api.GET("/series/categories", fredHandler.GetSeriesCategories)
		api.GET("/series/observations", fredHandler.GetObservations)
		api.GET("/series/release", fredHandler.GetSeriesRelease)
		api.GET("/series/search", fredHandler.SearchSeries)
		api.GET("/series/search/tags", fredHandler.SearchSeriesTags)
		api.GET("/series/search/related_tags", fredHandler.SearchSeriesRelatedTags)
		api.GET("/series/tags", fredHandler.GetSeriesTags)
		api.GET("/series/updates", fredHandler.GetSeriesUpdates)
		api.GET("/series/vintagedates", fredHandler.GetSeriesVintageDates)

		api.GET("/releases", fredHandler.GetReleases)
		api.GET("/releases/dates", fredHandler.GetReleaseDates)
		api.GET("/release", fredHandler.GetRelease)
		api.GET("/release/dates", fredHandler.GetReleaseDates2)
		api.GET("/release/series", fredHandler.GetReleaseSeries)
		api.GET("/release/sources", fredHandler.GetReleaseSources)
		api.GET("/release/tags", fredHandler.GetReleaseTags)
		api.GET("/release/related_tags", fredHandler.GetReleaseRelatedTags)
		api.GET("/release/tables", fredHandler.GetReleaseTables)

		api.GET("/sources", fredHandler.GetSources)
		api.GET("/source", fredHandler.GetSource)
		api.GET("/source/releases", fredHandler.GetSourceReleases)

		api.GET("/tags", fredHandler.GetTags)
		api.GET("/related_tags", fredHandler.GetRelatedTags)
		api.GET("/tags/series", fredHandler.GetTagsSeries)
	}

	router.Static("/static", "./web/static")
	router.LoadHTMLGlob("web/templates/*")

	router.GET("/", func(c *gin.Context) {
		c.HTML(200, "index.html", gin.H{
			"title": "FRED Economic Data Dashboard",
		})
	})

	go func() {
		fmt.Printf("FRED API Server starting on :%s\n", cfg.ServerPort)
		fmt.Printf("FRED API Base URL: %s\n", cfg.FREDBaseURL)
		fmt.Println("\nAvailable endpoints:")
		fmt.Println("  GET /health              - Health check")
		fmt.Println("  GET /                    - Web Dashboard")
		fmt.Println("  GET /api/v1/series                    - Get series info")
		fmt.Println("  GET /api/v1/series/observations       - Get observations")
		fmt.Println("  GET /api/v1/series/search             - Search series")
		fmt.Println("  GET /api/v1/releases                  - Get all releases")
		fmt.Println("  GET /api/v1/releases/dates            - Get release dates")
		fmt.Println("  GET /api/v1/release/series            - Get series in release")
		fmt.Println("  GET /api/v1/category                  - Get category")
		fmt.Println("  GET /api/v1/sources                   - Get sources")
		fmt.Println("  GET /api/v1/tags                      - Get tags")
		fmt.Println("")
		fmt.Println("Examples:")
		fmt.Println("  curl 'http://localhost:" + cfg.ServerPort + "/api/v1/series?series_id=GNPCA'")
		fmt.Println("  curl 'http://localhost:" + cfg.ServerPort + "/api/v1/series/observations?series_id=GNPCA&limit=10'")
		fmt.Println("  curl 'http://localhost:" + cfg.ServerPort + "/api/v1/series/search?search_text=GDP'")
		fmt.Println("")

		if err := router.Run(":" + cfg.ServerPort); err != nil {
			log.Fatalf("Failed to start server: %v", err)
		}
	}()

	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	fmt.Println("\nShutting down server...")
}
