package postgres

import (
	"context"
	"database/sql"
)

// ── Single-field helpers (v0.29.0) ──────────────────────────────────────
// Moved from handlers/completion.go and handlers/messages.go raw SQL.

func (s *ChannelStore) GetAIMode(ctx context.Context, channelID string) (string, error) {
	var aiMode string
	err := DB.QueryRowContext(ctx, `
		SELECT COALESCE(ai_mode, 'auto') FROM channels WHERE id = $1
	`, channelID).Scan(&aiMode)
	if err != nil {
		return "auto", err
	}
	return aiMode, nil
}

func (s *ChannelStore) GetTypeAndTeamID(ctx context.Context, channelID string) (string, *string, error) {
	var channelType string
	var teamID *string
	err := DB.QueryRowContext(ctx, `
		SELECT COALESCE(type, 'direct'), team_id FROM channels WHERE id = $1
	`, channelID).Scan(&channelType, &teamID)
	return channelType, teamID, err
}

func (s *ChannelStore) GetSystemPrompt(ctx context.Context, channelID string) (*string, error) {
	var prompt *string
	err := DB.QueryRowContext(ctx, `
		SELECT system_prompt FROM channels WHERE id = $1
	`, channelID).Scan(&prompt)
	if err == sql.ErrNoRows {
		return nil, nil
	}
	return prompt, err
}

func (s *ChannelStore) GetDefaultModel(ctx context.Context, channelID string) (*string, error) {
	var model *string
	err := DB.QueryRowContext(ctx, `
		SELECT model FROM channels WHERE id = $1
	`, channelID).Scan(&model)
	if err == sql.ErrNoRows {
		return nil, nil
	}
	return model, err
}

func (s *ChannelStore) TouchUpdatedAt(ctx context.Context, channelID string) error {
	_, err := DB.ExecContext(ctx, `UPDATE channels SET updated_at = NOW() WHERE id = $1`, channelID)
	return err
}

func (s *ChannelStore) ListUserParticipantIDs(ctx context.Context, channelID, excludeUserID string) ([]string, error) {
	rows, err := DB.QueryContext(ctx, `
		SELECT participant_id FROM channel_participants
		WHERE channel_id = $1 AND participant_type = 'user' AND participant_id != $2
	`, channelID, excludeUserID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var ids []string
	for rows.Next() {
		var id string
		if err := rows.Scan(&id); err != nil {
			return nil, err
		}
		ids = append(ids, id)
	}
	if ids == nil {
		ids = []string{}
	}
	return ids, rows.Err()
}

func (s *ChannelStore) ListPersonaParticipantIDs(ctx context.Context, channelID string) ([]string, error) {
	rows, err := DB.QueryContext(ctx, `
		SELECT participant_id FROM channel_participants
		WHERE channel_id = $1 AND participant_type = 'persona'
		ORDER BY created_at
	`, channelID)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var ids []string
	for rows.Next() {
		var id string
		if err := rows.Scan(&id); err != nil {
			return nil, err
		}
		ids = append(ids, id)
	}
	if ids == nil {
		ids = []string{}
	}
	return ids, rows.Err()
}

func (s *ChannelStore) GetLeaderPersonaID(ctx context.Context, channelID string) (string, error) {
	// Try group leader first
	var leaderID string
	err := DB.QueryRowContext(ctx, `
		SELECT cp.participant_id
		FROM channel_participants cp
		JOIN persona_group_members pgm ON pgm.persona_id = cp.participant_id
		WHERE cp.channel_id = $1
		  AND cp.participant_type = 'persona'
		  AND pgm.is_leader = true
		LIMIT 1
	`, channelID).Scan(&leaderID)
	if err == nil && leaderID != "" {
		return leaderID, nil
	}

	// Fallback: first persona participant
	err = DB.QueryRowContext(ctx, `
		SELECT participant_id FROM channel_participants
		WHERE channel_id = $1 AND participant_type = 'persona'
		ORDER BY created_at LIMIT 1
	`, channelID).Scan(&leaderID)
	if err == sql.ErrNoRows {
		return "", nil
	}
	return leaderID, err
}

func (s *ChannelStore) GetWorkflowInfo(ctx context.Context, channelID string) (*string, int, error) {
	var workflowID *string
	var currentStage int
	err := DB.QueryRowContext(ctx, `
		SELECT workflow_id, COALESCE(current_stage, 0)
		FROM channels WHERE id = $1 AND type = 'workflow'
	`, channelID).Scan(&workflowID, &currentStage)
	if err == sql.ErrNoRows {
		return nil, 0, nil
	}
	return workflowID, currentStage, err
}
