package main



import (

	"log"

	"net/http"

	"os"

	"time"



	"github.com/go-chi/chi/v5"

	"github.com/go-chi/chi/v5/middleware"

	"github.com/go-chi/httprate"



	"leadb2b.org/internal/api"

	"leadb2b.org/internal/auth"

	"leadb2b.org/internal/config"

	"leadb2b.org/internal/handlers"

	apiv1 "leadb2b.org/internal/handlers/apiv1"

	mw "leadb2b.org/internal/middleware"

	"leadb2b.org/internal/render"

	siteweb "leadb2b.org/web"

)



func main() {

	cfg, err := config.Load()

	if err != nil {

		log.Fatal(err)

	}



	engine, err := render.NewEngine(cfg.SiteURL, siteweb.Templates)

	if err != nil {

		log.Fatal(err)

	}



	client := api.NewClient(cfg.GlobalAPIBase, cfg.GlobalAPIKey)

	leads := api.NewLeadsService(client)

	authAPI := api.NewAuthService(client)

	productAPI := api.NewProductService(client)

	h := handlers.New(leads, engine, cfg.SiteURL)



	staticH, err := handlers.NewStaticHandler(cfg.SiteURL)

	if err != nil {

		log.Fatal(err)

	}



	authSvc := auth.NewService(authAPI)

	authH := handlers.NewAuthHandler(authSvc)

	appH := handlers.NewAppHandler(leads, productAPI, authAPI, engine, cfg.SiteURL)

	apiH := apiv1.New(productAPI, authAPI)



	r := chi.NewRouter()

	r.Use(middleware.RequestID)

	r.Use(middleware.RealIP)

	r.Use(middleware.Recoverer)

	r.Use(middleware.Timeout(130 * time.Second))

	r.Use(middleware.Compress(5))

	r.Use(mw.SecurityHeaders)



	imagesDir := "site/images"

	if _, err := os.Stat(imagesDir); err != nil {

		imagesDir = "web/static/images"

	}

	r.Get("/static/images/logo-light-3.png", legacyLogoRedirect("logo-white.png"))

	r.Get("/static/images/logo-light.png", legacyLogoRedirect("logo-white.png"))

	r.Get("/static/images/logo-light-2.png", legacyLogoRedirect("logo-white.png"))

	r.Handle("/static/images/*", mw.StaticCache(http.StripPrefix("/static/images/", http.FileServer(http.Dir(imagesDir)))))



	staticRoot := http.Dir("web/static")

	r.Handle("/static/*", mw.StaticCache(http.StripPrefix("/static/", http.FileServer(staticRoot))))



	r.Group(func(r chi.Router) {

		r.Use(httprate.LimitByIP(cfg.RateLimit, time.Minute))

		r.Use(mw.NoStore)

		r.Get("/", h.Home)

		r.Get("/busca", h.Busca)

		r.Get("/empresa/{slug}", h.Empresa)

		r.Get("/empresa-premium/{slug}", h.EmpresaPremiumRedirect)

	})



	r.Get("/login", authH.ShowLogin)

	r.Post("/login", authH.PostLogin)

	r.Get("/cadastro", authH.ShowRegister)

	r.Post("/cadastro", authH.PostRegister)

	r.Post("/logout", authH.PostLogout)

	r.Get("/recuperar-senha", authH.ShowForgotPassword)

	r.Post("/recuperar-senha", authH.PostForgotPassword)

	r.Get("/redefinir-senha", authH.ShowResetPassword)

	r.Post("/redefinir-senha", authH.PostResetPassword)



	r.Route("/app", func(r chi.Router) {

		r.Use(mw.RequireAuth(authSvc))

		r.Use(mw.RequireActivePlan)

		r.Get("/", appH.Dashboard)

		r.Get("/busca", appH.Busca)

		r.Get("/busca/results", appH.BuscaResults)

		r.Post("/busca/export", appH.PostSearchExport)

		r.Post("/busca/bulk/kanban", appH.PostBulkKanban)

		r.Post("/busca/bulk/export", appH.PostBulkExport)

		r.Get("/kanban", appH.Kanban)

		r.Post("/kanban/move", appH.PostMoveStage)

		r.Get("/tags", appH.Tags)

		r.Post("/tags", appH.Tags)

		r.Post("/leads/work", appH.PostWorkLead)

		r.Get("/leads/{id}", appH.LeadDetail)

		r.Post("/leads/{id}", appH.LeadDetail)

		r.Get("/mensagens", appH.Mensagens)

		r.Post("/mensagens", appH.Mensagens)

		r.Get("/plano", appH.Plano)

		r.Get("/exportacoes", appH.Exportacoes)

		r.Post("/exportacoes", appH.Exportacoes)

		r.Get("/perfil", appH.Perfil)

		r.Post("/perfil", appH.Perfil)

	})



	r.Route("/admin", func(r chi.Router) {

		r.Use(mw.RequireAuth(authSvc))

		r.Use(mw.RequireAdmin)

		r.Get("/", appH.AdminDashboard)

		r.Post("/users/{id}", appH.AdminPatchUser)

	})



	r.Route("/api/v1", func(r chi.Router) {

		r.Use(mw.RequireAuth(authSvc))

		r.Get("/auth/me", apiH.Me)

		r.Group(func(r chi.Router) {

			r.Use(mw.RequireActivePlan)

			r.Get("/product/search/companies", apiH.SearchCompanies)

			r.Post("/product/leads/work", apiH.WorkLead)

			r.Get("/product/leads", apiH.ListLeads)

			r.Get("/product/leads/{id}", apiH.GetLead)

			r.Get("/product/leads/{id}/history", apiH.GetLeadHistory)

			r.Patch("/product/leads/{id}", apiH.PatchLead)

			r.Delete("/product/leads/{id}", apiH.DeleteLead)

			r.Patch("/product/leads/{id}/stage", apiH.PatchStage)

			r.Get("/product/tags", apiH.ListTags)

			r.Post("/product/tags", apiH.CreateTag)

			r.Patch("/product/tags/{id}", apiH.PatchTag)

			r.Delete("/product/tags/{id}", apiH.DeleteTag)

			r.Get("/product/kanban", apiH.Kanban)

			r.Get("/product/kanban/stats", apiH.KanbanStats)

			r.Get("/product/stats/overview", apiH.StatsOverview)

			r.Post("/product/leads/{id}/contact/whatsapp", apiH.ContactWhatsApp)

			r.Post("/product/leads/{id}/contact/email", apiH.ContactEmail)

			r.Get("/product/templates", apiH.ListTemplates)

			r.Post("/product/templates", apiH.CreateTemplate)

			r.Patch("/product/templates/{id}", apiH.UpdateTemplate)

			r.Delete("/product/templates/{id}", apiH.DeleteTemplate)

			r.Post("/product/exports", apiH.CreateExport)

			r.Get("/product/exports", apiH.ListExports)

			r.Get("/product/exports/{id}/download", apiH.DownloadExport)

		})

		r.Route("/product/admin", func(r chi.Router) {

			r.Use(mw.RequireAdmin)

			r.Get("/users", apiH.AdminUsers)

			r.Patch("/users/{id}/status", apiH.AdminPatchUserStatus)

			r.Patch("/users/{id}/subscription", apiH.AdminPatchSubscription)

			r.Get("/plans", apiH.AdminPlans)

			r.Get("/metrics", apiH.AdminMetrics)

		})

	})



	r.Get("/health", h.Health)

	r.Get("/robots.txt", h.Robots)

	r.Get("/sitemap.xml", h.Sitemap)

	r.Get("/llms.txt", h.LLMsTxt)

	r.Handle("/sitemaps/*", handlers.ServeSitemapFiles())



	r.Route("/api/filtros", func(r chi.Router) {

		r.Use(httprate.LimitByIP(cfg.RateLimit*2, time.Minute))

		r.Get("/ufs", h.APIFiltrosUFs)

		r.Get("/municipios", h.APIFiltrosMunicipios)

		r.Get("/cnaes", h.APIFiltrosCNAEs)

	})

	r.Get("/busca-avancada", func(w http.ResponseWriter, r *http.Request) {

		http.Redirect(w, r, "/busca", http.StatusMovedPermanently)

	})



	legacy := []string{"index", "resultados", "empresa", "empresa-premium", "busca-avancada"}

	for _, name := range legacy {

		r.Get("/"+name+".html", h.RedirectLegacy)

	}



	registerStatic(r, staticH, "pricing", "/pricing")

	registerStatic(r, staticH, "faq", "/faq")

	registerStatic(r, staticH, "contact", "/contact")

	registerStatic(r, staticH, "termos", "/termos")

	registerStatic(r, staticH, "privacidade", "/privacidade")

	registerStatic(r, staticH, "blog", "/blog")

	registerStatic(r, staticH, "blog-como-encontrar-leads-b2b", "/blog/como-encontrar-leads-b2b")

	registerStatic(r, staticH, "blog-segmentacao-por-cnae", "/blog/segmentacao-por-cnae")

	registerStatic(r, staticH, "blog-exportar-lista-empresas-crm", "/blog/exportar-lista-empresas-crm")

	registerStatic(r, staticH, "blog-estrategias-prospeccao-ativa", "/blog/estrategias-prospeccao-ativa")

	registerStatic(r, staticH, "sobre-dados", "/sobre-dados")



	addr := ":" + cfg.Port

	log.Printf("LeadB2B listening on %s (images: %s, product: Global API)", addr, imagesDir)

	if err := http.ListenAndServe(addr, r); err != nil {

		log.Fatal(err)

	}

}



func registerStatic(r chi.Router, h *handlers.StaticHandler, name, path string) {

	r.Get(path, h.Serve(name))

}



func legacyLogoRedirect(target string) http.HandlerFunc {

	return func(w http.ResponseWriter, r *http.Request) {

		http.Redirect(w, r, "/static/images/"+target, http.StatusMovedPermanently)

	}

}


