package task

import (
	"context"
	"fmt"

	"github.com/tidbcloud/AgentTeam/internal/store/identity"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
)

type taskParityMessageStore interface {
	SendMessageForUserWithMetadata(ctx context.Context, user identity.User, workspaceID string, scopeID string, content string, attachmentIDs []string, metadata map[string]any) (message.AppMessage, message.MessageDelivery, error)
}

type taskParityNotificationStore interface {
	GetChannelNotificationPanelForUser(ctx context.Context, userID string, workspaceID string, channelID string, agentCursor string, agentLimit int) (message.ScopeNotificationPanel, error)
	SetChannelNotificationSelfStateForUser(ctx context.Context, userID string, workspaceID string, channelID string, state string) (message.ScopeNotificationPanel, error)
	SetChannelNotificationAgentWakeStateForUser(ctx context.Context, userID string, workspaceID string, channelID string, agentID string, state string) (message.ScopeNotificationPanel, error)

	GetThreadNotificationPanelForUser(ctx context.Context, userID string, workspaceID string, threadChannelID string, agentCursor string, agentLimit int) (message.ScopeNotificationPanel, error)
	SetThreadNotificationSelfStateForUser(ctx context.Context, userID string, workspaceID string, threadChannelID string, state string) (message.ScopeNotificationPanel, error)
	SetThreadNotificationAgentWakeStateForUser(ctx context.Context, userID string, workspaceID string, threadChannelID string, agentID string, state string) (message.ScopeNotificationPanel, error)

	GetTaskNotificationPanelForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string) (message.ScopeNotificationPanel, error)
	SetTaskNotificationSelfStateForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, state string) (message.ScopeNotificationPanel, error)
	SetTaskNotificationAgentWakeStateForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, agentID string, state string) (message.ScopeNotificationPanel, error)
	SetNotificationAgentsWakeStateForUser(ctx context.Context, userID, workspaceID, scopeType, scopeID, state string) (message.ScopeNotificationPanel, error)
	GetTaskWatchersForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, cursor string, limit int) (message.TaskWatcherPage, error)

	RequireTaskActiveTargetAgentForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, agentID string) error
	SetTaskActiveTargetForUser(ctx context.Context, userID string, workspaceID string, target message.TaskActiveTargetRecord) (message.TaskActiveTargetRecord, error)
	ListTaskActiveTargetsForUser(ctx context.Context, userID string, workspaceID string, taskIDs []string) ([]message.TaskActiveTargetRecord, error)
	ClearTaskActiveTargetForUser(ctx context.Context, userID string, workspaceID string, scope string, targetKey string) error
}

type taskParityStoreAdapter struct {
	messages      taskParityMessageStore
	notifications taskParityNotificationStore
}

// NewTaskParityStoreAdapter composes the task parity API store port from the
// app message surface and channel/thread notification plus active-target surface.
func NewTaskParityStoreAdapter(messages taskParityMessageStore, notifications taskParityNotificationStore) TaskParityStore {
	return taskParityStoreAdapter{messages: messages, notifications: notifications}
}

func (adapter taskParityStoreAdapter) SendMessageForUserWithMetadata(ctx context.Context, user identity.User, workspaceID string, scopeID string, content string, attachmentIDs []string, metadata map[string]any) (message.AppMessage, message.MessageDelivery, error) {
	if adapter.messages == nil {
		return message.AppMessage{}, message.MessageDelivery{}, fmt.Errorf("task parity message store is not configured")
	}
	return adapter.messages.SendMessageForUserWithMetadata(ctx, user, workspaceID, scopeID, content, attachmentIDs, metadata)
}

func (adapter taskParityStoreAdapter) GetChannelNotificationPanelForUser(ctx context.Context, userID string, workspaceID string, channelID string, agentCursor string, agentLimit int) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.GetChannelNotificationPanelForUser(ctx, userID, workspaceID, channelID, agentCursor, agentLimit)
}

func (adapter taskParityStoreAdapter) SetChannelNotificationSelfStateForUser(ctx context.Context, userID string, workspaceID string, channelID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetChannelNotificationSelfStateForUser(ctx, userID, workspaceID, channelID, state)
}

func (adapter taskParityStoreAdapter) SetChannelNotificationAgentWakeStateForUser(ctx context.Context, userID string, workspaceID string, channelID string, agentID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetChannelNotificationAgentWakeStateForUser(ctx, userID, workspaceID, channelID, agentID, state)
}

func (adapter taskParityStoreAdapter) GetThreadNotificationPanelForUser(ctx context.Context, userID string, workspaceID string, threadChannelID string, agentCursor string, agentLimit int) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.GetThreadNotificationPanelForUser(ctx, userID, workspaceID, threadChannelID, agentCursor, agentLimit)
}

func (adapter taskParityStoreAdapter) SetThreadNotificationSelfStateForUser(ctx context.Context, userID string, workspaceID string, threadChannelID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetThreadNotificationSelfStateForUser(ctx, userID, workspaceID, threadChannelID, state)
}

func (adapter taskParityStoreAdapter) SetThreadNotificationAgentWakeStateForUser(ctx context.Context, userID string, workspaceID string, threadChannelID string, agentID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetThreadNotificationAgentWakeStateForUser(ctx, userID, workspaceID, threadChannelID, agentID, state)
}

func (adapter taskParityStoreAdapter) GetTaskNotificationPanelForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.GetTaskNotificationPanelForUser(ctx, userID, workspaceID, taskScopeID)
}

func (adapter taskParityStoreAdapter) SetTaskNotificationSelfStateForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetTaskNotificationSelfStateForUser(ctx, userID, workspaceID, taskScopeID, state)
}

func (adapter taskParityStoreAdapter) SetTaskNotificationAgentWakeStateForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, agentID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetTaskNotificationAgentWakeStateForUser(ctx, userID, workspaceID, taskScopeID, agentID, state)
}

func (adapter taskParityStoreAdapter) SetTaskNotificationAgentsWakeStateForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, state string) (message.ScopeNotificationPanel, error) {
	if adapter.notifications == nil {
		return message.ScopeNotificationPanel{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.SetNotificationAgentsWakeStateForUser(ctx, userID, workspaceID, "task", taskScopeID, state)
}

func (adapter taskParityStoreAdapter) GetTaskWatchersForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, cursor string, limit int) (message.TaskWatcherPage, error) {
	if adapter.notifications == nil {
		return message.TaskWatcherPage{}, fmt.Errorf("task parity notification store is not configured")
	}
	return adapter.notifications.GetTaskWatchersForUser(ctx, userID, workspaceID, taskScopeID, cursor, limit)
}

func (adapter taskParityStoreAdapter) RequireTaskActiveTargetAgentForUser(ctx context.Context, userID string, workspaceID string, taskScopeID string, agentID string) error {
	if adapter.notifications == nil {
		return fmt.Errorf("task parity active target store is not configured")
	}
	return adapter.notifications.RequireTaskActiveTargetAgentForUser(ctx, userID, workspaceID, taskScopeID, agentID)
}

func (adapter taskParityStoreAdapter) SetTaskActiveTargetForUser(ctx context.Context, userID string, workspaceID string, target message.TaskActiveTargetRecord) (message.TaskActiveTargetRecord, error) {
	if adapter.notifications == nil {
		return message.TaskActiveTargetRecord{}, fmt.Errorf("task parity active target store is not configured")
	}
	return adapter.notifications.SetTaskActiveTargetForUser(ctx, userID, workspaceID, target)
}

func (adapter taskParityStoreAdapter) ListTaskActiveTargetsForUser(ctx context.Context, userID string, workspaceID string, taskIDs []string) ([]message.TaskActiveTargetRecord, error) {
	if adapter.notifications == nil {
		return nil, fmt.Errorf("task parity active target store is not configured")
	}
	return adapter.notifications.ListTaskActiveTargetsForUser(ctx, userID, workspaceID, taskIDs)
}

func (adapter taskParityStoreAdapter) ClearTaskActiveTargetForUser(ctx context.Context, userID string, workspaceID string, scope string, targetKey string) error {
	if adapter.notifications == nil {
		return fmt.Errorf("task parity active target store is not configured")
	}
	return adapter.notifications.ClearTaskActiveTargetForUser(ctx, userID, workspaceID, scope, targetKey)
}
