package drive

import (
	"strings"

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

const maxJSONRequestBody = 32 << 10

type moveRequest struct {
	Source      string `json:"source"`
	Destination string `json:"destination"`
}

type copyRequest struct {
	Source      string `json:"source"`
	Destination string `json:"destination"`
}

type renameRequest struct {
	Path    string `json:"path"`
	NewName string `json:"new_name"`
}

func validateMoveRequest(req *moveRequest) *apivalidate.ValidationError {
	var details []apivalidate.FieldDetail
	if strings.TrimSpace(req.Source) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "source", Message: "required"})
	}
	if strings.TrimSpace(req.Destination) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "destination", Message: "required"})
	}
	if len(details) == 0 {
		return nil
	}
	return apivalidate.NewValidationError(details...)
}

func validateCopyRequest(req *copyRequest) *apivalidate.ValidationError {
	var details []apivalidate.FieldDetail
	if strings.TrimSpace(req.Source) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "source", Message: "required"})
	}
	if strings.TrimSpace(req.Destination) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "destination", Message: "required"})
	}
	if len(details) == 0 {
		return nil
	}
	return apivalidate.NewValidationError(details...)
}

func validateRenameRequest(req *renameRequest) *apivalidate.ValidationError {
	var details []apivalidate.FieldDetail
	if strings.TrimSpace(req.Path) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "path", Message: "required"})
	}
	newName := strings.TrimSpace(req.NewName)
	if newName == "" {
		details = append(details, apivalidate.FieldDetail{Field: "new_name", Message: "required"})
	} else if strings.Contains(newName, "/") {
		details = append(details, apivalidate.FieldDetail{Field: "new_name", Message: "invalid"})
	}
	if len(details) == 0 {
		return nil
	}
	return apivalidate.NewValidationError(details...)
}

type createShareRequest struct {
	Path        string `json:"path"`
	ShareType   int    `json:"share_type"`
	Permissions int    `json:"permissions"`
	Role        string `json:"role"`
	Mode        string `json:"mode"`
	ShareWith   string `json:"share_with"`
	Note        string `json:"note"`
	SendMail    *bool  `json:"send_mail"`
}

func sharePermissionsForRole(role string) (int, bool) {
	switch strings.TrimSpace(strings.ToLower(role)) {
	case "owner":
		return 31, true
	case "editor":
		return 15, true
	case "viewer":
		return 1, true
	default:
		return 0, false
	}
}

func validateCreateShareRequest(req *createShareRequest) *apivalidate.ValidationError {
	var details []apivalidate.FieldDetail
	if strings.TrimSpace(req.Path) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "path", Message: "required"})
	}
	if role := strings.TrimSpace(req.Role); role != "" {
		if _, ok := sharePermissionsForRole(role); !ok {
			details = append(details, apivalidate.FieldDetail{Field: "role", Message: "invalid"})
		}
	}
	mode := strings.TrimSpace(strings.ToLower(req.Mode))
	switch mode {
	case "", "public", "internal":
	case "contact":
		if strings.TrimSpace(req.ShareWith) == "" {
			details = append(details, apivalidate.FieldDetail{Field: "share_with", Message: "required"})
		}
	default:
		details = append(details, apivalidate.FieldDetail{Field: "mode", Message: "invalid"})
	}
	if len(details) == 0 {
		return nil
	}
	return apivalidate.NewValidationError(details...)
}

type restoreTrashRequest struct {
	Name string `json:"name"`
}

func validateRestoreTrashRequest(req *restoreTrashRequest) *apivalidate.ValidationError {
	if strings.TrimSpace(req.Name) == "" {
		return apivalidate.NewValidationError(apivalidate.FieldDetail{
			Field: "name", Message: "required",
		})
	}
	return nil
}

type deleteTrashRequest struct {
	Name string `json:"name"`
}

func validateDeleteTrashRequest(req *deleteTrashRequest) *apivalidate.ValidationError {
	if strings.TrimSpace(req.Name) == "" {
		return apivalidate.NewValidationError(apivalidate.FieldDetail{
			Field: "name", Message: "required",
		})
	}
	return nil
}

type favoriteRequest struct {
	Path     string `json:"path"`
	Favorite bool   `json:"favorite"`
}

func validateFavoriteRequest(req *favoriteRequest) *apivalidate.ValidationError {
	if strings.TrimSpace(req.Path) == "" {
		return apivalidate.NewValidationError(apivalidate.FieldDetail{
			Field: "path", Message: "required",
		})
	}
	return nil
}

type updateShareRequest struct {
	Permissions int    `json:"permissions"`
	Role        string `json:"role"`
	ExpireDate  string `json:"expire_date"`
	Password    string `json:"password"`
}

type newFileRequest struct {
	ParentPath string `json:"parent_path"`
	Name       string `json:"name"`
	Kind       string `json:"kind"`
}

func validateNewFileRequest(req *newFileRequest) *apivalidate.ValidationError {
	var details []apivalidate.FieldDetail
	if strings.TrimSpace(req.Name) == "" {
		details = append(details, apivalidate.FieldDetail{Field: "name", Message: "required"})
	}
	k := strings.TrimSpace(strings.ToLower(req.Kind))
	if k != "document" && k != "spreadsheet" && k != "presentation" {
		details = append(details, apivalidate.FieldDetail{Field: "kind", Message: "invalid"})
	}
	if len(details) > 0 {
		return apivalidate.NewValidationError(details...)
	}
	return nil
}

func validatePath(path string) *apivalidate.ValidationError {
	if strings.TrimSpace(path) == "" {
		return apivalidate.NewValidationError(apivalidate.FieldDetail{
			Field: "path", Message: "required",
		})
	}
	return nil
}
