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

// Package stats provides helpers for computing task statistics.
package stats

import (
	"context"
	"fmt"

	"git.secluded.site/go-lunatask"
	"git.secluded.site/lune/internal/ui"
)

// TaskCounter provides methods to count tasks by various criteria.
type TaskCounter struct {
	client *lunatask.Client
	tasks  []lunatask.Task
}

// NewTaskCounter creates a counter that fetches tasks on first use.
func NewTaskCounter(client *lunatask.Client) *TaskCounter {
	return &TaskCounter{client: client}
}

// UncompletedInArea counts uncompleted tasks in the specified area.
func (tc *TaskCounter) UncompletedInArea(ctx context.Context, areaID string) (int, error) {
	if err := tc.ensureTasks(ctx); err != nil {
		return 0, err
	}

	count := 0

	for _, task := range tc.tasks {
		if !isUncompleted(task) {
			continue
		}

		if task.AreaID != nil && *task.AreaID == areaID {
			count++
		}
	}

	return count, nil
}

// UncompletedInGoal counts uncompleted tasks in the specified goal.
func (tc *TaskCounter) UncompletedInGoal(ctx context.Context, goalID string) (int, error) {
	if err := tc.ensureTasks(ctx); err != nil {
		return 0, err
	}

	count := 0

	for _, task := range tc.tasks {
		if !isUncompleted(task) {
			continue
		}

		if task.GoalID != nil && *task.GoalID == goalID {
			count++
		}
	}

	return count, nil
}

// ensureTasks fetches tasks if not already loaded.
func (tc *TaskCounter) ensureTasks(ctx context.Context) error {
	if tc.tasks != nil {
		return nil
	}

	tasks, err := ui.Spin("Fetching tasks…", func() ([]lunatask.Task, error) {
		return tc.client.ListTasks(ctx, nil)
	})
	if err != nil {
		return fmt.Errorf("listing tasks: %w", err)
	}

	tc.tasks = tasks

	return nil
}

func isUncompleted(task lunatask.Task) bool {
	if task.Status == nil {
		return true
	}

	return *task.Status != lunatask.StatusCompleted
}
