package dialectsfcrm

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"sort"
	"strconv"
	"strings"

	"github.com/nexuscrm/dialect-sf-crm/wire"
	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/contract"
	"github.com/nexuscrm/shared/pkg/dialect"
	sharederrors "github.com/nexuscrm/shared/pkg/errors"
	"github.com/nexuscrm/shared/pkg/models"
	"github.com/nexuscrm/shared/pkg/queryspec"
)

const (
	folderDefaultPageSize        = 200
	folderMaxPageSize            = 2000
	folderQueryLimit             = 10000
	folderResourceAccessType     = "folder"
	folderGenericInternalError   = "An internal server error occurred. Contact your system administrator."
	folderCodeInsufficientAccess = "INSUFFICIENT_ACCESS"
)

type folderRouteDeps struct {
	records        contract.Records
	query          contract.Query
	folderAccess   contract.FolderAccess
	resourceAccess contract.ResourceAccess
	policy         contract.CapabilityPolicy
}

type folderRouteErrorKind string

const (
	folderErrInvalidField         folderRouteErrorKind = "invalid_field"
	folderErrInvalidRequest       folderRouteErrorKind = "invalid_request"
	folderErrRequiredFieldMissing folderRouteErrorKind = "required_field_missing"
	folderErrForbidden            folderRouteErrorKind = "forbidden"
	folderErrInsufficientAccess   folderRouteErrorKind = "insufficient_access"
	folderErrNotFound             folderRouteErrorKind = "not_found"
	folderErrShareSyncFailed      folderRouteErrorKind = "share_sync_failed"
	folderErrInternal             folderRouteErrorKind = "internal"
)

type folderRouteError struct {
	kind    folderRouteErrorKind
	message string
	cause   error
}

func (e *folderRouteError) Error() string {
	if e == nil {
		return ""
	}
	if e.message != "" {
		return e.message
	}
	return string(e.kind)
}

func (e *folderRouteError) Unwrap() error {
	if e == nil {
		return nil
	}
	return e.cause
}

type folderModel struct {
	ID               string
	Name             string
	DeveloperName    string
	Description      string
	RawType          string
	Type             string
	AccessType       string
	ParentFolderID   string
	OwnerID          string
	CreatedByID      string
	CreatedDate      string
	LastModifiedDate string
}

type folderShareModel struct {
	ID              string
	FolderID        string
	SharedToID      string
	SharedToType    string
	AccessLevel     string
	SharedWithLabel string
}

type folderResponse struct {
	ID               string `json:"id"`
	Name             string `json:"name"`
	Label            string `json:"label"`
	DeveloperName    string `json:"developerName"`
	Description      string `json:"description,omitempty"`
	Type             string `json:"type"`
	AccessType       string `json:"accessType"`
	ParentFolderID   string `json:"parentFolderId,omitempty"`
	CreatedDate      string `json:"createdDate,omitempty"`
	LastModifiedDate string `json:"lastModifiedDate,omitempty"`
}

type folderShareResponse struct {
	ShareID         string `json:"shareId"`
	AccessType      string `json:"accessType"`
	ShareType       string `json:"shareType"`
	SharedWithID    string `json:"sharedWithId"`
	SharedWithLabel string `json:"sharedWithLabel"`
	URL             string `json:"url"`
}

type folderChildrenResponse struct {
	Folders   []folderResponse `json:"folders"`
	TotalSize int              `json:"totalSize"`
	URL       string           `json:"url"`
}

type folderSharesResponse struct {
	Shares []folderShareResponse `json:"shares"`
}

type folderListResponse struct {
	Folders     []folderResponse `json:"folders"`
	HasNextPage bool             `json:"hasNextPage"`
	NextPageURL string           `json:"nextPageUrl,omitempty"`
}

type folderCreateRequest struct {
	Name           string `json:"name"`
	DeveloperName  string `json:"developerName"`
	Description    string `json:"description,omitempty"`
	Type           string `json:"type"`
	AccessType     string `json:"accessType"`
	ParentFolderID string `json:"parentFolderId,omitempty"`
}

type folderUpdateRequest struct {
	Name           *string `json:"name,omitempty"`
	DeveloperName  *string `json:"developerName,omitempty"`
	Description    *string `json:"description,omitempty"`
	AccessType     *string `json:"accessType,omitempty"`
	ParentFolderID *string `json:"parentFolderId,omitempty"`
}

type folderShareMutationRequest struct {
	SharedToID   string `json:"sharedToId"`
	SharedToType string `json:"sharedToType"`
	AccessLevel  string `json:"accessLevel"`
}

type folderSharesMutationRequest struct {
	Shares []folderShareMutationRequest `json:"shares"`
}

type folderShareUpdateRequest struct {
	AccessLevel string `json:"accessLevel"`
}

type folderTransferOwnershipRequest struct {
	SourceUserID string `json:"sourceUserId"`
	TargetUserID string `json:"targetUserId"`
}

type folderTransferOwnershipResponse struct {
	Success      bool   `json:"success"`
	SourceUserID string `json:"sourceUserId"`
	TargetUserID string `json:"targetUserId"`
}

func ListFoldersNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderResourceDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	rt.ensurePersonalFolders(ctx, req.User)

	filterGroup := queryValue(req, "filterGroup")
	page, pageSize := parseFolderPagination(req)
	visibleIDs, err := rt.resourceAccess.ListVisibleResourceIDs(ctx, req.User, contract.ResourceVisibilityRequest{
		ResourceType: folderResourceAccessType,
	})
	if err != nil {
		return &dialect.Response{Status: http.StatusOK, Body: folderListResponse{Folders: []folderResponse{}, HasNextPage: false}}, nil
	}
	if visibleIDs != nil && len(visibleIDs) == 0 {
		return &dialect.Response{Status: http.StatusOK, Body: folderListResponse{Folders: []folderResponse{}, HasNextPage: false}}, nil
	}

	folders, err := rt.queryFolders(ctx, queryspec.Predicate{}, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	folders = filterFoldersByGroup(folders, filterGroup)
	if visibleIDs != nil {
		folders = filterVisibleFolders(folders, visibleIDs)
	}
	paged, hasNextPage := paginateFolders(folders, page, pageSize)
	body := folderListResponse{
		Folders:     folderResponses(paged),
		HasNextPage: hasNextPage,
	}
	if hasNextPage {
		body.NextPageURL = folderPageURL(req, "/folders", page+1, pageSize, filterGroup)
	}
	return &dialect.Response{Status: http.StatusOK, Body: body}, nil
}

func CreateFolderNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	var body folderCreateRequest
	if err := json.Unmarshal(req.Body, &body); err != nil {
		return folderErrorResponse(req, newFolderRouteError(folderErrRequiredFieldMissing, err.Error(), err)), nil
	}
	if body.Name == "" {
		return folderErrorResponse(req, newFolderRouteError(folderErrRequiredFieldMissing, "Name is required", nil)), nil
	}

	folderType := normalizeFolderType(body.Type)
	if err := rt.requireFolderCreateCapability(ctx, req.User, folderType); err != nil {
		return folderErrorResponse(req, err), nil
	}
	if err := rt.requireFolderManageCapability(ctx, req.User, folderType); err != nil {
		return folderErrorResponse(req, err), nil
	}

	developerName := body.DeveloperName
	if developerName == "" {
		developerName = strings.ReplaceAll(body.Name, " ", "_")
	}
	accessType := normalizeFolderAccessType(body.AccessType)
	record := contract.Record{
		constants.FieldReportFolder_Name:          body.Name,
		constants.FieldReportFolder_DeveloperName: developerName,
		constants.FieldReportFolder_Type:          folderType,
		constants.FieldReportFolder_AccessType:    accessType,
	}
	if body.Description != "" {
		record[constants.FieldReportFolder_Description] = body.Description
	}
	if body.ParentFolderID != "" {
		if !validateFolderID(body.ParentFolderID) {
			return folderErrorResponse(req, newFolderRouteError(folderErrInvalidField, "Invalid parent folder ID format", nil)), nil
		}
		if !rt.folderExists(ctx, body.ParentFolderID, req.User) {
			return folderErrorResponse(req, newFolderRouteError(folderErrNotFound, "Parent folder not found", nil)), nil
		}
		record[constants.FieldReportFolder_ParentID] = body.ParentFolderID
	}

	created, err := rt.records.Insert(ctx, constants.TableReportFolder, record, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if accessType == "Public" {
		folderID := folderRecordString(created, constants.FieldReportFolder_ID)
		if folderID != "" {
			if err := rt.ensureOrganizationViewGrant(ctx, folderID, req.User); err != nil {
				if delErr := rt.records.Delete(ctx, constants.TableReportFolder, folderID, req.User); delErr != nil {
					logFolderInternalError("folder creation share rollback failed", delErr)
				}
				return folderErrorResponse(req, newFolderRouteError(folderErrShareSyncFailed, "Folder creation failed: could not create Organization share", err)), nil
			}
		}
	}
	return &dialect.Response{Status: http.StatusCreated, Body: folderResponseFromModel(folderFromRecord(created))}, nil
}

func UpdateFolderNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return resp, nil
	}
	var body folderUpdateRequest
	if err := json.Unmarshal(req.Body, &body); err != nil {
		return folderErrorResponse(req, newFolderRouteError(folderErrInvalidRequest, err.Error(), err)), nil
	}
	folder, err := rt.authorizeFolderManage(ctx, folderID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if err := rt.requireFolderManageCapability(ctx, req.User, folder.Type); err != nil {
		return folderErrorResponse(req, err), nil
	}
	if body.Name != nil || body.DeveloperName != nil {
		if !rt.hasCapability(ctx, req.User, constants.PermManageUsers) {
			return folderErrorResponse(req, newFolderRouteError(folderErrInsufficientAccess, "Only administrators can change folder Name or DeveloperName", nil)), nil
		}
	}

	updates := contract.Record{}
	if body.Name != nil {
		updates[constants.FieldReportFolder_Name] = *body.Name
	}
	if body.DeveloperName != nil {
		updates[constants.FieldReportFolder_DeveloperName] = *body.DeveloperName
	}
	if body.Description != nil {
		updates[constants.FieldReportFolder_Description] = *body.Description
	}
	oldAccessType := folder.AccessType
	newAccessType := ""
	if body.AccessType != nil {
		newAccessType = normalizeFolderAccessType(*body.AccessType)
		updates[constants.FieldReportFolder_AccessType] = newAccessType
	}
	if body.ParentFolderID != nil {
		if *body.ParentFolderID != "" && !validateFolderID(*body.ParentFolderID) {
			return folderErrorResponse(req, newFolderRouteError(folderErrInvalidField, "Invalid parent folder ID format", nil)), nil
		}
		if *body.ParentFolderID != "" && !rt.folderExists(ctx, *body.ParentFolderID, req.User) {
			return folderErrorResponse(req, newFolderRouteError(folderErrNotFound, "Parent folder not found", nil)), nil
		}
		updates[constants.FieldReportFolder_ParentID] = *body.ParentFolderID
	}
	if len(updates) == 0 {
		return folderErrorResponse(req, newFolderRouteError(folderErrRequiredFieldMissing, "No fields to update", nil)), nil
	}
	if err := rt.records.Update(ctx, constants.TableReportFolder, folderID, updates, req.User); err != nil {
		return folderErrorResponse(req, err), nil
	}
	if newAccessType != "" && oldAccessType != newAccessType {
		if err := rt.syncFolderAccessType(ctx, folderID, oldAccessType, newAccessType, req.User); err != nil {
			if revertErr := rt.records.Update(ctx, constants.TableReportFolder, folderID, contract.Record{constants.FieldReportFolder_AccessType: oldAccessType}, req.User); revertErr != nil {
				logFolderInternalError("folder access type rollback failed", revertErr)
			}
			return folderErrorResponse(req, newFolderRouteError(folderErrShareSyncFailed, "Folder update reverted: failed to sync folder sharing", err)), nil
		}
	}
	updated, err := rt.records.Retrieve(ctx, constants.TableReportFolder, folderID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	return &dialect.Response{Status: http.StatusOK, Body: folderResponseFromModel(folderFromRecord(updated))}, nil
}

func DeleteFolderNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return resp, nil
	}
	folder, err := rt.authorizeFolderManage(ctx, folderID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if err := rt.requireFolderManageCapability(ctx, req.User, folder.Type); err != nil {
		return folderErrorResponse(req, err), nil
	}
	if err := rt.records.Delete(ctx, constants.TableReportFolder, folderID, req.User); err != nil {
		return folderErrorResponse(req, err), nil
	}
	return &dialect.Response{Status: http.StatusNoContent}, nil
}

func AddFolderSharesNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, _, shares, resp := rt.parseFolderSharesMutation(ctx, req, true)
	if resp != nil {
		return resp, nil
	}
	grants := make([]contract.ResourceAccessGrant, 0, len(shares))
	for _, share := range shares {
		grant, err := rt.resourceAccess.CreateResourceAccessGrant(ctx, req.User, contract.ResourceAccessCreateRequest{
			ResourceType: folderResourceAccessType,
			ResourceID:   folderID,
			CreatedByID:  req.User.ID,
			Grant:        share,
		})
		if err != nil {
			return folderErrorResponse(req, err), nil
		}
		grants = append(grants, *grant)
	}
	responses := rt.folderShareResponsesFromGrants(ctx, req, folderID, grants)
	return &dialect.Response{Status: http.StatusCreated, Body: folderSharesResponse{Shares: responses}}, nil
}

func ReplaceFolderSharesNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, folder, shares, resp := rt.parseFolderSharesMutation(ctx, req, true)
	if resp != nil {
		return resp, nil
	}
	shares = appendDerivedFolderOrganizationShare(folder, shares)
	grants, err := rt.resourceAccess.ReplaceResourceAccessGrants(ctx, req.User, contract.ResourceAccessReplaceRequest{
		ResourceType: folderResourceAccessType,
		ResourceID:   folderID,
		CreatedByID:  req.User.ID,
		Grants:       shares,
	})
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	responses := rt.folderShareResponsesFromGrants(ctx, req, folderID, grants)
	return &dialect.Response{Status: http.StatusOK, Body: folderSharesResponse{Shares: responses}}, nil
}

func UpdateFolderShareNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, shareID, resp := folderAndShareIDParams(req)
	if resp != nil {
		return resp, nil
	}
	var body folderShareUpdateRequest
	if err := json.Unmarshal(req.Body, &body); err != nil {
		return folderErrorResponse(req, newFolderRouteError(folderErrInvalidRequest, err.Error(), err)), nil
	}
	if strings.TrimSpace(body.AccessLevel) == "" {
		return folderErrorResponse(req, newFolderRouteError(folderErrInvalidRequest, "accessLevel is required", nil)), nil
	}
	folder, err := rt.authorizeFolderManage(ctx, folderID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if err := rt.requireFolderManageCapability(ctx, req.User, folder.Type); err != nil {
		return folderErrorResponse(req, err), nil
	}
	current, err := rt.getFolderShareGrant(ctx, folderID, shareID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if isFolderOrganizationShare(current.SharedToType, current.SharedToID) {
		return folderErrorResponse(req, folderOrganizationShareMutationError()), nil
	}
	accessLevel := normalizeFolderAccessLevel(body.AccessLevel)
	grant, err := rt.resourceAccess.UpdateResourceAccessGrant(ctx, req.User, contract.ResourceAccessUpdateRequest{
		ResourceType: folderResourceAccessType,
		GrantID:      shareID,
		AccessLevel:  accessLevel,
	})
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if grant == nil {
		grant = &contract.ResourceAccessGrant{
			ID:            current.ID,
			ResourceType:  folderResourceAccessType,
			ResourceID:    folderID,
			PrincipalID:   current.SharedToID,
			PrincipalType: current.SharedToType,
			AccessLevel:   accessLevel,
		}
	}
	responses := rt.folderShareResponsesFromGrants(ctx, req, folderID, []contract.ResourceAccessGrant{*grant})
	if len(responses) == 0 {
		return folderInternalErrorResponseWithLog("folder share mutation response projection returned no shares", nil), nil
	}
	return &dialect.Response{Status: http.StatusOK, Body: responses[0]}, nil
}

func DeleteFolderShareNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, shareID, resp := folderAndShareIDParams(req)
	if resp != nil {
		return resp, nil
	}
	folder, err := rt.authorizeFolderManage(ctx, folderID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if err := rt.requireFolderManageCapability(ctx, req.User, folder.Type); err != nil {
		return folderErrorResponse(req, err), nil
	}
	current, err := rt.getFolderShareGrant(ctx, folderID, shareID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	if isFolderOrganizationShare(current.SharedToType, current.SharedToID) {
		return folderErrorResponse(req, folderOrganizationShareMutationError()), nil
	}
	if err := rt.resourceAccess.DeleteResourceAccessGrant(ctx, req.User, contract.ResourceAccessDeleteRequest{
		ResourceType: folderResourceAccessType,
		GrantID:      shareID,
	}); err != nil {
		return folderErrorResponse(req, err), nil
	}
	return &dialect.Response{Status: http.StatusNoContent}, nil
}

func TransferFolderOwnershipNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderMutationDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	if !rt.hasCapability(ctx, req.User, constants.PermManageUsers) {
		return folderErrorResponse(req, newFolderRouteError(folderErrForbidden, "Admin permission required to transfer folder ownership", nil)), nil
	}
	var body folderTransferOwnershipRequest
	if err := json.Unmarshal(req.Body, &body); err != nil {
		return folderErrorResponse(req, newFolderRouteError(folderErrRequiredFieldMissing, err.Error(), err)), nil
	}
	if strings.TrimSpace(body.SourceUserID) == "" || strings.TrimSpace(body.TargetUserID) == "" {
		return folderErrorResponse(req, newFolderRouteError(folderErrRequiredFieldMissing, "sourceUserId and targetUserId are required", nil)), nil
	}
	if !validateFolderID(body.SourceUserID) || !validateFolderID(body.TargetUserID) {
		return folderErrorResponse(req, newFolderRouteError(folderErrInvalidField, "Invalid user ID format", nil)), nil
	}
	if body.SourceUserID == body.TargetUserID {
		return folderErrorResponse(req, newFolderRouteError(folderErrInvalidField, "sourceUserId and targetUserId must be different", nil)), nil
	}
	if err := rt.resourceAccess.TransferResourceOwnership(ctx, req.User, contract.ResourceOwnershipTransferRequest{
		ResourceType:  folderResourceAccessType,
		SourceOwnerID: body.SourceUserID,
		TargetOwnerID: body.TargetUserID,
	}); err != nil {
		return folderInternalErrorResponseWithLog("transfer folder ownership", err), nil
	}
	return &dialect.Response{Status: http.StatusOK, Body: folderTransferOwnershipResponse{Success: true, SourceUserID: body.SourceUserID, TargetUserID: body.TargetUserID}}, nil
}

func GetFolderNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return resp, nil
	}
	folder, err := rt.authorizeFolderRead(ctx, folderID, req.User, "Folder not found")
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	return &dialect.Response{Status: http.StatusOK, Body: folderResponseFromModel(folder)}, nil
}

func GetFolderChildrenNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	parentID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return resp, nil
	}
	if _, err := rt.authorizeFolderRead(ctx, parentID, req.User, "Parent folder not found"); err != nil {
		return folderErrorResponse(req, err), nil
	}
	children, err := rt.queryFolders(ctx, queryspec.FieldPredicate(constants.FieldReportFolder_ParentID, "=", parentID), req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	page, pageSize := parseFolderPagination(req)
	paged, _ := paginateFolders(children, page, pageSize)
	body := folderChildrenResponse{
		Folders:   folderResponses(paged),
		TotalSize: len(children),
		URL:       folderPageURL(req, "/folders/"+url.PathEscape(parentID)+"/children", page, pageSize, ""),
	}
	return &dialect.Response{Status: http.StatusOK, Body: body}, nil
}

func ListFolderSharesNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return resp, nil
	}
	if _, err := rt.authorizeFolderRead(ctx, folderID, req.User, "Folder not found"); err != nil {
		return folderErrorResponse(req, err), nil
	}
	shares, err := rt.listFolderShares(ctx, folderID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	return &dialect.Response{Status: http.StatusOK, Body: folderSharesResponse{Shares: folderShareResponses(req, folderID, shares)}}, nil
}

func GetFolderShareNeutralHandler(ctx context.Context, req *dialect.Request, deps dialect.Deps) (*dialect.Response, error) {
	rt, resp := folderDepsFrom(deps)
	if resp != nil {
		return resp, nil
	}
	folderID, shareID, resp := folderAndShareIDParams(req)
	if resp != nil {
		return resp, nil
	}
	if _, err := rt.authorizeFolderRead(ctx, folderID, req.User, "Folder not found"); err != nil {
		return folderErrorResponse(req, err), nil
	}
	share, err := rt.getFolderShare(ctx, folderID, shareID, req.User)
	if err != nil {
		return folderErrorResponse(req, err), nil
	}
	return &dialect.Response{Status: http.StatusOK, Body: folderShareResponseFromModel(req, folderID, share)}, nil
}

func folderDepsFrom(deps dialect.Deps) (*folderRouteDeps, *dialect.Response) {
	policy, _ := deps.Contracts.Policy.(contract.CapabilityPolicy)
	rt := &folderRouteDeps{
		records:        deps.Contracts.Records,
		query:          deps.Contracts.Query,
		folderAccess:   deps.Contracts.FolderAccess,
		resourceAccess: deps.Contracts.ResourceAccess,
		policy:         policy,
	}
	if rt.records == nil || rt.query == nil || rt.folderAccess == nil {
		return nil, folderInternalErrorResponseWithLog("contracts unavailable", nil)
	}
	return rt, nil
}

func folderResourceDepsFrom(deps dialect.Deps) (*folderRouteDeps, *dialect.Response) {
	rt, resp := folderDepsFrom(deps)
	if resp != nil {
		return nil, resp
	}
	if rt.resourceAccess == nil {
		return nil, folderInternalErrorResponseWithLog("resource access contract unavailable", nil)
	}
	return rt, nil
}

func folderMutationDepsFrom(deps dialect.Deps) (*folderRouteDeps, *dialect.Response) {
	rt, resp := folderResourceDepsFrom(deps)
	if resp != nil {
		return nil, resp
	}
	if rt.policy == nil {
		return nil, folderInternalErrorResponseWithLog("capability policy contract unavailable", nil)
	}
	return rt, nil
}

func (rt *folderRouteDeps) queryFolders(ctx context.Context, filter queryspec.Predicate, user *models.UserSession) ([]folderModel, error) {
	result, err := rt.query.Query(ctx, queryspec.QuerySpec{
		ObjectAPIName: constants.TableReportFolder,
		Filter:        filter,
		SortField:     constants.FieldReportFolder_Name,
		SortDirection: "ASC",
		Limit:         folderQueryLimit,
	}, user)
	if err != nil {
		return nil, err
	}
	records := []contract.Record(nil)
	if result != nil {
		records = result.Records
	}
	folders := make([]folderModel, 0, len(records))
	for _, record := range records {
		folders = append(folders, *folderFromRecord(record))
	}
	return folders, nil
}

func (rt *folderRouteDeps) authorizeFolderRead(ctx context.Context, folderID string, user *models.UserSession, notFoundMessage string) (*folderModel, error) {
	if !rt.folderAccess.CheckFolderAccess(ctx, user, folderID, contract.FolderAccessView) {
		return nil, newFolderRouteError(folderErrNotFound, folderNotFoundMessage(folderID), nil)
	}
	record, err := rt.records.Retrieve(ctx, constants.TableReportFolder, folderID, user)
	if err != nil {
		if !isNotFoundError(err) {
			return nil, err
		}
		return nil, newFolderRouteError(folderErrNotFound, notFoundMessage, err)
	}
	return folderFromRecord(record), nil
}

func (rt *folderRouteDeps) authorizeFolderManage(ctx context.Context, folderID string, user *models.UserSession) (*folderModel, error) {
	if !rt.folderAccess.CheckFolderAccess(ctx, user, folderID, contract.FolderAccessManage) {
		return nil, newFolderRouteError(folderErrNotFound, folderNotFoundMessage(folderID), nil)
	}
	record, err := rt.records.Retrieve(ctx, constants.TableReportFolder, folderID, user)
	if err != nil {
		if !isNotFoundError(err) {
			return nil, err
		}
		return nil, newFolderRouteError(folderErrNotFound, "Folder not found", err)
	}
	return folderFromRecord(record), nil
}

func (rt *folderRouteDeps) folderExists(ctx context.Context, folderID string, user *models.UserSession) bool {
	_, err := rt.records.Retrieve(ctx, constants.TableReportFolder, folderID, user)
	return err == nil
}

func (rt *folderRouteDeps) ensurePersonalFolders(ctx context.Context, user *models.UserSession) {
	if user == nil {
		return
	}
	for _, folderType := range []string{"Report", "Dashboard"} {
		result, err := rt.query.Query(ctx, queryspec.QuerySpec{
			ObjectAPIName: constants.TableReportFolder,
			Filter: queryspec.CriteriaPredicate([]queryspec.QueryCriterion{
				{Field: constants.FieldReportFolder_CreatedByID, Op: "=", Val: user.ID},
				{Field: constants.FieldReportFolder_AccessType, Op: "=", Val: "Hidden"},
				{Field: constants.FieldReportFolder_Type, Op: "=", Val: folderType},
			}),
			Limit: 1,
		}, user)
		if err != nil {
			logFolderInternalError("ensure personal folders query failed", err)
			continue
		}
		if result != nil && len(result.Records) > 0 {
			continue
		}
		name := "My Personal Custom Reports"
		developerName := fmt.Sprintf("my_personal_reports_%s", user.ID)
		if folderType == "Dashboard" {
			name = "My Personal Dashboards"
			developerName = fmt.Sprintf("my_personal_dashboards_%s", user.ID)
		}
		_, err = rt.records.Insert(ctx, constants.TableReportFolder, contract.Record{
			constants.FieldReportFolder_Name:          name,
			constants.FieldReportFolder_DeveloperName: developerName,
			constants.FieldReportFolder_Type:          folderType,
			constants.FieldReportFolder_AccessType:    "Hidden",
			constants.FieldReportFolder_CreatedByID:   user.ID,
			constants.FieldReportFolder_OwnerID:       user.ID,
		}, user)
		if err != nil {
			logFolderInternalError("ensure personal folders insert failed", err)
		}
	}
}

func (rt *folderRouteDeps) listFolderShares(ctx context.Context, folderID string, user *models.UserSession) ([]folderShareModel, error) {
	if rt.resourceAccess == nil {
		return nil, newFolderRouteError(folderErrInternal, "contracts unavailable", nil)
	}
	grants, err := rt.resourceAccess.ListResourceAccessGrants(ctx, user, contract.ResourceAccessListRequest{
		ResourceType: folderResourceAccessType,
		ResourceID:   folderID,
	})
	if err != nil {
		return nil, err
	}
	shares := make([]folderShareModel, 0, len(grants))
	for _, grant := range grants {
		shares = append(shares, folderShareFromGrant(grant))
	}
	if err := rt.populateFolderShareLabels(ctx, shares, user); err != nil {
		return nil, err
	}
	return shares, nil
}

func (rt *folderRouteDeps) getFolderShare(ctx context.Context, folderID string, shareID string, user *models.UserSession) (*folderShareModel, error) {
	if rt.resourceAccess == nil {
		return nil, newFolderRouteError(folderErrInternal, "contracts unavailable", nil)
	}
	grant, err := rt.resourceAccess.GetResourceAccessGrant(ctx, user, contract.ResourceAccessGetRequest{
		ResourceType: folderResourceAccessType,
		GrantID:      shareID,
	})
	if err != nil {
		return nil, newFolderRouteError(folderErrNotFound, "Share not found", err)
	}
	if grant == nil {
		return nil, newFolderRouteError(folderErrNotFound, "Share not found", nil)
	}
	shareModel := folderShareFromGrant(*grant)
	share := &shareModel
	if share.FolderID != folderID {
		return nil, newFolderRouteError(folderErrNotFound, "Share not found", nil)
	}
	shares := []folderShareModel{*share}
	if err := rt.populateFolderShareLabels(ctx, shares, user); err != nil {
		return nil, err
	}
	share = &shares[0]
	return share, nil
}

func (rt *folderRouteDeps) getFolderShareGrant(ctx context.Context, folderID string, shareID string, user *models.UserSession) (*folderShareModel, error) {
	if rt.resourceAccess == nil {
		return nil, newFolderRouteError(folderErrInternal, "contracts unavailable", nil)
	}
	grant, err := rt.resourceAccess.GetResourceAccessGrant(ctx, user, contract.ResourceAccessGetRequest{
		ResourceType: folderResourceAccessType,
		GrantID:      shareID,
	})
	if err != nil {
		return nil, newFolderRouteError(folderErrNotFound, "Share not found", err)
	}
	if grant == nil {
		return nil, newFolderRouteError(folderErrNotFound, "Share not found", nil)
	}
	shareModel := folderShareFromGrant(*grant)
	if shareModel.FolderID != folderID {
		return nil, newFolderRouteError(folderErrNotFound, "Share not found", nil)
	}
	return &shareModel, nil
}

func (rt *folderRouteDeps) hasCapability(ctx context.Context, user *models.UserSession, capability constants.Permission) bool {
	return rt != nil && rt.policy != nil && rt.policy.HasCapability(ctx, user, contract.Capability(capability))
}

func (rt *folderRouteDeps) requireFolderCreateCapability(ctx context.Context, user *models.UserSession, folderType string) error {
	switch folderType {
	case "Dashboard":
		if !rt.hasCapability(ctx, user, constants.PermCreateDashboards) {
			return newFolderRouteError(folderErrInsufficientAccess, "You do not have permission to create dashboards", nil)
		}
	default:
		if !rt.hasCapability(ctx, user, constants.PermCreateCustomizeReports) {
			return newFolderRouteError(folderErrInsufficientAccess, "You do not have permission to create reports", nil)
		}
	}
	return nil
}

func (rt *folderRouteDeps) requireFolderManageCapability(ctx context.Context, user *models.UserSession, folderType string) error {
	switch folderType {
	case "Dashboard":
		if rt.hasCapability(ctx, user, constants.PermManageDashbdsInPubFolders) {
			return nil
		}
	default:
		if rt.hasCapability(ctx, user, constants.PermManageReportsInPubFolders) {
			return nil
		}
	}
	return newFolderRouteError(folderErrForbidden, "You do not have permission to manage this folder type", nil)
}

func (rt *folderRouteDeps) ensureOrganizationViewGrant(ctx context.Context, folderID string, user *models.UserSession) error {
	createdByID := ""
	if user != nil {
		createdByID = user.ID
	}
	_, err := rt.resourceAccess.EnsureResourceAccessGrant(ctx, user, contract.ResourceAccessEnsureRequest{
		ResourceType: folderResourceAccessType,
		ResourceID:   folderID,
		CreatedByID:  createdByID,
		Grant:        folderOrganizationViewGrantInput(),
	})
	return err
}

func (rt *folderRouteDeps) syncFolderAccessType(ctx context.Context, folderID string, oldAccessType string, newAccessType string, user *models.UserSession) error {
	switch newAccessType {
	case "Hidden", "Shared":
		return rt.resourceAccess.DeleteResourceAccessGrantsByPrincipalType(ctx, user, contract.ResourceAccessDeleteByPrincipalTypeRequest{
			ResourceType:  folderResourceAccessType,
			ResourceID:    folderID,
			PrincipalType: "Organization",
		})
	case "Public":
		return rt.ensureOrganizationViewGrant(ctx, folderID, user)
	default:
		return nil
	}
}

func (rt *folderRouteDeps) parseFolderSharesMutation(ctx context.Context, req *dialect.Request, requireManage bool) (string, *folderModel, []contract.ResourceAccessGrantInput, *dialect.Response) {
	folderID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return "", nil, nil, resp
	}
	var body folderSharesMutationRequest
	if err := json.Unmarshal(req.Body, &body); err != nil || body.Shares == nil {
		if err == nil {
			err = errors.New("shares is required")
		}
		return "", nil, nil, folderErrorResponse(req, newFolderRouteError(folderErrInvalidRequest, err.Error(), err))
	}
	var folder *folderModel
	if requireManage {
		var err error
		folder, err = rt.authorizeFolderManage(ctx, folderID, req.User)
		if err != nil {
			return "", nil, nil, folderErrorResponse(req, err)
		}
		if err := rt.requireFolderManageCapability(ctx, req.User, folder.Type); err != nil {
			return "", nil, nil, folderErrorResponse(req, err)
		}
	}
	shares := make([]contract.ResourceAccessGrantInput, 0, len(body.Shares))
	for _, share := range body.Shares {
		normalized, err := normalizeFolderShareInput(share)
		if err != nil {
			return "", nil, nil, folderErrorResponse(req, err)
		}
		shares = append(shares, normalized)
	}
	return folderID, folder, shares, nil
}

func folderErrorResponse(req *dialect.Request, err error) *dialect.Response {
	if err == nil {
		return nil
	}
	var folderErr *folderRouteError
	if errors.As(err, &folderErr) {
		switch folderErr.kind {
		case folderErrInvalidField:
			return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidField, folderErr.Error())}
		case folderErrInvalidRequest:
			return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidRequest, folderErr.Error())}
		case folderErrRequiredFieldMissing:
			return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeRequiredFieldMissing, folderErr.Error())}
		case folderErrForbidden:
			return &dialect.Response{Status: http.StatusForbidden, Body: wire.SFErrorResponse(wire.SFCodeForbidden, folderErr.Error())}
		case folderErrInsufficientAccess:
			return &dialect.Response{Status: http.StatusForbidden, Body: wire.SFErrorResponse(folderCodeInsufficientAccess, folderErr.Error())}
		case folderErrNotFound:
			return &dialect.Response{Status: http.StatusNotFound, Body: wire.SFErrorResponse(wire.SFCodeNotFound, folderErr.Error())}
		case folderErrShareSyncFailed:
			return folderInternalErrorResponseWithLog("share sync failed", folderErr)
		case folderErrInternal:
			return folderInternalErrorResponseWithLog("internal route error", folderErr)
		}
	}
	if resp := respondServiceError(req, err); resp != nil {
		if resp.Status >= http.StatusInternalServerError {
			return folderInternalErrorResponseWithLog("service error", err)
		}
		return resp
	}
	if fields, message, ok := sharederrors.FieldWriteDeniedDetails(err); ok {
		return &dialect.Response{
			Status: http.StatusBadRequest,
			Body:   wire.SFErrorWithFields(wire.SFCodeInvalidFieldForInsertUpdate, message, fields...),
		}
	}
	if message, ok := sharederrors.ValidationRuleMessage(err); ok {
		return &dialect.Response{
			Status: http.StatusBadRequest,
			Body:   wire.SFErrorResponse(wire.SFCodeFieldCustomValidationException, message),
		}
	}
	if resp := validationErrorMaybe(err, wire.SFCodeInvalidField); resp != nil {
		return resp
	}
	return folderInternalErrorResponseWithLog("unclassified error", err)
}

func newFolderRouteError(kind folderRouteErrorKind, message string, cause error) *folderRouteError {
	return &folderRouteError{kind: kind, message: message, cause: cause}
}

func folderInternalErrorResponse() *dialect.Response {
	return &dialect.Response{Status: http.StatusInternalServerError, Body: wire.SFErrorResponse(wire.SFCodeInternalError, folderGenericInternalError)}
}

func folderInternalErrorResponseWithLog(context string, err error) *dialect.Response {
	logFolderInternalError(context, err)
	return folderInternalErrorResponse()
}

func logFolderInternalError(context string, err error) {
	if err == nil {
		log.Printf("folders: %s", context)
		return
	}
	if cause := errors.Unwrap(err); cause != nil {
		log.Printf("folders: %s: %v: %v", context, err, cause)
		return
	}
	log.Printf("folders: %s: %v", context, err)
}

func folderInvalidFieldResponse(message string) *dialect.Response {
	return &dialect.Response{Status: http.StatusBadRequest, Body: wire.SFErrorResponse(wire.SFCodeInvalidField, message)}
}

func folderIDParam(req *dialect.Request, key string, message string) (string, *dialect.Response) {
	id := strings.TrimSpace(req.Params[key])
	if !validateFolderID(id) {
		return "", folderInvalidFieldResponse(message)
	}
	return id, nil
}

func folderAndShareIDParams(req *dialect.Request) (string, string, *dialect.Response) {
	folderID, resp := folderIDParam(req, "id", "Invalid folder ID format")
	if resp != nil {
		return "", "", resp
	}
	shareID, resp := folderIDParam(req, "shareId", "Invalid share ID format")
	if resp != nil {
		return "", "", resp
	}
	return folderID, shareID, nil
}

func validateFolderID(id string) bool {
	if len(id) == 0 || len(id) > 255 {
		return false
	}
	for _, c := range id {
		if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_') {
			return false
		}
	}
	return true
}

func normalizeFolderEnum(input string, mapping map[string]string, fallback string) string {
	if value, ok := mapping[strings.ToLower(input)]; ok {
		return value
	}
	return fallback
}

func normalizeFolderType(input string) string {
	return normalizeFolderEnum(input, map[string]string{
		"dashboard": "Dashboard",
		"report":    "Report",
	}, "Report")
}

func normalizeFolderAccessType(input string) string {
	return normalizeFolderEnum(input, map[string]string{
		"hidden": "Hidden",
		"public": "Public",
		"shared": "Shared",
	}, "Hidden")
}

func normalizeFolderSharedToType(input string) string {
	return normalizeFolderEnum(input, map[string]string{
		"user":                "User",
		"group":               "Group",
		"role":                "Role",
		"roleandsubordinates": "RoleAndSubordinates",
		"organization":        "Organization",
	}, "User")
}

func normalizeFolderAccessLevel(input string) string {
	return normalizeFolderEnum(input, map[string]string{
		"manage": "Manage",
		"view":   "View",
	}, "View")
}

func normalizeFolderShareInput(input folderShareMutationRequest) (contract.ResourceAccessGrantInput, error) {
	sharedToType := normalizeFolderSharedToType(input.SharedToType)
	sharedToID := strings.TrimSpace(input.SharedToID)
	if sharedToID == "" || (sharedToType != "Organization" && !validateFolderID(sharedToID)) {
		return contract.ResourceAccessGrantInput{}, newFolderRouteError(folderErrInvalidField, "Invalid sharedToId format", nil)
	}
	if isFolderOrganizationShare(sharedToType, sharedToID) {
		return contract.ResourceAccessGrantInput{}, folderOrganizationShareMutationError()
	}
	return contract.ResourceAccessGrantInput{
		PrincipalID:   sharedToID,
		PrincipalType: sharedToType,
		AccessLevel:   normalizeFolderAccessLevel(input.AccessLevel),
	}, nil
}

func folderOrganizationViewGrantInput() contract.ResourceAccessGrantInput {
	return contract.ResourceAccessGrantInput{
		PrincipalID:   "ALL_INTERNAL",
		PrincipalType: "Organization",
		AccessLevel:   "View",
	}
}

func appendDerivedFolderOrganizationShare(folder *folderModel, shares []contract.ResourceAccessGrantInput) []contract.ResourceAccessGrantInput {
	if folder == nil || folder.AccessType != "Public" {
		return shares
	}
	return append(shares, folderOrganizationViewGrantInput())
}

func isFolderOrganizationShare(sharedToType string, sharedToID string) bool {
	return strings.EqualFold(strings.TrimSpace(sharedToType), "Organization") ||
		strings.EqualFold(strings.TrimSpace(sharedToID), "ALL_INTERNAL") ||
		strings.EqualFold(strings.TrimSpace(sharedToID), "AllUsers")
}

func folderOrganizationShareMutationError() *folderRouteError {
	return newFolderRouteError(folderErrInvalidRequest, "Organization folder shares are managed through folder accessType", nil)
}

func filterFoldersByGroup(folders []folderModel, filterGroup string) []folderModel {
	if filterGroup != "Dashboards" && filterGroup != "Reports" {
		return folders
	}
	folderType := "Report"
	if filterGroup == "Dashboards" {
		folderType = "Dashboard"
	}
	filtered := folders[:0]
	for _, folder := range folders {
		if folder.RawType == folderType {
			filtered = append(filtered, folder)
		}
	}
	return filtered
}

func filterVisibleFolders(folders []folderModel, visibleIDs []string) []folderModel {
	visible := make(map[string]struct{}, len(visibleIDs))
	for _, id := range visibleIDs {
		visible[id] = struct{}{}
	}
	filtered := folders[:0]
	for _, folder := range folders {
		if _, ok := visible[folder.ID]; ok {
			filtered = append(filtered, folder)
		}
	}
	return filtered
}

func parseFolderPagination(req *dialect.Request) (page, pageSize int) {
	page = 0
	pageSize = folderDefaultPageSize
	if raw := queryValue(req, "page"); raw != "" {
		if parsed, err := strconv.Atoi(raw); err == nil && parsed >= 0 {
			page = parsed
		}
	}
	if raw := queryValue(req, "pageSize"); raw != "" {
		if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 {
			pageSize = parsed
			if pageSize > folderMaxPageSize {
				pageSize = folderMaxPageSize
			}
		}
	}
	return page, pageSize
}

func paginateFolders(folders []folderModel, page, pageSize int) ([]folderModel, bool) {
	start := page * pageSize
	if start >= len(folders) {
		return []folderModel{}, false
	}
	end := start + pageSize
	hasNextPage := false
	if end > len(folders) {
		end = len(folders)
	} else {
		hasNextPage = true
	}
	return folders[start:end], hasNextPage
}

func folderPageURL(req *dialect.Request, path string, page, pageSize int, filterGroup string) string {
	base := fmt.Sprintf("/services/data/%s%s?page=%d&pageSize=%d", apiVersionOrDefault(req.Version), path, page, pageSize)
	if filterGroup != "" {
		base += "&filterGroup=" + url.QueryEscape(filterGroup)
	}
	return base
}

func folderFromRecord(record contract.Record) *folderModel {
	rawFolderType := folderRecordString(record, constants.FieldReportFolder_Type)
	folderType := rawFolderType
	if folderType == "" {
		folderType = "Report"
	}
	accessType := folderRecordString(record, constants.FieldReportFolder_AccessType)
	if accessType == "" {
		accessType = "Hidden"
	}
	return &folderModel{
		ID:               folderRecordString(record, constants.FieldReportFolder_ID),
		Name:             folderRecordString(record, constants.FieldReportFolder_Name),
		DeveloperName:    folderRecordString(record, constants.FieldReportFolder_DeveloperName),
		Description:      folderRecordString(record, constants.FieldReportFolder_Description),
		RawType:          rawFolderType,
		Type:             folderType,
		AccessType:       accessType,
		ParentFolderID:   folderRecordString(record, constants.FieldReportFolder_ParentID),
		OwnerID:          folderRecordString(record, constants.FieldReportFolder_OwnerID),
		CreatedByID:      folderRecordString(record, constants.FieldReportFolder_CreatedByID),
		CreatedDate:      folderRecordString(record, constants.FieldReportFolder_CreatedDate),
		LastModifiedDate: folderRecordString(record, constants.FieldReportFolder_LastModifiedDate),
	}
}

func folderShareFromGrant(grant contract.ResourceAccessGrant) folderShareModel {
	return folderShareModel{
		ID:           grant.ID,
		FolderID:     grant.ResourceID,
		SharedToID:   grant.PrincipalID,
		SharedToType: grant.PrincipalType,
		AccessLevel:  grant.AccessLevel,
	}
}

func folderRecordString(record contract.Record, key string) string {
	if record == nil {
		return ""
	}
	if value, ok := record[key].(string); ok {
		return value
	}
	return ""
}

func folderResponseFromModel(folder *folderModel) folderResponse {
	if folder == nil {
		return folderResponse{}
	}
	return folderResponse{
		ID:               folder.ID,
		Name:             folder.Name,
		Label:            folder.Name,
		DeveloperName:    folder.DeveloperName,
		Description:      folder.Description,
		Type:             folder.Type,
		AccessType:       folder.AccessType,
		ParentFolderID:   folder.ParentFolderID,
		CreatedDate:      folder.CreatedDate,
		LastModifiedDate: folder.LastModifiedDate,
	}
}

func folderResponses(folders []folderModel) []folderResponse {
	out := make([]folderResponse, 0, len(folders))
	for i := range folders {
		out = append(out, folderResponseFromModel(&folders[i]))
	}
	return out
}

func folderShareResponseFromModel(req *dialect.Request, folderID string, share *folderShareModel) folderShareResponse {
	if share == nil {
		return folderShareResponse{}
	}
	return folderShareResponse{
		ShareID:         share.ID,
		AccessType:      share.AccessLevel,
		ShareType:       share.SharedToType,
		SharedWithID:    share.SharedToID,
		SharedWithLabel: folderShareLabelForResponse(share),
		URL:             folderShareURL(req, folderID, share.ID),
	}
}

func folderShareResponses(req *dialect.Request, folderID string, shares []folderShareModel) []folderShareResponse {
	out := make([]folderShareResponse, 0, len(shares))
	for i := range shares {
		out = append(out, folderShareResponseFromModel(req, folderID, &shares[i]))
	}
	sort.Slice(out, func(i, j int) bool {
		return out[i].ShareID < out[j].ShareID
	})
	return out
}

func (rt *folderRouteDeps) folderShareResponsesFromGrants(ctx context.Context, req *dialect.Request, folderID string, grants []contract.ResourceAccessGrant) []folderShareResponse {
	shares := make([]folderShareModel, 0, len(grants))
	for _, grant := range grants {
		shares = append(shares, folderShareFromGrant(grant))
	}
	if err := rt.populateFolderShareLabels(ctx, shares, req.User); err != nil {
		logFolderInternalError("folder share mutation label hydration failed", err)
	}
	return folderShareResponses(req, folderID, shares)
}

func (rt *folderRouteDeps) populateFolderShareLabels(ctx context.Context, shares []folderShareModel, user *models.UserSession) error {
	if len(shares) == 0 {
		return nil
	}
	type principalKey struct {
		objectName string
		id         string
	}
	indicesByPrincipal := make(map[principalKey][]int)
	idsByObject := make(map[string][]string)
	seenByObject := make(map[string]map[string]struct{})
	for i := range shares {
		if label, ok := folderShareOrganizationLabel(&shares[i]); ok {
			shares[i].SharedWithLabel = label
			continue
		}
		objectName, ok := folderSharePrincipalObject(shares[i].SharedToType)
		if !ok || !validateFolderID(shares[i].SharedToID) {
			continue
		}
		key := principalKey{objectName: objectName, id: shares[i].SharedToID}
		indicesByPrincipal[key] = append(indicesByPrincipal[key], i)
		if seenByObject[objectName] == nil {
			seenByObject[objectName] = make(map[string]struct{})
		}
		if _, seen := seenByObject[objectName][shares[i].SharedToID]; seen {
			continue
		}
		seenByObject[objectName][shares[i].SharedToID] = struct{}{}
		idsByObject[objectName] = append(idsByObject[objectName], shares[i].SharedToID)
	}
	labelCtx := constants.WithSecurityContext(ctx, constants.SystemContext, "folders: resolve folder share principal labels")
	for objectName, ids := range idsByObject {
		for start := 0; start < len(ids); start += folderQueryLimit {
			end := start + folderQueryLimit
			if end > len(ids) {
				end = len(ids)
			}
			chunk := ids[start:end]
			records, err := rt.query.Query(labelCtx, queryspec.QuerySpec{
				ObjectAPIName: objectName,
				SelectFields:  folderSharePrincipalLabelFields(objectName),
				Filter:        folderIDInPredicate(chunk),
				Limit:         len(chunk),
			}, user)
			if err != nil {
				return err
			}
			if records == nil {
				continue
			}
			for _, record := range records.Records {
				id := folderRecordString(record, constants.FieldID)
				if id == "" {
					continue
				}
				label := folderSharePrincipalLabel(objectName, record)
				if label == "" {
					continue
				}
				for _, index := range indicesByPrincipal[principalKey{objectName: objectName, id: id}] {
					shares[index].SharedWithLabel = label
				}
			}
		}
	}
	return nil
}

func folderSharePrincipalLabelFields(objectName string) []string {
	switch objectName {
	case constants.TableUser:
		return []string{constants.FieldID, constants.FieldUsername, constants.FieldFirstName, constants.FieldLastName}
	case constants.TableUserRole:
		return []string{constants.FieldID, constants.FieldUserRole_Name}
	case constants.TableGroup:
		return []string{constants.FieldID, constants.FieldGroup_Label, constants.FieldGroup_Name, constants.FieldGroup_DeveloperName}
	default:
		return []string{constants.FieldID, constants.FieldName}
	}
}

func folderSharePrincipalLabel(objectName string, record contract.Record) string {
	switch objectName {
	case constants.TableUser:
		return constructDisplayName(
			folderRecordString(record, constants.FieldUsername),
			folderRecordString(record, constants.FieldFirstName),
			folderRecordString(record, constants.FieldLastName),
		)
	case constants.TableUserRole:
		return folderRecordString(record, constants.FieldUserRole_Name)
	case constants.TableGroup:
		if label := folderRecordString(record, constants.FieldGroup_Label); label != "" {
			return label
		}
		if name := folderRecordString(record, constants.FieldGroup_Name); name != "" {
			return name
		}
		return folderRecordString(record, constants.FieldGroup_DeveloperName)
	default:
		return folderRecordString(record, constants.FieldName)
	}
}

func folderSharePrincipalObject(sharedToType string) (string, bool) {
	switch strings.ToLower(strings.TrimSpace(sharedToType)) {
	case "user":
		return constants.TableUser, true
	case "role", "roleandsubordinates":
		return constants.TableUserRole, true
	case "group":
		return constants.TableGroup, true
	default:
		return "", false
	}
}

func folderShareOrganizationLabel(share *folderShareModel) (string, bool) {
	if share == nil {
		return "", false
	}
	if strings.EqualFold(strings.TrimSpace(share.SharedToType), "Organization") ||
		strings.EqualFold(strings.TrimSpace(share.SharedToID), "ALL_INTERNAL") ||
		strings.EqualFold(strings.TrimSpace(share.SharedToID), "AllUsers") {
		return "All Internal Users", true
	}
	return "", false
}

func folderShareLabelForResponse(share *folderShareModel) string {
	if share == nil {
		return ""
	}
	if share.SharedWithLabel != "" {
		return share.SharedWithLabel
	}
	if label, ok := folderShareOrganizationLabel(share); ok {
		return label
	}
	switch strings.ToLower(strings.TrimSpace(share.SharedToType)) {
	case "user":
		return "Unknown User"
	case "role", "roleandsubordinates":
		return "Unknown Role"
	case "group":
		return "Unknown Group"
	default:
		return "Unknown Share Target"
	}
}

func folderIDInPredicate(ids []string) queryspec.Predicate {
	values := make([]queryspec.Operand, 0, len(ids))
	for _, id := range ids {
		if !validateFolderID(id) {
			continue
		}
		values = append(values, queryspec.LiteralOperand(id))
	}
	if len(values) == 0 {
		return queryspec.FieldPredicate(constants.FieldID, "=", "__none__")
	}
	return queryspec.ComparisonPredicate(
		queryspec.FieldOperand(constants.FieldID),
		"in",
		queryspec.ListOperand(values...),
	)
}

func folderShareURL(req *dialect.Request, folderID string, shareID string) string {
	return fmt.Sprintf("/services/data/%s/folders/%s/shares/%s", apiVersionOrDefault(req.Version), url.PathEscape(folderID), url.PathEscape(shareID))
}

func folderNotFoundMessage(folderID string) string {
	return fmt.Sprintf("Folder %s not found or access denied", folderID)
}
