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

// Package deeplink parses and builds Lunatask deep links.
package deeplink

import (
	"errors"
	"fmt"
	"strings"

	"github.com/google/uuid"
)

// Resource represents a Lunatask resource type that supports deep linking.
type Resource string

// Supported Lunatask resource types for deep linking.
const (
	Area     Resource = "areas"
	Goal     Resource = "goals"
	Task     Resource = "tasks"
	Note     Resource = "notes"
	Person   Resource = "people"
	Notebook Resource = "notebooks"
)

const (
	scheme            = "lunatask://"
	deepLinkPartCount = 2
)

// ErrInvalidReference indicates the input is neither a valid UUID nor deep link.
var ErrInvalidReference = errors.New("invalid reference: expected UUID or lunatask:// deep link")

// ErrUnsupportedResource indicates the deep link resource type is not recognised.
var ErrUnsupportedResource = errors.New("unsupported resource type in deep link")

// ParseID extracts a UUID from either a raw UUID string or a Lunatask deep link.
// Accepts formats:
//   - UUID: "3bbf1923-64ae-4bcf-96a9-9bb86c799dab"
//   - Deep link: "lunatask://areas/3bbf1923-64ae-4bcf-96a9-9bb86c799dab"
func ParseID(input string) (string, error) {
	input = strings.TrimSpace(input)

	// Try parsing as UUID first
	if parsed, err := uuid.Parse(input); err == nil {
		return parsed.String(), nil
	}

	// Try parsing as deep link
	if !strings.HasPrefix(input, scheme) {
		return "", fmt.Errorf("%w: %s", ErrInvalidReference, input)
	}

	path := strings.TrimPrefix(input, scheme)
	parts := strings.Split(path, "/")

	if len(parts) != deepLinkPartCount {
		return "", fmt.Errorf("%w: %s", ErrInvalidReference, input)
	}

	resource := parts[0]
	id := parts[1]

	// Validate resource type
	switch Resource(resource) {
	case Area, Goal, Task, Note, Person, Notebook:
		// Valid resource
	default:
		return "", fmt.Errorf("%w: %s", ErrUnsupportedResource, resource)
	}

	// Validate and normalise the UUID
	parsed, err := uuid.Parse(id)
	if err != nil {
		return "", fmt.Errorf("%w: %s", ErrInvalidReference, input)
	}

	return parsed.String(), nil
}

// Build constructs a Lunatask deep link for the given resource and ID.
func Build(resource Resource, id string) (string, error) {
	parsed, err := uuid.Parse(id)
	if err != nil {
		return "", fmt.Errorf("%w: %s", ErrInvalidReference, id)
	}

	return fmt.Sprintf("%s%s/%s", scheme, resource, parsed.String()), nil
}
