import APIClient
import ComponentLibrary
import Localization
import StatsigClient
import SwiftUI

struct NotificationContentV2Stack: View {
    let notification: NotificationItemV2
    let followProgressHandle: String?
    let userToFollow: MiniProfileV2?
    let onTappedFollow: (MiniProfileV2) -> Void
    let onTappedProfile: () -> Void
    let onTappedContent: () -> Void

    init(
        _ notification: NotificationItemV2,
        followProgressHandle: String?,
        userToFollow: MiniProfileV2?,
        onTappedFollow: @escaping (MiniProfileV2) -> Void,
        onTappedProfile: @escaping () -> Void,
        onTappedContent: @escaping () -> Void
    ) {
        self.notification = notification
        self.followProgressHandle = followProgressHandle
        self.userToFollow = userToFollow
        self.onTappedFollow = onTappedFollow
        self.onTappedProfile = onTappedProfile
        self.onTappedContent = onTappedContent
    }

    var body: some View {
        HStack {
            if notification.notificationType == .defaultValue {
                EmptyView()
            } else {
                Button {
                    onTappedProfile()
                } label: {
                    MiniProfileV2Stack(
                        userProfileURLs: notification.userProfileURLs
                    )
                }
                .buttonStyle(.plain)
            }

            VStack(alignment: .leading) {
                Text(userText)
                    .multilineTextAlignment(.leading)
                Text(notification.updatedAt.longTimeAgoDisplay())
                    .typographyV1(.caption4)
            }
            Spacer()
            ancillaryView
        }
        .onTapGesture {
            onTappedContent()
        }
    }
}

private extension NotificationContentV2Stack {
    @ViewBuilder
    var ancillaryView: some View {
        switch notification.notificationType {
        case .clipComment,
             .clipLike,
             .commentLike,
             .commentReply,
             .commentMention,
             .captionMention,
             .defaultValue,
             .hookCreated,
             .hookComment,
             .hookCommentLike,
             .hookCommentMention,
             .hookCommentReply,
             .hookLike,
             .videoCoverHookLike,
             .videoCoverHookComment,
             .videoCoverHookCommentLike,
             .videoCoverHookCommentMention,
             .videoCoverHookCommentReply,
             .playlistComment,
             .playlistLike,
             .sceneComment,
             .sceneLike,
             .personaFavorite,
             .personaFollow,
             .personaUsed,
             .clipCreateFollowee,
             .clipRemix:
            contentImageView
                .frame(width: 60.0)

        case .follow:
            if let userToFollow = userToFollow {
                followButton(userToFollow)
            }

        case .announcement,
             .clipUnlike,
             .codeRedeem,
             .delete,
             .invite,
             .inviteAccepted,
             .playlistUnlike,
             .sceneUnlike,
             .unfollow,
             .restrictedByDefault:
            EmptyView()
        }
    }

    var userText: AttributedString {
        let boldAttributes = TypographyV1.attributedContainer(TypographyV1.caption2, .SemanticV1.textPrimary)
        let regularAttributes = TypographyV1.attributedContainer(TypographyV1.caption, .SemanticV1.textSecondary)

        let userProfiles = notification.userProfiles
        let totalUsers = notification.totalUsers
        let isMultiple = totalUsers > 1

        var result = AttributedString()
        if notification.notificationType == .defaultValue {
            /* Skip User string */
        } else if userProfiles.count == 1 {
            let profile = userProfiles[0].displayName ?? ""
            let profileString = AttributedString(profile, attributes: boldAttributes)
            result.append(profileString)

        } else if userProfiles.count == 2 {
            let profileA = userProfiles[0].displayName ?? ""
            let profileB = userProfiles[1].displayName ?? ""
            let profileAString = AttributedString(profileA, attributes: boldAttributes)
            let profileBString = AttributedString(profileB, attributes: boldAttributes)
            let and = AttributedString(" and ", attributes: regularAttributes)
            result.append(profileAString)
            result.append(and)
            result.append(profileBString)

        } else if totalUsers >= 3 {
            let profileA = userProfiles[0].displayName ?? ""
            let profileAString = AttributedString(profileA, attributes: boldAttributes)
            let countString = AttributedString("\(totalUsers - 1) others", attributes: boldAttributes)
            let and = AttributedString(" + ", attributes: boldAttributes)
            result.append(profileAString)
            result.append(and)
            result.append(countString)
        }

        var typeMessage: String
        var includeContentMessage = true
        var includeContentTitle = false
        var includeHeart = false

        switch notification.notificationType {
        case .announcement:
            typeMessage = ""

        case .clipRemix:
            typeMessage = L10n.FeatureNotifications.remixedYourSong
            includeContentTitle = true
            includeContentMessage = false

        case .clipComment:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.commentedOnYourClip
                includeContentMessage = false

            } else {
                typeMessage = L10n.FeatureNotifications.saidThisAboutYourClip
            }
            includeContentTitle = true

        case .clipLike:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.love
            } else {
                typeMessage = L10n.FeatureNotifications.likedYourSong
            }
            includeContentMessage = false
            includeContentTitle = true
            includeHeart = true

        case .clipUnlike:
            typeMessage = ""

        case .codeRedeem:
            typeMessage = ""

        case .commentLike:
            typeMessage = L10n.FeatureNotifications.likedYourComment

        case .commentReply:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.repliedToYourComment

        case .commentMention:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.mentionedYouInAComment
            includeContentTitle = false

        case .captionMention:
            typeMessage = L10n.FeatureNotifications.mentionedYouInACaption
            includeContentTitle = false
            includeContentMessage = true

        case .defaultValue:
            typeMessage = ""

        case .delete:
            typeMessage = ""

        case .follow:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.followedYou
            } else {
                typeMessage = L10n.FeatureNotifications.justFollowedYou
                typeMessage += ". 🌟 " + L10n.FeatureNotifications.followThemBackCopy1
            }

        case .invite:
            typeMessage = ""

        case .inviteAccepted:
            typeMessage = L10n.FeatureNotifications.acceptedYourInvite

        case .personaFavorite:
            typeMessage = L10n.FeatureNotifications.favoritedYourPersona

        case .personaFollow:
            typeMessage = L10n.FeatureNotifications.followedYourPersona

        case .personaUsed:
            typeMessage = L10n.FeatureNotifications.usedYourPersona

        case .playlistComment:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.commentedOnYourPlaylist

        case .playlistLike:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.love
                includeContentMessage = false
            } else {
                typeMessage = L10n.FeatureNotifications.likedYourPlaylist
            }
            includeContentTitle = true
            includeHeart = true

        case .playlistUnlike:
            typeMessage = ""

        case .restrictedByDefault:
            typeMessage = ""

        case .sceneComment:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.commentedOnYourScene
            includeContentTitle = true

        case .sceneLike:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.love
                includeContentMessage = false
            } else {
                typeMessage = L10n.FeatureNotifications.likedYourScene
            }

            includeContentTitle = true
            includeHeart = true

        case .sceneUnlike:
            typeMessage = ""

        case .unfollow:
            typeMessage = ""

        case .clipCreateFollowee:
            typeMessage = L10n.FeatureNotifications.justPostedANewTrackCopy1
            includeContentTitle = true
            includeContentMessage = false

        case .hookLike:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.love
            } else {
                typeMessage = L10n.FeatureNotifications.likedYourHook
            }
            includeContentMessage = false
            includeContentTitle = true
            includeHeart = true

        case .hookComment:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.commentedOnYourHook
                includeContentMessage = false
            } else {
                typeMessage = L10n.FeatureNotifications.saidThisAboutYourHook
            }
            includeContentTitle = true

        case .hookCommentReply:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.repliedToYourComment

        case .hookCommentLike:
            typeMessage = L10n.FeatureNotifications.likedYourComment

        case .hookCommentMention:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.mentionedYouInAComment
            includeContentTitle = false

        case .hookCreated:
            if FeatureFlag.hooks.isFeedEnabled {
                typeMessage = L10n.FeatureNotifications.justCreatedAHook
                includeContentTitle = true
                includeContentMessage = false
            } else {
                typeMessage = ""
                includeContentTitle = false
                includeContentMessage = false
            }

        case .videoCoverHookLike:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.love
            } else {
                typeMessage = L10n.FeatureNotifications.likedYourVideoCoverHook
            }
            includeContentMessage = false
            includeContentTitle = true
            includeHeart = true

        case .videoCoverHookComment:
            if isMultiple {
                typeMessage = L10n.FeatureNotifications.commentedOnYourVideoCoverHook
                includeContentMessage = false
            } else {
                typeMessage = L10n.FeatureNotifications.saidThisAboutYourVideoCoverHook
            }
            includeContentTitle = true

        case .videoCoverHookCommentReply:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.repliedToYourComment

        case .videoCoverHookCommentLike:
            typeMessage = L10n.FeatureNotifications.likedYourComment

        case .videoCoverHookCommentMention:
            if isMultiple {
                includeContentMessage = false
            }
            typeMessage = L10n.FeatureNotifications.mentionedYouInAComment
            includeContentTitle = false
        }

        if !typeMessage.isEmpty {
            let typeMessageString = AttributedString(" \(typeMessage)", attributes: regularAttributes)
            result.append(typeMessageString)
        }

        if includeContentTitle, let contentTitle = notification.contentTitle {
            let contentTitleString = AttributedString(" \(contentTitle)", attributes: boldAttributes)
            result.append(contentTitleString)
        }

        if includeHeart {
            let typeMessageString = AttributedString(" ❤️", attributes: regularAttributes)
            result.append(typeMessageString)
        }

        if includeContentMessage, let contentMessage = notification.contentMessage {
            let contentMessageString = AttributedString(": \(contentMessage)", attributes: regularAttributes)
            result.append(contentMessageString)
        }

        return result
    }

    @ViewBuilder
    var contentImageView: some View {
        if let imageURL = notification.contentImageUrl {
            Color.clear
                .frame(width: 44, height: 56)
                .background {
                    RemoteImage(url: imageURL, fallbackId: "1")
                }
                .clipShape(.rect(cornerRadius: 4.0))
        } else {
            EmptyView()
        }
    }

    @ViewBuilder
    func followButton(_ user: MiniProfileV2) -> some View {
        PrimaryButtonV1(
            title: user.isFollowing ? L10n.FeatureProfile.following : L10n.FeatureProfile.follow,
            isLoading: followProgressHandle == user.handle,
            colorCombination: .dark,
            preferredSize: .smallAdaptive,
            action: { onTappedFollow(user) }
        )
        .background(Color.SemanticV1.backgroundPrimary)
    }
}
