package converter

import (
	"strings"
	"time"

	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/store/message"
)

const reviewFeedbackStatusFullyResolved = "fully_resolved"

func ToReviewFeedbackMessages(messages []message.AppMessage) []dto.ReviewFeedbackMessage {
	items := make([]dto.ReviewFeedbackMessage, 0, len(messages))
	for _, appMessage := range messages {
		items = append(items, ToReviewFeedbackMessage(appMessage))
	}
	return items
}

func ToReviewFeedbackMessage(appMessage message.AppMessage) dto.ReviewFeedbackMessage {
	payload, ok, _ := message.ReviewFeedbackPayloadFromMetadata(appMessage.Metadata)
	if !ok {
		return dto.ReviewFeedbackMessage{
			ID:        strings.TrimSpace(appMessage.ID),
			Status:    message.ReviewFeedbackStatusOpen,
			Content:   appMessage.Content,
			CreatedAt: appMessage.CreatedAt,
			UpdatedAt: appMessage.EditedAt,
			Items:     []dto.ReviewFeedbackItemMessage{},
		}
	}

	authorProfile := appMessage.EffectiveAuthorProfile()
	authorMemberID := strings.TrimSpace(authorProfile.MemberID)
	authorDisplayName := strings.TrimSpace(authorProfile.DisplayName)
	items := make([]dto.ReviewFeedbackItemMessage, 0, len(payload.Items))
	allResolved := len(payload.Items) > 0
	for _, item := range payload.Items {
		status := strings.TrimSpace(item.Status)
		if status == "" {
			status = message.ReviewFeedbackStatusOpen
		}
		if status != message.ReviewFeedbackStatusResolved {
			allResolved = false
		}
		itemAuthorMemberID := strings.TrimSpace(item.CreatedByMemberID)
		if itemAuthorMemberID == "" {
			itemAuthorMemberID = authorMemberID
		}
		createdAt := strings.TrimSpace(item.CreatedAt)
		if createdAt == "" && !appMessage.CreatedAt.IsZero() {
			createdAt = appMessage.CreatedAt.Format(time.RFC3339Nano)
		}
		items = append(items, dto.ReviewFeedbackItemMessage{
			ID:                    strings.TrimSpace(item.ID),
			FeedbackMessageID:     strings.TrimSpace(appMessage.ID),
			Type:                  reviewFeedbackDTOType(item),
			Path:                  strings.TrimSpace(item.Path),
			OldPath:               strings.TrimSpace(item.OldPath),
			Side:                  strings.TrimSpace(item.Side),
			OldLine:               copyInt64Ptr(item.OldLine),
			NewLine:               copyInt64Ptr(item.NewLine),
			StartLine:             copyInt64Ptr(item.StartLine),
			EndLine:               copyInt64Ptr(item.EndLine),
			HunkHeader:            strings.TrimSpace(item.HunkHeader),
			AnchorFingerprint:     strings.TrimSpace(item.AnchorFingerprint),
			CodePreview:           strings.TrimSpace(item.CodePreview),
			Body:                  item.Body,
			Status:                status,
			AuthorMemberID:        itemAuthorMemberID,
			AuthorDisplayName:     authorDisplayName,
			CreatedAt:             createdAt,
			ResolvedByMemberID:    strings.TrimSpace(item.ResolvedByMemberID),
			ResolvedByDisplayName: "",
			ResolvedAt:            strings.TrimSpace(item.ResolvedAt),
		})
	}
	messageStatus := message.ReviewFeedbackStatusOpen
	if allResolved {
		messageStatus = reviewFeedbackStatusFullyResolved
	}
	return dto.ReviewFeedbackMessage{
		ID:              strings.TrimSpace(appMessage.ID),
		ReviewContextID: strings.TrimSpace(payload.ReviewContextID),
		SourceAgentID:   strings.TrimSpace(payload.Context.SourceAgentID),
		Status:          messageStatus,
		Decision:        message.NormalizeReviewFeedbackDecision(payload.Decision),
		Content:         appMessage.Content,
		CreatedAt:       appMessage.CreatedAt,
		UpdatedAt:       appMessage.EditedAt,
		Refs:            payload.Refs,
		Items:           items,
	}
}

func reviewFeedbackDTOType(item message.ReviewFeedbackItem) string {
	if value := strings.TrimSpace(item.Type); value != "" {
		return value
	}
	switch strings.TrimSpace(item.Kind) {
	case "inline":
		return "line"
	case "general":
		return "general"
	default:
		return strings.TrimSpace(item.Kind)
	}
}

func copyInt64Ptr(value *int64) *int64 {
	if value == nil {
		return nil
	}
	copied := *value
	return &copied
}
