package admin

import (
	"context"
	"fmt"
	"net/http"

	"github.com/go-chi/chi/v5"

	"github.com/ultisuite/ulti-backend/internal/api/apiresponse"
	"github.com/ultisuite/ulti-backend/internal/api/apivalidate"
	"github.com/ultisuite/ulti-backend/internal/api/middleware"
	"github.com/ultisuite/ulti-backend/internal/authentik"
)

func (s *Service) SyncIdentityProviders(ctx context.Context, actorSub, providerID string) (map[string]any, error) {
	stored, _, _, err := s.loadOrgPolicyRaw(ctx)
	if err != nil {
		return nil, err
	}
	idpSection, _ := stored["identity_providers"].(map[string]any)
	if idpSection == nil {
		return nil, fmt.Errorf("identity_providers not configured")
	}
	providers, _ := idpSection["providers"].([]any)
	found := false
	for _, item := range providers {
		pm, ok := item.(map[string]any)
		if !ok {
			continue
		}
		if id, _ := pm["id"].(string); id == providerID {
			found = true
			break
		}
	}
	if !found {
		return nil, fmt.Errorf("provider not found")
	}

	syncer := authentik.NewSourceSyncer(s.db, s.cfg)
	if err := syncer.SyncSection(ctx, idpSection); err != nil {
		return nil, err
	}
	s.logAudit(ctx, actorSub, "sync_identity_provider", map[string]any{
		"provider_id": providerID,
	})
	return s.GetOrgSettings(ctx)
}

func (h *Handler) GetIdentityProviderRedirectURI(w http.ResponseWriter, r *http.Request) {
	slug := chi.URLParam(r, "slug")
	if slug == "" {
		apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
			apivalidate.FieldDetail{Field: "slug", Message: "required"},
		))
		return
	}
	syncer := authentik.NewSourceSyncer(h.svc.db, h.svc.cfg)
	apiresponse.WriteJSON(w, http.StatusOK, map[string]any{
		"slug":         slug,
		"redirect_uri": syncer.RedirectURI(slug),
	})
}

func (h *Handler) TestIdentityProvider(w http.ResponseWriter, r *http.Request) {
	providerID := chi.URLParam(r, "providerID")
	if providerID == "" {
		apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
			apivalidate.FieldDetail{Field: "providerID", Message: "required"},
		))
		return
	}
	syncer := authentik.NewSourceSyncer(h.svc.db, h.svc.cfg)
	if err := syncer.TestProvider(r.Context(), providerID); err != nil {
		apiresponse.WriteError(w, r, http.StatusBadRequest, apiresponse.CodeInvalidRequest, err.Error(), nil)
		return
	}
	apiresponse.WriteJSON(w, http.StatusOK, map[string]any{"ok": true})
}

func (h *Handler) SyncIdentityProvider(w http.ResponseWriter, r *http.Request) {
	providerID := chi.URLParam(r, "providerID")
	if providerID == "" {
		apivalidate.WriteValidationError(w, r, apivalidate.NewValidationError(
			apivalidate.FieldDetail{Field: "providerID", Message: "required"},
		))
		return
	}
	claims := middleware.ClaimsFromContext(r.Context())
	payload, err := h.svc.SyncIdentityProviders(r.Context(), claims.Sub, providerID)
	if err != nil {
		h.logger.Error("sync identity provider", "error", err, "provider_id", providerID)
		apivalidate.WriteInternal(w, r)
		return
	}
	apiresponse.WriteJSON(w, http.StatusOK, payload)
}
