package handlers

import (
	"context"
	"net/http"
	"time"

	"github.com/orchard9/rdev/internal/auth"
	"github.com/orchard9/rdev/internal/domain"
	"github.com/orchard9/rdev/internal/service"
	"github.com/orchard9/rdev/pkg/api"
)

// MeHandler handles the /me endpoint.
type MeHandler struct {
	authService    *auth.Service
	projectService *service.ProjectService
}

// NewMeHandler creates a new me handler.
func NewMeHandler(authService *auth.Service, projectService *service.ProjectService) *MeHandler {
	return &MeHandler{
		authService:    authService,
		projectService: projectService,
	}
}

// Mount registers the /me route.
func (h *MeHandler) Mount(r api.Router) {
	r.Get("/me", h.Get)
}

// MeResponse is the JSON response for GET /me.
type MeResponse struct {
	ID            string           `json:"id"`
	Name          string           `json:"name"`
	KeyPrefix     string           `json:"key_prefix"`
	Scopes        []string         `json:"scopes"`
	ProjectAccess string           `json:"project_access"` // "unrestricted" | "restricted"
	Projects      []ProjectSummary `json:"projects,omitempty"`
	AllowedIPs    []string         `json:"allowed_ips,omitempty"`
	CreatedAt     string           `json:"created_at"`
	ExpiresAt     *string          `json:"expires_at,omitempty"`
	Active        bool             `json:"active"`
}

// ProjectSummary is a lightweight project view for embedding in /me.
type ProjectSummary struct {
	ID     string `json:"id"`
	Name   string `json:"name"`
	Status string `json:"status"`
}

// Get returns the current key's identity, scopes, and project access.
// GET /me
func (h *MeHandler) Get(w http.ResponseWriter, r *http.Request) {
	ctx, cancel := context.WithTimeout(r.Context(), TimeoutFastLookup)
	defer cancel()

	apiKey := auth.GetAPIKey(ctx)
	if apiKey == nil {
		api.WriteUnauthorized(w, r, "Not authenticated")
		return
	}

	resp := MeResponse{
		ID:            string(apiKey.ID),
		Name:          apiKey.Name,
		KeyPrefix:     apiKey.KeyPrefix,
		Scopes:        auth.ScopesToStrings(apiKey.Scopes),
		ProjectAccess: "unrestricted",
		AllowedIPs:    apiKey.AllowedIPs,
		CreatedAt:     apiKey.CreatedAt.Format(time.RFC3339),
		Active:        apiKey.IsActive(),
	}

	// Populate projects list when key is restricted (non-admin with explicit project_ids)
	if apiKey.ProjectIDs != nil && !apiKey.HasScope(domain.ScopeAdmin) {
		resp.ProjectAccess = "restricted"
		if h.projectService != nil {
			projects, _ := h.projectService.List(ctx, apiKey.ProjectIDs)
			resp.Projects = make([]ProjectSummary, len(projects))
			for i, p := range projects {
				resp.Projects[i] = ProjectSummary{
					ID:     string(p.ID),
					Name:   p.Name,
					Status: string(p.Status),
				}
			}
		}
	}

	if apiKey.ExpiresAt != nil {
		s := apiKey.ExpiresAt.Format(time.RFC3339)
		resp.ExpiresAt = &s
	}

	api.WriteSuccess(w, r, resp)
}
