package taskboard

import (
	"context"
	"fmt"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/coredb"
)

// GetReadableTaskScope is the narrow read gate for Task-adjacent resources
// that need the canonical task_scope_id but not the expensive detail graph.
// It deliberately uses the same source-channel authorization helper as Task
// detail and returns the same not-found/forbidden errors.
func (txs TxStore) GetReadableTaskScope(ctx context.Context, request GetReadableTaskScopeRequest) (GetReadableTaskScopeResponse, error) {
	workspaceID, err := request.Context.requireWorkspaceID()
	if err != nil {
		return GetReadableTaskScopeResponse{}, err
	}
	userID, _, err := request.Context.requireUser()
	if err != nil {
		return GetReadableTaskScopeResponse{}, err
	}
	taskID := strings.TrimSpace(request.Task.TaskID)
	if taskID == "" {
		return GetReadableTaskScopeResponse{}, badRequest("task id is required")
	}

	var taskScopeID string
	var channelID string
	if err := txs.db.QueryRow(ctx, `
SELECT task.task_scope_id, board.channel_id
FROM tasks task
JOIN task_boards board
  ON board.id = task.board_id
 AND board.workspace_id = $1
JOIN scopes task_scope
  ON task_scope.id = task.task_scope_id
 AND task_scope.workspace_id = $1
 AND task_scope.type = 'task'
 AND task_scope.status = 'active'
 AND task_scope.archived_at IS NULL
JOIN scopes board_channel
  ON board_channel.id = board.channel_id
 AND board_channel.workspace_id = $1
 AND board_channel.type = 'channel'
 AND board_channel.status = 'active'
 AND board_channel.archived_at IS NULL
WHERE task.channel_id = board.channel_id
  AND task.id = $2
LIMIT 1
`, workspaceID, taskID).Scan(&taskScopeID, &channelID); err != nil {
		if coredb.IsNotFound(err) {
			return GetReadableTaskScopeResponse{}, ErrNotFound
		}
		return GetReadableTaskScopeResponse{}, fmt.Errorf("load readable task scope: %w", err)
	}
	if _, err := txs.loadAuthorizedUserTaskChannelAccess(ctx, txs.db, userID, workspaceID, channelID, taskReadChannelAction); err != nil {
		return GetReadableTaskScopeResponse{}, err
	}
	taskScopeID = strings.TrimSpace(taskScopeID)
	if taskScopeID == "" {
		return GetReadableTaskScopeResponse{}, ErrNotFound
	}
	return GetReadableTaskScopeResponse{
		TaskID:      taskID,
		TaskScopeID: taskScopeID,
	}, nil
}

// GetReadableTaskScope avoids opening a transaction because it performs only
// a narrow authorization read and does not need a multi-query detail snapshot.
func (store *Store) GetReadableTaskScope(ctx context.Context, request GetReadableTaskScopeRequest) (GetReadableTaskScopeResponse, error) {
	return (TxStore{db: store.db}).GetReadableTaskScope(ctx, request)
}
