package admin

import (
	"net/http"
	"strings"

	"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/nextcloud"
)

func (h *Handler) registerDriveOrgMountRoutes(r chi.Router, read, write func(http.Handler) http.Handler) {
	r.With(read).Get("/drive/org-mounts", h.ListDriveOrgMounts)
	r.With(write).Post("/drive/org-mounts", h.CreateDriveOrgMount)
	r.With(write).Delete("/drive/org-mounts/{mountID}", h.DeleteDriveOrgMount)
}

func (h *Handler) ListDriveOrgMounts(w http.ResponseWriter, r *http.Request) {
	svc := h.driveService()
	mounts, err := svc.ListOrgMountsAdmin(r.Context())
	if err != nil {
		h.logger.Error("list drive org mounts", "error", err)
		apivalidate.WriteInternal(w, r)
		return
	}
	apiresponse.WriteJSON(w, http.StatusOK, map[string]any{"mounts": mounts})
}

func (h *Handler) CreateDriveOrgMount(w http.ResponseWriter, r *http.Request) {
	svc := h.driveService()
	var req struct {
		OrgSlug     string                       `json:"org_slug"`
		DisplayName string                       `json:"display_name"`
		WebDAV      nextcloud.WebDAVMountConfig  `json:"webdav"`
	}
	if err := apivalidate.DecodeJSON(w, r, 32<<10, &req); err != nil {
		return
	}
	if verr := validateOrgWebDAVMountRequest(req.OrgSlug, req.DisplayName, req.WebDAV); verr != nil {
		apivalidate.WriteValidationError(w, r, verr)
		return
	}
	mount, err := svc.CreateOrgWebDAVMount(r.Context(), req.OrgSlug, req.DisplayName, req.WebDAV)
	if err != nil {
		writeDriveAdminError(w, r, err)
		return
	}
	apiresponse.WriteJSON(w, http.StatusCreated, mount)
}

func (h *Handler) DeleteDriveOrgMount(w http.ResponseWriter, r *http.Request) {
	svc := h.driveService()
	mountID := chi.URLParam(r, "mountID")
	mount, err := svc.GetMountAdmin(r.Context(), mountID)
	if err != nil {
		writeDriveAdminError(w, r, err)
		return
	}
	if mount.Scope != "org" {
		apivalidate.WriteNotFound(w, r, "mount not found")
		return
	}
	if err := svc.DeleteMount(r.Context(), mountID); err != nil {
		writeDriveAdminError(w, r, err)
		return
	}
	w.WriteHeader(http.StatusNoContent)
}

func validateOrgWebDAVMountRequest(orgSlug, displayName string, cfg nextcloud.WebDAVMountConfig) *apivalidate.ValidationError {
	var details []apivalidate.FieldDetail
	if strings.TrimSpace(orgSlug) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "org_slug", Message: "required"})
	}
	if strings.TrimSpace(displayName) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "display_name", Message: "required"})
	}
	if strings.TrimSpace(cfg.Host) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "webdav.host", Message: "required"})
	}
	if strings.TrimSpace(cfg.User) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "webdav.user", Message: "required"})
	}
	if len(details) > 0 {
		return &apivalidate.ValidationError{Details: details}
	}
	return nil
}
