import APIClient
import CommentsClient
import ComposableArchitecture
import Foundation
import Utilities

extension CommentsSheetReducer {
    func handlePostComment(entityType: CommentEntity.CommentEntityType, state: inout State) -> Effect<Action> {
        guard state.hasCommentText else { return .none }

        let tempCommentId: String = createTemporaryCommentIfNeeded(entityType, state: &state)
        let sentAt: Double? = nil

        // Construct HooksRecommendationMetadata if this is a hook comment
        let recommendationMetadata: HooksRecommendationMetadata? = {
            guard entityType == .hook,
                  let hook = state.item as? Hook,
                  let source = state.source else { return nil }

            let analyticsContext = source.analyticsContext
            return HooksRecommendationMetadata(
                contextType: analyticsContext.contextType,
                hookId: hook.id,
                recommendationItemId: hook.recommendationItemId
            )
        }()

        commentsSheetClient.postComment(
            state.item.commentEntityId,
            entityType,
            tempCommentId,
            state.currentReplyParentCommentID,
            sentAt,
            state.userCommentText,
            state.userMentions,
            recommendationMetadata
        )

        resetCommentInput(state: &state)
        unlockTrackTimeIfNeeded(state: &state, when: true)
        return .none
    }
}

private extension CommentsSheetReducer {
    func createTemporaryCommentIfNeeded(_ entityType: CommentEntity.CommentEntityType, state: inout State) -> String {
        if state.currentReplyParentCommentID != nil {
            return ""
        } else {
            return addTemporaryComment(state.userCommentText, entityType, state: &state)
        }
    }

    func addTemporaryComment(_ content: String, _ entityType: CommentEntity.CommentEntityType, state: inout State) -> String {
        let tempComment = CommentEntity.temporary(
            entityType: entityType,
            entityId: state.item.commentEntityId,
            userId: state.currentUser.id,
            userDisplayName: state.currentUser.displayName ?? "",
            userAvatarUrl: state.currentUser.avatarImageUrl ?? "",
            userHandle: state.currentUser.handle,
            content: content,
            trackTimestamp: state.commentTrackTime
        )
        state.pendingComments.append(tempComment)
        return tempComment.id
    }

    func resetCommentInput(state: inout State) {
        state.currentReplyParentCommentID = nil
        state.userCommentText = ""
        state.userMentionSearchSuggestions = []
        state.userMentions = []
        state.hasStartedTypingSession = false
    }
}

private extension CommentEntity {
    static func temporary(
        entityType: CommentEntityType,
        entityId: String,
        userId: String,
        userDisplayName: String,
        userAvatarUrl: String,
        userHandle: String,
        content: String,
        trackTimestamp: Double
    ) -> CommentEntity {
        let tempId = "temp-\(entityType.rawValue)-\(UUID().uuidString)"
        return CommentEntity(
            id: tempId,
            hookId: entityType == .hook ? entityId : nil,
            clipId: entityType == .clip ? entityId : nil,
            entityType: entityType,
            userId: userId,
            userDisplayName: userDisplayName,
            userAvatarUrl: userAvatarUrl,
            userHandle: userHandle,
            content: content,
            createdAt: .now,
            numLikes: .zero,
            numReports: .zero,
            parentId: nil,
            trackTimestamp: trackTimestamp,
            reactionType: nil,
            replyContinuationToken: nil,
            numReplies: .zero
        )
    }
}
