import Foundation
import GenAPI

public struct CommentEntity: Codable, Equatable, Hashable, Identifiable {
    public let id: String
    public var hookId: String?
    public var clipId: String?
    public var entityType: CommentEntityType
    public let userId: String
    public let userDisplayName: String
    public let userAvatarUrl: String
    public let userHandle: String
    public let content: String
    public let createdAt: Date
    public var numLikes: Int
    public let numReports: Int
    public var parentId: String?
    public let trackTimestamp: TimeInterval
    public var reactionType: String?
    public var numReplies: Int
    public var replyContinuationToken: String?
    public let userMentions: [CommentUserMention]

    public var reaction: CommentReactionType {
        .init(reactionType)
    }

    public var isReply: Bool {
        parentId != nil
    }

    public var replies: [CommentEntity]
}

public extension CommentEntity {
    /// The type of entity (clip, hook, etc.) this comment is for
    enum CommentEntityType: String, CaseIterable, Codable, Equatable {
        case clip
        case hook
    }

    var entityId: String? {
        switch entityType {
        case .hook: hookId
        case .clip: clipId
        }
    }
}

public extension CommentEntity {
    init(
        id: String,
        hookId: String?,
        clipId: String?,
        entityType: CommentEntityType,
        userId: String,
        userDisplayName: String,
        userAvatarUrl: String,
        userHandle: String,
        content: String,
        createdAt: Date,
        numLikes: Int,
        numReports: Int,
        parentId: String?,
        trackTimestamp: Double,
        reactionType: String?,
        replyContinuationToken: String?,
        replies: [CommentEntity] = [],
        numReplies: Int,
        userMentions: [CommentUserMention] = []
    ) {
        self.id = id
        self.clipId = clipId
        self.hookId = hookId
        self.entityType = entityType
        self.userId = userId
        self.userDisplayName = userDisplayName
        self.userAvatarUrl = userAvatarUrl
        self.userHandle = userHandle
        self.content = content
        self.createdAt = createdAt
        self.numLikes = numLikes
        self.numReports = numReports
        self.parentId = parentId
        self.trackTimestamp = trackTimestamp
        self.reactionType = reactionType
        self.replyContinuationToken = replyContinuationToken
        self.replies = replies
        self.numReplies = numReplies
        self.userMentions = userMentions
    }
}

public extension CommentEntity {
    /// Comment
    init(_ remote: GenAPI.CommentSchema) throws {
        self.id = remote.id
        self.hookId = remote.hookId
        self.clipId = remote.clipId
        self.entityType = .init(rawValue: remote.entityType?.rawValue ?? "hook") ?? .hook
        self.userId = remote.userId
        self.userDisplayName = remote.userDisplayName
        self.userAvatarUrl = remote.userAvatarUrl
        self.userHandle = remote.userHandle
        self.content = remote.content
        self.createdAt = remote.createdAt
        self.numLikes = remote.numLikes
        self.numReports = 0
        self.parentId = remote.parentId
        self.trackTimestamp = remote.trackTimestamp ?? 0
        self.reactionType = remote.reactionType
        self.replyContinuationToken = remote.replyContinuationToken
        self.replies = remote.replies?.map { CommentEntity($0) } ?? []
        self.numReplies = remote.numReplies ?? 0
        self.userMentions = remote.userMentions?.map {
            .init(start: $0.start, end: $0.end, handle: $0.handle, displayName: $0.displayName)
        } ?? []

        for index in replies.indices {
            replies[index].parentId = id
            replies[index].hookId = hookId
            replies[index].clipId = clipId
            replies[index].entityType = entityType
        }
    }

    /// Comment Reply
    init(_ remote: GenAPI.ReplySchema) {
        self.id = remote.id
        self.hookId = nil
        self.clipId = nil
        self.entityType = .init(rawValue: remote.entityType?.rawValue ?? "hook") ?? .hook
        self.userId = remote.userId
        self.userDisplayName = remote.userDisplayName
        self.userAvatarUrl = remote.userAvatarUrl
        self.userHandle = remote.userHandle
        self.content = remote.content
        self.createdAt = remote.createdAt
        self.numLikes = remote.numLikes
        self.numReports = 0
        self.parentId = remote.parentId
        self.trackTimestamp = 0
        self.reactionType = remote.reactionType
        self.replyContinuationToken = nil
        self.replies = []
        self.numReplies = 0
        self.userMentions = remote.userMentions?.map {
            .init(start: $0.start, end: $0.end, handle: $0.handle, displayName: $0.displayName)
        } ?? []
    }
}

#if DEBUG
    public extension CommentEntity {
        static var mock: CommentEntity {
            .init(
                id: UUID().uuidString,
                hookId: "hook1234",
                clipId: nil,
                entityType: .hook,
                userId: "user1234",
                userDisplayName: "John Smith",
                userAvatarUrl: "https://example.com/avatar.jpg",
                userHandle: "@johnsmith",
                content: "This is a mock comment",
                createdAt: .now,
                numLikes: 999,
                numReports: 0,
                parentId: nil,
                trackTimestamp: 123.45,
                reactionType: "like",
                replyContinuationToken: nil,
                numReplies: 5
            )
        }
    }
#endif
