// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
//
// SPDX-License-Identifier: AGPL-3.0-or-later

package lunatask

import (
	"errors"
	"fmt"
	"strings"
)

// Errors returned by deep link operations.
var (
	// ErrInvalidDeepLink is returned when parsing a malformed deep link.
	ErrInvalidDeepLink = errors.New("invalid deep link")
	// ErrInvalidResource is returned when a resource type is unknown.
	ErrInvalidResource = errors.New("invalid resource")
	// ErrInvalidUUID is returned when the UUID portion is empty.
	ErrInvalidUUID = errors.New("invalid UUID")
)

// Resource represents a Lunatask resource type for deep links.
type Resource string

// Valid resource types for deep links.
const (
	ResourceArea     Resource = "areas"
	ResourceGoal     Resource = "goals"
	ResourceTask     Resource = "tasks"
	ResourceNote     Resource = "notes"
	ResourcePerson   Resource = "people"
	ResourceNotebook Resource = "notebooks"
)

// ParseDeepLink extracts resource type and UUID from a Lunatask deep link
// or plain UUID. Accepts "lunatask://tasks/uuid" or plain UUID strings.
// When a plain UUID is provided, the resource type will be empty.
func ParseDeepLink(input string) (Resource, string, error) {
	if input == "" {
		return "", "", fmt.Errorf("%w: empty input", ErrInvalidDeepLink)
	}

	// Check for lunatask:// prefix
	const prefix = "lunatask://"
	if !strings.HasPrefix(input, prefix) {
		// Treat as plain UUID
		return "", input, nil
	}

	// Remove prefix and split
	remainder := strings.TrimPrefix(input, prefix)
	parts := strings.SplitN(remainder, "/", 2) //nolint:mnd // split resource/uuid

	if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
		return "", "", fmt.Errorf("%w: %q", ErrInvalidDeepLink, input)
	}

	resource := Resource(parts[0])
	uuid := parts[1]

	// Validate resource type
	switch resource {
	case ResourceArea, ResourceGoal, ResourceTask, ResourceNote, ResourcePerson, ResourceNotebook:
		// valid
	default:
		return "", "", fmt.Errorf("%w: %q", ErrInvalidResource, resource)
	}

	return resource, uuid, nil
}

// BuildDeepLink constructs a Lunatask deep link from resource type and ID.
// Returns "lunatask://resource/uuid".
func BuildDeepLink(resource Resource, id string) (string, error) {
	if id == "" {
		return "", ErrInvalidUUID
	}

	// Validate resource type
	switch resource {
	case ResourceArea, ResourceGoal, ResourceTask, ResourceNote, ResourcePerson, ResourceNotebook:
		// valid
	default:
		return "", fmt.Errorf("%w: %q", ErrInvalidResource, resource)
	}

	return fmt.Sprintf("lunatask://%s/%s", resource, id), nil
}
