package app

import (
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/core/domain"
	"github.com/tidbcloud/AgentTeam/internal/coredb"
	"github.com/tidbcloud/AgentTeam/internal/store/access"
	"github.com/tidbcloud/AgentTeam/internal/store/agent"
)

func (store *Store) AgentDetailForWorkspace(ctx context.Context, userID string, workspaceID string, agentID string) (agent.AppAgent, error) {
	if _, err := store.requireAgentOperation(ctx, userID, workspaceID, agentID); err != nil {
		return agent.AppAgent{}, err
	}
	includeRuntimeFailure := false
	return store.agentForWorkspace(ctx, userID, workspaceID, agentID, includeRuntimeFailure)
}

func (store *Store) agentForWorkspace(ctx context.Context, userID string, workspaceID string, agentID string, includeRuntimeFailure bool) (agent.AppAgent, error) {
	workspaceMember, err := store.loadRuntimeWorkspaceMember(ctx, store.db, userID, workspaceID)
	if err != nil {
		return agent.AppAgent{}, err
	}
	canDisableAll := access.HasWorkspaceAdminRole(domain.WorkspaceRole(workspaceMember.WorkspaceRole))

	row := store.db.QueryRow(ctx, `
SELECT a.id, a.name, m.id, m.display_name, a.avatar_url, a.description, a.runtime, a.permission_mode, a.model, a.reasoning_effort,
       a.llm_mode, a.llm_base_url, a.llm_api_key_ciphertext, a.llm_headers_json, a.llm_wire_api, a.machine_id,
       'offline' AS machine_status,
       COALESCE(a.model_profile_id, ''),
       a.source_kind, a.source_ref,
       mac.created_by_user_id,
       FALSE AS can_review_shared,
       a.auto_wake_enabled, 'inactive', 'offline', '',
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
       a.created_at
FROM agents a
JOIN members m ON m.id = a.member_id
JOIN machines mac ON mac.workspace_id = a.workspace_id AND mac.id = a.machine_id
WHERE a.workspace_id = $1 AND a.id = $2
  AND a.status <> 'archived'
  AND mac.status = 'active'
`, workspaceID, agentID)

	var appAgent agent.AppAgent
	var createdByUserID string
	var canReviewShared bool
	var currentInstanceID *string
	var currentInstanceMachineID *string
	var currentInstanceSessionID *string
	var currentInstanceStatus *string
	var currentInstanceActivity *string
	var currentInstanceActivityDetail *string
	var currentInstanceSourceKind *string
	var currentInstanceSourceRef *string
	var currentInstanceStartedAt *time.Time
	var currentInstanceLastSeenAt *time.Time
	var llmMode string
	var baseURL string
	var apiKeyCiphertext string
	var headersJSON []byte
	var wireAPI string
	if err := row.Scan(
		&appAgent.ID,
		&appAgent.Name,
		&appAgent.MemberID,
		&appAgent.DisplayName,
		&appAgent.AvatarURL,
		&appAgent.Description,
		&appAgent.Runtime,
		&appAgent.PermissionMode,
		&appAgent.Model,
		&appAgent.ReasoningEffort,
		&llmMode,
		&baseURL,
		&apiKeyCiphertext,
		&headersJSON,
		&wireAPI,
		&appAgent.MachineID,
		&appAgent.MachineStatus,
		&appAgent.ModelProfileID,
		&appAgent.SourceKind,
		&appAgent.SourceRef,
		&createdByUserID,
		&canReviewShared,
		&appAgent.AutoWakeEnabled,
		&appAgent.Status,
		&appAgent.Activity,
		&appAgent.ActivityDetail,
		&currentInstanceID,
		&currentInstanceMachineID,
		&currentInstanceSessionID,
		&currentInstanceStatus,
		&currentInstanceActivity,
		&currentInstanceActivityDetail,
		&currentInstanceSourceKind,
		&currentInstanceSourceRef,
		&currentInstanceStartedAt,
		&currentInstanceLastSeenAt,
		&appAgent.CreatedAt,
	); err != nil {
		if coredb.IsNotFound(err) {
			return agent.AppAgent{}, ErrNotFound
		}
		return agent.AppAgent{}, fmt.Errorf("load agent: %w", err)
	}
	appAgent.ReasoningEffort = agent.NormalizeReasoningEffortForRuntime(
		appAgent.Runtime,
		appAgent.ReasoningEffort,
	)
	appAgent.PermissionMode = agent.DefaultAgentPermissionMode(appAgent.PermissionMode)
	appAgent.CurrentInstance = buildAppAgentInstance(
		currentInstanceID,
		currentInstanceMachineID,
		currentInstanceSessionID,
		currentInstanceStatus,
		currentInstanceActivity,
		currentInstanceActivityDetail,
		currentInstanceSourceKind,
		currentInstanceSourceRef,
		currentInstanceStartedAt,
		currentInstanceLastSeenAt,
	)
	roleBindings, err := store.loadAgentRoleBindingSummaries(ctx, workspaceID, []string{agentID})
	if err != nil {
		return agent.AppAgent{}, err
	}
	appAgent.CurrentRoleBinding = roleBindings[strings.TrimSpace(agentID)]
	appAgent.OwnerUserID = strings.TrimSpace(createdByUserID)
	appAgent.CanManage = strings.TrimSpace(createdByUserID) == strings.TrimSpace(userID)
	appAgent.CanReview = appAgent.CanManage || canReviewShared
	appAgent.CanDisable = canDisableAll || appAgent.CanManage
	if appAgent.CanManage {
		store.applyAppAgentLLMViewFields(&appAgent, llmMode, baseURL, apiKeyCiphertext, headersJSON, wireAPI)
	} else {
		appAgent.ModelProfileID = ""
	}
	if !includeRuntimeFailure {
		return appAgent, nil
	}
	latestRuntimeFailure, err := store.AgentOps().LoadLatestAgentRuntimeFailureSummary(ctx, workspaceID, agentID)
	if err != nil {
		return agent.AppAgent{}, err
	}
	appAgent.LatestRuntimeFailure = latestRuntimeFailure
	return appAgent, nil
}
