package httpapi

import (
	"log"
	"net/http"

	"git.az-it.net/az/morz-infoboard/server/backend/internal/httpapi/manage"
	"git.az-it.net/az/morz-infoboard/server/backend/internal/store"
)

// RouterDeps holds all dependencies needed to build the HTTP router.
type RouterDeps struct {
	StatusStore   playerStatusStore
	TenantStore   *store.TenantStore
	ScreenStore   *store.ScreenStore
	MediaStore    *store.MediaStore
	PlaylistStore *store.PlaylistStore
	UploadDir     string
	Logger        *log.Logger
}

func NewRouter(deps RouterDeps) http.Handler {
	mux := http.NewServeMux()

	// ── Health ───────────────────────────────────────────────────────────
	mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) {
		writeJSON(w, http.StatusOK, map[string]string{
			"status":  "ok",
			"service": "morz-infoboard-backend",
		})
	})

	// ── Status / diagnostic UI ───────────────────────────────────────────
	mux.HandleFunc("GET /status", handleStatusPage(deps.StatusStore))
	mux.HandleFunc("GET /status/{screenId}", handleScreenDetailPage(deps.StatusStore))

	// ── API meta ─────────────────────────────────────────────────────────
	mux.HandleFunc("GET /api/v1", func(w http.ResponseWriter, _ *http.Request) {
		writeJSON(w, http.StatusOK, map[string]any{
			"name":    "morz-infoboard-backend",
			"version": "dev",
			"tools": []string{
				"message-wall-resolve",
				"screen-status-list",
				"screen-status-detail",
				"player-status-ingest",
				"screen-status-delete",
			},
		})
	})
	mux.HandleFunc("GET /api/v1/meta", handleMeta)

	// ── Player status (existing) ──────────────────────────────────────────
	mux.HandleFunc("POST /api/v1/player/status", handlePlayerStatus(deps.StatusStore))
	mux.HandleFunc("GET /api/v1/screens/status", handleListLatestPlayerStatuses(deps.StatusStore))
	mux.HandleFunc("GET /api/v1/screens/{screenId}/status", handleGetLatestPlayerStatus(deps.StatusStore))
	mux.HandleFunc("DELETE /api/v1/screens/{screenId}/status", handleDeletePlayerStatus(deps.StatusStore))

	// ── Message wall ──────────────────────────────────────────────────────
	mux.HandleFunc("POST /api/v1/tools/message-wall/resolve", handleResolveMessageWall)

	// ── Playlist management — only register if stores are wired up ────────
	if deps.TenantStore != nil {
		registerManageRoutes(mux, deps)
	}

	return mux
}

func registerManageRoutes(mux *http.ServeMux, d RouterDeps) {
	uploadDir := d.UploadDir
	if uploadDir == "" {
		uploadDir = "/tmp/morz-uploads"
	}

	// Serve uploaded files.
	mux.Handle("GET /uploads/", http.StripPrefix("/uploads/", http.FileServer(http.Dir(uploadDir))))

	// ── Admin UI ──────────────────────────────────────────────────────────
	mux.HandleFunc("GET /admin", manage.HandleAdminUI(d.TenantStore, d.ScreenStore))
	mux.HandleFunc("POST /admin/screens", manage.HandleCreateScreenUI(d.TenantStore, d.ScreenStore))
	mux.HandleFunc("POST /admin/screens/{screenId}/delete", manage.HandleDeleteScreenUI(d.ScreenStore))

	// ── Playlist management UI ────────────────────────────────────────────
	mux.HandleFunc("GET /manage/{screenSlug}",
		manage.HandleManageUI(d.TenantStore, d.ScreenStore, d.MediaStore, d.PlaylistStore))
	mux.HandleFunc("POST /manage/{screenSlug}/upload",
		manage.HandleUploadMediaUI(d.MediaStore, d.ScreenStore, uploadDir))
	mux.HandleFunc("POST /manage/{screenSlug}/items",
		manage.HandleAddItemUI(d.PlaylistStore, d.MediaStore, d.ScreenStore))
	mux.HandleFunc("POST /manage/{screenSlug}/items/{itemId}",
		manage.HandleUpdateItemUI(d.PlaylistStore))
	mux.HandleFunc("POST /manage/{screenSlug}/items/{itemId}/delete",
		manage.HandleDeleteItemUI(d.PlaylistStore))
	mux.HandleFunc("POST /manage/{screenSlug}/reorder",
		manage.HandleReorderUI(d.PlaylistStore, d.ScreenStore))
	mux.HandleFunc("POST /manage/{screenSlug}/media/{mediaId}/delete",
		manage.HandleDeleteMediaUI(d.MediaStore, d.ScreenStore, uploadDir))

	// ── JSON API — screens ────────────────────────────────────────────────
	mux.HandleFunc("GET /api/v1/tenants/{tenantSlug}/screens",
		manage.HandleListScreens(d.TenantStore, d.ScreenStore))
	mux.HandleFunc("POST /api/v1/tenants/{tenantSlug}/screens",
		manage.HandleCreateScreen(d.TenantStore, d.ScreenStore))

	// ── JSON API — media ──────────────────────────────────────────────────
	mux.HandleFunc("GET /api/v1/tenants/{tenantSlug}/media",
		manage.HandleListMedia(d.MediaStore))
	mux.HandleFunc("POST /api/v1/tenants/{tenantSlug}/media",
		manage.HandleUploadMedia(d.MediaStore, uploadDir))
	mux.HandleFunc("DELETE /api/v1/media/{id}",
		manage.HandleDeleteMedia(d.MediaStore, uploadDir))

	// ── JSON API — playlists ──────────────────────────────────────────────
	mux.HandleFunc("GET /api/v1/screens/{screenId}/playlist",
		manage.HandlePlayerPlaylist(d.ScreenStore, d.PlaylistStore))
	mux.HandleFunc("GET /api/v1/playlists/{screenId}",
		manage.HandleGetPlaylist(d.ScreenStore, d.PlaylistStore))
	mux.HandleFunc("POST /api/v1/playlists/{playlistId}/items",
		manage.HandleAddItem(d.PlaylistStore, d.MediaStore))
	mux.HandleFunc("PATCH /api/v1/items/{itemId}",
		manage.HandleUpdateItem(d.PlaylistStore))
	mux.HandleFunc("DELETE /api/v1/items/{itemId}",
		manage.HandleDeleteItem(d.PlaylistStore))
	mux.HandleFunc("PUT /api/v1/playlists/{playlistId}/order",
		manage.HandleReorder(d.PlaylistStore))
	mux.HandleFunc("PATCH /api/v1/playlists/{playlistId}/duration",
		manage.HandleUpdatePlaylistDuration(d.PlaylistStore))
}
