package httpserver

import (
	"net/http"
	"strconv"
	"time"
)

func (h *handler) health(w http.ResponseWriter, r *http.Request) {
	payload := map[string]any{
		"status":    "ok",
		"database":  "ok",
		"service":   h.config.AppName,
		"timestamp": time.Now().UTC().Format(time.RFC3339),
	}

	if h.store == nil {
		payload["status"] = "degraded"
		payload["database"] = "unavailable"
		payload["error"] = "database store is not initialized"
		writeJSON(w, http.StatusServiceUnavailable, payload)
		return
	}

	if err := h.store.HealthCheck(r.Context()); err != nil {
		payload["status"] = "degraded"
		payload["database"] = "unavailable"
		payload["error"] = "database ping failed"
		writeJSON(w, http.StatusServiceUnavailable, payload)
		return
	}

	writeJSON(w, http.StatusOK, payload)
}

func (h *handler) home(w http.ResponseWriter, r *http.Request) {
	data := HomePageData{
		PageData: PageData{
			Title:       "Client Update API Ready",
			Eyebrow:     "Usable Product Flow",
			Heading:     h.config.AppName,
			BaseURL:     h.config.BaseURL,
			Description: "Protected admin flows now connect all the way through to bearer-authenticated client endpoints for project discovery, latest-release metadata, release metadata, and private artifact downloads.",
		},
		Links: []PageLink{
			{Label: "Health check", Href: "/healthz", Description: "JSON readiness endpoint covering both the HTTP server and SQLite connectivity."},
			{Label: "Admin login", Href: "/admin/login", Description: "Server-rendered login form for the protected admin workspace."},
			{Label: "Projects", Href: "/admin/projects", Description: "Create projects, attach tags, upload releases, and inspect the client-facing metadata paths from the protected admin UI."},
			{Label: "Tags", Href: "/admin/tags", Description: "Manage reusable tags that projects can use from day one."},
			{Label: "API keys", Href: "/admin/api-keys", Description: "Generate hashed API keys, reveal the raw key once, preview accessible projects, and copy the client API quick-start flow."},
			{Label: "Client API", Href: "/api/v1", Description: "Versioned JSON API entrypoint documenting the bearer-authenticated project, metadata, and download endpoints."},
		},
	}

	renderPage(w, h.renderer, "home", data)
}

func (h *handler) adminHome(w http.ResponseWriter, r *http.Request) {
	projects, err := h.store.Projects.List(r.Context())
	if err != nil {
		http.Error(w, "project summary lookup failed", http.StatusInternalServerError)
		return
	}

	tags, err := h.store.Tags.List(r.Context())
	if err != nil {
		http.Error(w, "tag summary lookup failed", http.StatusInternalServerError)
		return
	}

	apiKeys, err := h.store.APIKeys.List(r.Context())
	if err != nil {
		http.Error(w, "api key summary lookup failed", http.StatusInternalServerError)
		return
	}

	totalReleases := 0
	for _, item := range projects {
		totalReleases += item.ReleaseCount
	}

	data := DashboardPageData{
		PageData: h.basePageData(
			r,
			"Admin Dashboard",
			"Protected Admin",
			"Admin Dashboard",
			"Projects, tags, releases, and API keys now feed the client update API so admins can complete the end-to-end product flow in one workspace.",
		),
		Metrics: []DashboardMetric{
			{Label: "Projects", Value: strconv.Itoa(len(projects)), Description: "Active and archived projects available for management."},
			{Label: "Tags", Value: strconv.Itoa(len(tags)), Description: "Reusable labels ready for project assignment and future access scopes."},
			{Label: "Releases", Value: strconv.Itoa(totalReleases), Description: "Stored release records with checksum and disk path metadata."},
			{Label: "API Keys", Value: strconv.Itoa(len(apiKeys)), Description: "Hashed client credentials with permission flags and scope rules."},
		},
		Links: []PageLink{
			{Label: "Manage projects", Href: "/admin/projects", Description: "Open project detail pages to edit metadata, attach tags, upload releases, and inspect client metadata or download paths."},
			{Label: "Manage tags", Href: "/admin/tags", Description: "Create tags once and reuse them across projects from the same protected UI."},
			{Label: "Manage API keys", Href: "/admin/api-keys", Description: "Generate, revoke, and scope client credentials, then copy the bearer-authenticated client API flow."},
			{Label: "Client API", Href: "/api/v1", Description: "Public JSON index for accessible projects, latest release metadata, release metadata, and authenticated downloads."},
		},
	}

	renderPage(w, h.renderer, "admin", data)
}

func (h *handler) apiIndex(w http.ResponseWriter, r *http.Request) {
	writeJSON(w, http.StatusOK, map[string]any{
		"service": h.config.AppName,
		"version": "v1",
		"status":  "client-api-ready",
		"auth": map[string]any{
			"type":   "bearer",
			"header": "Authorization: Bearer <api_key>",
		},
		"routes": []map[string]string{
			{
				"method":      http.MethodGet,
				"path":        "/api/v1/projects",
				"description": "List active projects accessible to the API key.",
			},
			{
				"method":      http.MethodGet,
				"path":        "/api/v1/projects/{projectSlug}/releases/latest",
				"description": "Get the latest active release metadata for an accessible project.",
			},
			{
				"method":      http.MethodGet,
				"path":        "/api/v1/releases/{releaseID}",
				"description": "Get release metadata for an accessible release.",
			},
			{
				"method":      http.MethodGet,
				"path":        "/api/v1/releases/{releaseID}/download",
				"description": "Download the private artifact for an accessible release.",
			},
		},
	})
}

func renderPage(w http.ResponseWriter, renderer *Renderer, name string, data any) {
	renderPageStatus(w, renderer, name, http.StatusOK, data)
}

func renderPageStatus(w http.ResponseWriter, renderer *Renderer, name string, status int, data any) {
	if err := renderer.Render(w, name, status, data); err != nil {
		http.Error(w, "template rendering failed", http.StatusInternalServerError)
	}
}
