package main

import (
	"expvar"
	"net/http"

	"party.at/party/cmd/party/common"
	"party.at/party/cmd/party/api"
	"party.at/party/cmd/party/web"
)

func routes(app *common.Application) http.Handler {
    // ── API router ──────────────────────────────────────────────────────────
    api := api.Api{
		App: app,
	}
    apiMux := http.NewServeMux()

    apiMux.HandleFunc("GET /v1/healthcheck", api.Healthcheck)

    apiMux.HandleFunc("GET /v1/issues",                    api.RequirePermission("issues:read",  api.ListIssues))
    apiMux.HandleFunc("POST /v1/issues",                   api.RequirePermission("issues:write", api.CreateIssue))
    apiMux.HandleFunc("GET /v1/issues/{id}",               api.RequirePermission("issues:read",  api.ReadIssue))
    apiMux.HandleFunc("PATCH /v1/issues/{id}",             api.RequirePermission("issues:write", api.UpdateIssue))
    apiMux.HandleFunc("DELETE /v1/issues/{id}",            api.RequirePermission("issues:write", api.DeleteIssue))
    apiMux.HandleFunc("GET /v1/issues/{id}/pubkey",        api.RequirePermission("issues:read",  api.ReadIssuePubKey))
    apiMux.HandleFunc("POST /v1/issues/{id}/blind-sign",   api.RequirePermission("issues:read",  api.BlindSignIssueVote))
    apiMux.HandleFunc("POST /v1/votes",                    api.Vote)
    apiMux.HandleFunc("POST /v1/users",                    api.CreateUser)
    apiMux.HandleFunc("GET /v1/users",                     api.RequirePermission("users:read", api.ListUsers))
    apiMux.HandleFunc("GET /v1/users/{id}",                api.RequireAuthenticatedUser(api.ReadUser))
    apiMux.HandleFunc("DELETE /v1/users/{id}",             api.RequirePermission("users:write", api.DeleteUser))
    apiMux.HandleFunc("PUT /v1/users/activated",           api.ActivateUser)
    apiMux.HandleFunc("POST /v1/tokens/authentication",    api.CreateAuthenticationToken)
    apiMux.HandleFunc("DELETE /v1/tokens/authentication",  api.RequireAuthenticatedUser(api.DeleteAuthenticationToken))
    apiMux.HandleFunc("POST /v1/device-tokens",            api.RequireAuthenticatedUser(api.RegisterDeviceToken))
    apiMux.HandleFunc("DELETE /v1/device-tokens",          api.RequireAuthenticatedUser(api.DeleteDeviceToken))
    apiMux.HandleFunc("GET /v1/mps",                       api.ListMPs)
    apiMux.HandleFunc("GET /v1/parlament/votes",           api.ListParlVotes)
    apiMux.HandleFunc("GET /v1/parlament/votes/{path...}", api.GetParlVoteDetail)
    apiMux.Handle("GET /debug/vars",                       expvar.Handler())

    apiChain := app.Metrics(api.RecoverPanic(app.EnableCORS(api.RateLimit(api.Authenticate(apiMux)))))

    // ── Web router ──────────────────────────────────────────────────────────
    web := web.Web{
		App: app,
	}
    webMux := http.NewServeMux()

    webMux.HandleFunc("GET /",                        web.Home)
    webMux.HandleFunc("GET /register",                web.Register)
    webMux.HandleFunc("POST /register",               web.RegisterUserPage)
    webMux.HandleFunc("GET /issues",                  web.RequirePermission("issues:read", web.IssuesPage))
    webMux.HandleFunc("POST /issues",                 web.RequirePermission("issues:write", web.CreateIssueAction))
    webMux.HandleFunc("GET /issues/{id}",             web.RequirePermission("issues:read", web.IssuePage))
    webMux.HandleFunc("PATCH /issues/{id}",           web.RequirePermission("issues:write", web.UpdateIssueAction))
    webMux.HandleFunc("DELETE /issues/{id}",          web.RequirePermission("issues:write", web.DeleteIssueAction))
    webMux.HandleFunc("GET /issues/{id}/pubkey",      web.RequirePermission("issues:read", web.GetIssuePubKey))
    webMux.HandleFunc("POST /issues/{id}/blind-sign", web.RequirePermission("issues:read", web.BlindSignIssueVote))
    webMux.HandleFunc("POST /votes",                  web.VoteAction)

    webMux.HandleFunc("GET /users",                   web.RequirePermission("users:read", web.UsersPage))
    webMux.HandleFunc("GET /users/me",                web.RequireAuthenticatedUser(web.ProfilePage))
    webMux.HandleFunc("GET /users/activated",         web.ActivatePage)
    webMux.HandleFunc("POST /users/activated",        web.ActivateUserAction)
    webMux.HandleFunc("DELETE /users/{id}",           web.RequirePermission("users:write", web.DeleteUserAction))

    webMux.HandleFunc("GET /mps",                     web.MembersOfParliamentPage)
    webMux.HandleFunc("GET /parlament",               web.ParlVotesPage)
    webMux.HandleFunc("GET /parlament/{path...}",     web.ParlamentDispatch)

    webMux.HandleFunc("POST /login",                  web.Login)
    webMux.HandleFunc("POST /dev-login",              web.DevLogin)
    webMux.HandleFunc("POST /logout",                 web.Logout)
    webMux.HandleFunc("GET /ws",                      ws)
    
    fileServer := http.FileServer(http.Dir("web/static"))
    webMux.Handle("GET /static/", http.StripPrefix("/static/", fileServer))

    webChain := app.Metrics(web.WebRecoverPanic(web.WebRateLimit(web.AuthenticateCookie(webMux))))

    // ── Top-level mux ────────────────────────────────────────────────────────
    mainMux := http.NewServeMux()
    mainMux.Handle("/v1/", apiChain)
    mainMux.Handle("/debug/", apiChain)
    mainMux.Handle("/", webChain)

    return mainMux
}
